feat(api): refactor API endpoints to use structured ApiEndpoint class and introduce new endpoint files

This commit is contained in:
Achintha Isuru
2026-03-17 11:26:44 -04:00
parent eccd2c6dbd
commit 31231c1e6d
10 changed files with 596 additions and 137 deletions

View File

@@ -20,7 +20,13 @@ export 'src/services/api_service/dio_client.dart';
export 'src/services/api_service/mixins/api_error_handler.dart';
export 'src/services/api_service/mixins/session_handler_mixin.dart';
// Core API Services
// API Endpoint classes
export 'src/services/api_service/api_endpoint.dart';
export 'src/services/api_service/endpoints/auth_endpoints.dart';
export 'src/services/api_service/endpoints/client_endpoints.dart';
export 'src/services/api_service/endpoints/core_endpoints.dart';
export 'src/services/api_service/endpoints/staff_endpoints.dart';
// Backward-compatible facades (deprecated)
export 'src/services/api_service/core_api_services/core_api_endpoints.dart';
export 'src/services/api_service/core_api_services/v2_api_endpoints.dart';
export 'src/services/api_service/core_api_services/file_upload/file_upload_service.dart';

View File

@@ -0,0 +1,16 @@
/// Represents an API endpoint with its path and required scopes for future
/// feature gating.
class ApiEndpoint {
/// Creates an [ApiEndpoint] with the given [path] and optional
/// [requiredScopes].
const ApiEndpoint(this.path, {this.requiredScopes = const <String>[]});
/// The relative URL path (e.g. '/auth/client/sign-in').
final String path;
/// Scopes required to access this endpoint. Empty means no gate.
final List<String> requiredScopes;
@override
String toString() => path;
}

View File

@@ -1,40 +1,41 @@
import '../../../config/app_config.dart';
import 'package:krow_core/src/services/api_service/endpoints/core_endpoints.dart';
/// Constants for Core API endpoints.
/// Backward-compatible facade that re-exports all Core API endpoints as
/// [String] paths.
///
/// New code should use [CoreEndpoints] directly.
@Deprecated('Use CoreEndpoints directly')
class CoreApiEndpoints {
CoreApiEndpoints._();
/// The base URL for the Core API.
static const String baseUrl = AppConfig.coreApiBaseUrl;
/// Upload a file.
static const String uploadFile = '$baseUrl/core/upload-file';
static String get uploadFile => CoreEndpoints.uploadFile.path;
/// Create a signed URL for a file.
static const String createSignedUrl = '$baseUrl/core/create-signed-url';
static String get createSignedUrl => CoreEndpoints.createSignedUrl.path;
/// Invoke a Large Language Model.
static const String invokeLlm = '$baseUrl/core/invoke-llm';
static String get invokeLlm => CoreEndpoints.invokeLlm.path;
/// Root for verification operations.
static const String verifications = '$baseUrl/core/verifications';
static String get verifications => CoreEndpoints.verifications.path;
/// Get status of a verification job.
static String verificationStatus(String id) =>
'$baseUrl/core/verifications/$id';
CoreEndpoints.verificationStatus(id).path;
/// Review a verification decision.
static String verificationReview(String id) =>
'$baseUrl/core/verifications/$id/review';
CoreEndpoints.verificationReview(id).path;
/// Retry a verification job.
static String verificationRetry(String id) =>
'$baseUrl/core/verifications/$id/retry';
CoreEndpoints.verificationRetry(id).path;
/// Transcribe audio to text for rapid orders.
static const String transcribeRapidOrder =
'$baseUrl/core/rapid-orders/transcribe';
static String get transcribeRapidOrder =>
CoreEndpoints.transcribeRapidOrder.path;
/// Parse text to structured rapid order.
static const String parseRapidOrder = '$baseUrl/core/rapid-orders/parse';
static String get parseRapidOrder => CoreEndpoints.parseRapidOrder.path;
}

View File

@@ -1,343 +1,358 @@
import '../../../config/app_config.dart';
import 'package:krow_core/src/services/api_service/endpoints/auth_endpoints.dart';
import 'package:krow_core/src/services/api_service/endpoints/client_endpoints.dart';
import 'package:krow_core/src/services/api_service/endpoints/staff_endpoints.dart';
/// Constants for V2 Unified API endpoints.
/// Backward-compatible facade that re-exports all V2 endpoints as [String]
/// paths.
///
/// All mobile read/write operations go through the V2 gateway which proxies
/// to the internal Query API and Command API services.
/// New code should use [AuthEndpoints], [StaffEndpoints], or
/// [ClientEndpoints] directly.
@Deprecated(
'Use AuthEndpoints, StaffEndpoints, or ClientEndpoints directly',
)
class V2ApiEndpoints {
V2ApiEndpoints._();
/// The base URL for the V2 Unified API gateway.
static const String baseUrl = AppConfig.v2ApiBaseUrl;
// ── Auth ──────────────────────────────────────────────────────────────
/// Client email/password sign-in.
static const String clientSignIn = '$baseUrl/auth/client/sign-in';
static String get clientSignIn => AuthEndpoints.clientSignIn.path;
/// Client business registration.
static const String clientSignUp = '$baseUrl/auth/client/sign-up';
static String get clientSignUp => AuthEndpoints.clientSignUp.path;
/// Client sign-out.
static const String clientSignOut = '$baseUrl/auth/client/sign-out';
static String get clientSignOut => AuthEndpoints.clientSignOut.path;
/// Start staff phone verification (SMS).
static const String staffPhoneStart = '$baseUrl/auth/staff/phone/start';
static String get staffPhoneStart => AuthEndpoints.staffPhoneStart.path;
/// Complete staff phone verification.
static const String staffPhoneVerify = '$baseUrl/auth/staff/phone/verify';
static String get staffPhoneVerify => AuthEndpoints.staffPhoneVerify.path;
/// Generic sign-out.
static const String signOut = '$baseUrl/auth/sign-out';
static String get signOut => AuthEndpoints.signOut.path;
/// Staff-specific sign-out.
static const String staffSignOut = '$baseUrl/auth/staff/sign-out';
static String get staffSignOut => AuthEndpoints.staffSignOut.path;
/// Get current session data.
static const String session = '$baseUrl/auth/session';
static String get session => AuthEndpoints.session.path;
// ── Staff Read ────────────────────────────────────────────────────────
/// Staff session data.
static const String staffSession = '$baseUrl/staff/session';
static String get staffSession => StaffEndpoints.session.path;
/// Staff dashboard overview.
static const String staffDashboard = '$baseUrl/staff/dashboard';
static String get staffDashboard => StaffEndpoints.dashboard.path;
/// Staff profile completion status.
static const String staffProfileCompletion =
'$baseUrl/staff/profile-completion';
static String get staffProfileCompletion =>
StaffEndpoints.profileCompletion.path;
/// Staff availability schedule.
static const String staffAvailability = '$baseUrl/staff/availability';
static String get staffAvailability => StaffEndpoints.availability.path;
/// Today's shifts for clock-in.
static const String staffClockInShiftsToday =
'$baseUrl/staff/clock-in/shifts/today';
static String get staffClockInShiftsToday =>
StaffEndpoints.clockInShiftsToday.path;
/// Current clock-in status.
static const String staffClockInStatus = '$baseUrl/staff/clock-in/status';
static String get staffClockInStatus => StaffEndpoints.clockInStatus.path;
/// Payments summary.
static const String staffPaymentsSummary = '$baseUrl/staff/payments/summary';
static String get staffPaymentsSummary =>
StaffEndpoints.paymentsSummary.path;
/// Payments history.
static const String staffPaymentsHistory = '$baseUrl/staff/payments/history';
static String get staffPaymentsHistory =>
StaffEndpoints.paymentsHistory.path;
/// Payments chart data.
static const String staffPaymentsChart = '$baseUrl/staff/payments/chart';
static String get staffPaymentsChart => StaffEndpoints.paymentsChart.path;
/// Assigned shifts.
static const String staffShiftsAssigned = '$baseUrl/staff/shifts/assigned';
static String get staffShiftsAssigned =>
StaffEndpoints.shiftsAssigned.path;
/// Open shifts available to apply.
static const String staffShiftsOpen = '$baseUrl/staff/shifts/open';
static String get staffShiftsOpen => StaffEndpoints.shiftsOpen.path;
/// Pending shift assignments.
static const String staffShiftsPending = '$baseUrl/staff/shifts/pending';
static String get staffShiftsPending => StaffEndpoints.shiftsPending.path;
/// Cancelled shifts.
static const String staffShiftsCancelled = '$baseUrl/staff/shifts/cancelled';
static String get staffShiftsCancelled =>
StaffEndpoints.shiftsCancelled.path;
/// Completed shifts.
static const String staffShiftsCompleted = '$baseUrl/staff/shifts/completed';
static String get staffShiftsCompleted =>
StaffEndpoints.shiftsCompleted.path;
/// Shift details by ID.
static String staffShiftDetails(String shiftId) =>
'$baseUrl/staff/shifts/$shiftId';
StaffEndpoints.shiftDetails(shiftId).path;
/// Staff profile sections overview.
static const String staffProfileSections = '$baseUrl/staff/profile/sections';
static String get staffProfileSections =>
StaffEndpoints.profileSections.path;
/// Personal info.
static const String staffPersonalInfo = '$baseUrl/staff/profile/personal-info';
static String get staffPersonalInfo => StaffEndpoints.personalInfo.path;
/// Industries/experience.
static const String staffIndustries = '$baseUrl/staff/profile/industries';
static String get staffIndustries => StaffEndpoints.industries.path;
/// Skills.
static const String staffSkills = '$baseUrl/staff/profile/skills';
static String get staffSkills => StaffEndpoints.skills.path;
/// Documents.
static const String staffDocuments = '$baseUrl/staff/profile/documents';
static String get staffDocuments => StaffEndpoints.documents.path;
/// Attire items.
static const String staffAttire = '$baseUrl/staff/profile/attire';
static String get staffAttire => StaffEndpoints.attire.path;
/// Tax forms.
static const String staffTaxForms = '$baseUrl/staff/profile/tax-forms';
static String get staffTaxForms => StaffEndpoints.taxForms.path;
/// Emergency contacts.
static const String staffEmergencyContacts =
'$baseUrl/staff/profile/emergency-contacts';
static String get staffEmergencyContacts =>
StaffEndpoints.emergencyContacts.path;
/// Certificates.
static const String staffCertificates = '$baseUrl/staff/profile/certificates';
static String get staffCertificates => StaffEndpoints.certificates.path;
/// Bank accounts.
static const String staffBankAccounts = '$baseUrl/staff/profile/bank-accounts';
static String get staffBankAccounts => StaffEndpoints.bankAccounts.path;
/// Benefits.
static const String staffBenefits = '$baseUrl/staff/profile/benefits';
static String get staffBenefits => StaffEndpoints.benefits.path;
/// Time card.
static const String staffTimeCard = '$baseUrl/staff/profile/time-card';
static String get staffTimeCard => StaffEndpoints.timeCard.path;
/// Privacy settings.
static const String staffPrivacy = '$baseUrl/staff/profile/privacy';
static String get staffPrivacy => StaffEndpoints.privacy.path;
/// FAQs.
static const String staffFaqs = '$baseUrl/staff/faqs';
static String get staffFaqs => StaffEndpoints.faqs.path;
/// FAQs search.
static const String staffFaqsSearch = '$baseUrl/staff/faqs/search';
static String get staffFaqsSearch => StaffEndpoints.faqsSearch.path;
// ── Staff Write ───────────────────────────────────────────────────────
/// Staff profile setup.
static const String staffProfileSetup = '$baseUrl/staff/profile/setup';
static String get staffProfileSetup => StaffEndpoints.profileSetup.path;
/// Clock in.
static const String staffClockIn = '$baseUrl/staff/clock-in';
static String get staffClockIn => StaffEndpoints.clockIn.path;
/// Clock out.
static const String staffClockOut = '$baseUrl/staff/clock-out';
static String get staffClockOut => StaffEndpoints.clockOut.path;
/// Quick-set availability.
static const String staffAvailabilityQuickSet =
'$baseUrl/staff/availability/quick-set';
static String get staffAvailabilityQuickSet =>
StaffEndpoints.availabilityQuickSet.path;
/// Apply for a shift.
static String staffShiftApply(String shiftId) =>
'$baseUrl/staff/shifts/$shiftId/apply';
StaffEndpoints.shiftApply(shiftId).path;
/// Accept a shift.
static String staffShiftAccept(String shiftId) =>
'$baseUrl/staff/shifts/$shiftId/accept';
StaffEndpoints.shiftAccept(shiftId).path;
/// Decline a shift.
static String staffShiftDecline(String shiftId) =>
'$baseUrl/staff/shifts/$shiftId/decline';
StaffEndpoints.shiftDecline(shiftId).path;
/// Request a shift swap.
static String staffShiftRequestSwap(String shiftId) =>
'$baseUrl/staff/shifts/$shiftId/request-swap';
StaffEndpoints.shiftRequestSwap(shiftId).path;
/// Update emergency contact by ID.
static String staffEmergencyContactUpdate(String contactId) =>
'$baseUrl/staff/profile/emergency-contacts/$contactId';
StaffEndpoints.emergencyContactUpdate(contactId).path;
/// Update tax form by type.
static String staffTaxFormUpdate(String formType) =>
'$baseUrl/staff/profile/tax-forms/$formType';
StaffEndpoints.taxFormUpdate(formType).path;
/// Submit tax form by type.
static String staffTaxFormSubmit(String formType) =>
'$baseUrl/staff/profile/tax-forms/$formType/submit';
StaffEndpoints.taxFormSubmit(formType).path;
/// Upload staff profile photo.
static const String staffProfilePhoto = '$baseUrl/staff/profile/photo';
static String get staffProfilePhoto => StaffEndpoints.profilePhoto.path;
/// Upload document by ID.
static String staffDocumentUpload(String documentId) =>
'$baseUrl/staff/profile/documents/$documentId/upload';
StaffEndpoints.documentUpload(documentId).path;
/// Upload attire by ID.
static String staffAttireUpload(String documentId) =>
'$baseUrl/staff/profile/attire/$documentId/upload';
StaffEndpoints.attireUpload(documentId).path;
/// Delete certificate by ID.
static String staffCertificateDelete(String certificateId) =>
'$baseUrl/staff/profile/certificates/$certificateId';
StaffEndpoints.certificateDelete(certificateId).path;
// ── Client Read ───────────────────────────────────────────────────────
/// Client session data.
static const String clientSession = '$baseUrl/client/session';
static String get clientSession => ClientEndpoints.session.path;
/// Client dashboard.
static const String clientDashboard = '$baseUrl/client/dashboard';
static String get clientDashboard => ClientEndpoints.dashboard.path;
/// Client reorders.
static const String clientReorders = '$baseUrl/client/reorders';
static String get clientReorders => ClientEndpoints.reorders.path;
/// Billing accounts.
static const String clientBillingAccounts = '$baseUrl/client/billing/accounts';
static String get clientBillingAccounts =>
ClientEndpoints.billingAccounts.path;
/// Pending invoices.
static const String clientBillingInvoicesPending =
'$baseUrl/client/billing/invoices/pending';
static String get clientBillingInvoicesPending =>
ClientEndpoints.billingInvoicesPending.path;
/// Invoice history.
static const String clientBillingInvoicesHistory =
'$baseUrl/client/billing/invoices/history';
static String get clientBillingInvoicesHistory =>
ClientEndpoints.billingInvoicesHistory.path;
/// Current bill.
static const String clientBillingCurrentBill =
'$baseUrl/client/billing/current-bill';
static String get clientBillingCurrentBill =>
ClientEndpoints.billingCurrentBill.path;
/// Savings data.
static const String clientBillingSavings = '$baseUrl/client/billing/savings';
static String get clientBillingSavings =>
ClientEndpoints.billingSavings.path;
/// Spend breakdown.
static const String clientBillingSpendBreakdown =
'$baseUrl/client/billing/spend-breakdown';
static String get clientBillingSpendBreakdown =>
ClientEndpoints.billingSpendBreakdown.path;
/// Coverage overview.
static const String clientCoverage = '$baseUrl/client/coverage';
static String get clientCoverage => ClientEndpoints.coverage.path;
/// Coverage stats.
static const String clientCoverageStats = '$baseUrl/client/coverage/stats';
static String get clientCoverageStats =>
ClientEndpoints.coverageStats.path;
/// Core team.
static const String clientCoverageCoreTeam =
'$baseUrl/client/coverage/core-team';
static String get clientCoverageCoreTeam =>
ClientEndpoints.coverageCoreTeam.path;
/// Hubs list.
static const String clientHubs = '$baseUrl/client/hubs';
static String get clientHubs => ClientEndpoints.hubs.path;
/// Cost centers.
static const String clientCostCenters = '$baseUrl/client/cost-centers';
static String get clientCostCenters => ClientEndpoints.costCenters.path;
/// Vendors.
static const String clientVendors = '$baseUrl/client/vendors';
static String get clientVendors => ClientEndpoints.vendors.path;
/// Vendor roles by ID.
static String clientVendorRoles(String vendorId) =>
'$baseUrl/client/vendors/$vendorId/roles';
ClientEndpoints.vendorRoles(vendorId).path;
/// Hub managers by ID.
static String clientHubManagers(String hubId) =>
'$baseUrl/client/hubs/$hubId/managers';
ClientEndpoints.hubManagers(hubId).path;
/// Team members.
static const String clientTeamMembers = '$baseUrl/client/team-members';
static String get clientTeamMembers => ClientEndpoints.teamMembers.path;
/// View orders.
static const String clientOrdersView = '$baseUrl/client/orders/view';
static String get clientOrdersView => ClientEndpoints.ordersView.path;
/// Order reorder preview.
static String clientOrderReorderPreview(String orderId) =>
'$baseUrl/client/orders/$orderId/reorder-preview';
ClientEndpoints.orderReorderPreview(orderId).path;
/// Reports summary.
static const String clientReportsSummary = '$baseUrl/client/reports/summary';
static String get clientReportsSummary =>
ClientEndpoints.reportsSummary.path;
/// Daily ops report.
static const String clientReportsDailyOps =
'$baseUrl/client/reports/daily-ops';
static String get clientReportsDailyOps =>
ClientEndpoints.reportsDailyOps.path;
/// Spend report.
static const String clientReportsSpend = '$baseUrl/client/reports/spend';
static String get clientReportsSpend => ClientEndpoints.reportsSpend.path;
/// Coverage report.
static const String clientReportsCoverage =
'$baseUrl/client/reports/coverage';
static String get clientReportsCoverage =>
ClientEndpoints.reportsCoverage.path;
/// Forecast report.
static const String clientReportsForecast =
'$baseUrl/client/reports/forecast';
static String get clientReportsForecast =>
ClientEndpoints.reportsForecast.path;
/// Performance report.
static const String clientReportsPerformance =
'$baseUrl/client/reports/performance';
static String get clientReportsPerformance =>
ClientEndpoints.reportsPerformance.path;
/// No-show report.
static const String clientReportsNoShow = '$baseUrl/client/reports/no-show';
static String get clientReportsNoShow =>
ClientEndpoints.reportsNoShow.path;
// ── Client Write ──────────────────────────────────────────────────────
/// Create one-time order.
static const String clientOrdersOneTime = '$baseUrl/client/orders/one-time';
static String get clientOrdersOneTime =>
ClientEndpoints.ordersOneTime.path;
/// Create recurring order.
static const String clientOrdersRecurring =
'$baseUrl/client/orders/recurring';
static String get clientOrdersRecurring =>
ClientEndpoints.ordersRecurring.path;
/// Create permanent order.
static const String clientOrdersPermanent =
'$baseUrl/client/orders/permanent';
static String get clientOrdersPermanent =>
ClientEndpoints.ordersPermanent.path;
/// Edit order by ID.
static String clientOrderEdit(String orderId) =>
'$baseUrl/client/orders/$orderId/edit';
ClientEndpoints.orderEdit(orderId).path;
/// Cancel order by ID.
static String clientOrderCancel(String orderId) =>
'$baseUrl/client/orders/$orderId/cancel';
ClientEndpoints.orderCancel(orderId).path;
/// Create hub.
static const String clientHubCreate = '$baseUrl/client/hubs';
static String get clientHubCreate => ClientEndpoints.hubCreate.path;
/// Update hub by ID.
static String clientHubUpdate(String hubId) =>
'$baseUrl/client/hubs/$hubId';
ClientEndpoints.hubUpdate(hubId).path;
/// Delete hub by ID.
static String clientHubDelete(String hubId) =>
'$baseUrl/client/hubs/$hubId';
ClientEndpoints.hubDelete(hubId).path;
/// Assign NFC to hub.
static String clientHubAssignNfc(String hubId) =>
'$baseUrl/client/hubs/$hubId/assign-nfc';
ClientEndpoints.hubAssignNfc(hubId).path;
/// Assign managers to hub.
static String clientHubAssignManagers(String hubId) =>
'$baseUrl/client/hubs/$hubId/managers';
ClientEndpoints.hubAssignManagers(hubId).path;
/// Approve invoice.
static String clientInvoiceApprove(String invoiceId) =>
'$baseUrl/client/billing/invoices/$invoiceId/approve';
ClientEndpoints.invoiceApprove(invoiceId).path;
/// Dispute invoice.
static String clientInvoiceDispute(String invoiceId) =>
'$baseUrl/client/billing/invoices/$invoiceId/dispute';
ClientEndpoints.invoiceDispute(invoiceId).path;
/// Submit coverage review.
static const String clientCoverageReviews =
'$baseUrl/client/coverage/reviews';
static String get clientCoverageReviews =>
ClientEndpoints.coverageReviews.path;
/// Cancel late worker assignment.
static String clientCoverageCancelLateWorker(String assignmentId) =>
'$baseUrl/client/coverage/late-workers/$assignmentId/cancel';
ClientEndpoints.coverageCancelLateWorker(assignmentId).path;
}

View File

@@ -1,14 +1,19 @@
import 'package:dio/dio.dart';
import 'package:krow_core/src/config/app_config.dart';
import 'package:krow_core/src/services/api_service/inspectors/auth_interceptor.dart';
import 'package:krow_core/src/services/api_service/inspectors/idempotency_interceptor.dart';
/// A custom Dio client for the KROW project that includes basic configuration,
/// [AuthInterceptor], and [IdempotencyInterceptor].
///
/// Sets [AppConfig.v2ApiBaseUrl] as the base URL so that endpoint paths only
/// need to be relative (e.g. '/staff/dashboard').
class DioClient extends DioMixin implements Dio {
DioClient([BaseOptions? baseOptions]) {
options =
baseOptions ??
BaseOptions(
baseUrl: AppConfig.v2ApiBaseUrl,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
);

View File

@@ -0,0 +1,34 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart';
/// Authentication endpoints for both staff and client apps.
abstract final class AuthEndpoints {
/// Client email/password sign-in.
static const ApiEndpoint clientSignIn =
ApiEndpoint('/auth/client/sign-in');
/// Client business registration.
static const ApiEndpoint clientSignUp =
ApiEndpoint('/auth/client/sign-up');
/// Client sign-out.
static const ApiEndpoint clientSignOut =
ApiEndpoint('/auth/client/sign-out');
/// Start staff phone verification (SMS).
static const ApiEndpoint staffPhoneStart =
ApiEndpoint('/auth/staff/phone/start');
/// Complete staff phone verification.
static const ApiEndpoint staffPhoneVerify =
ApiEndpoint('/auth/staff/phone/verify');
/// Generic sign-out.
static const ApiEndpoint signOut = ApiEndpoint('/auth/sign-out');
/// Staff-specific sign-out.
static const ApiEndpoint staffSignOut =
ApiEndpoint('/auth/staff/sign-out');
/// Get current session data.
static const ApiEndpoint session = ApiEndpoint('/auth/session');
}

View File

@@ -0,0 +1,165 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart';
/// Client-specific API endpoints (read and write).
abstract final class ClientEndpoints {
// ── Read ──────────────────────────────────────────────────────────────
/// Client session data.
static const ApiEndpoint session = ApiEndpoint('/client/session');
/// Client dashboard.
static const ApiEndpoint dashboard = ApiEndpoint('/client/dashboard');
/// Client reorders.
static const ApiEndpoint reorders = ApiEndpoint('/client/reorders');
/// Billing accounts.
static const ApiEndpoint billingAccounts =
ApiEndpoint('/client/billing/accounts');
/// Pending invoices.
static const ApiEndpoint billingInvoicesPending =
ApiEndpoint('/client/billing/invoices/pending');
/// Invoice history.
static const ApiEndpoint billingInvoicesHistory =
ApiEndpoint('/client/billing/invoices/history');
/// Current bill.
static const ApiEndpoint billingCurrentBill =
ApiEndpoint('/client/billing/current-bill');
/// Savings data.
static const ApiEndpoint billingSavings =
ApiEndpoint('/client/billing/savings');
/// Spend breakdown.
static const ApiEndpoint billingSpendBreakdown =
ApiEndpoint('/client/billing/spend-breakdown');
/// Coverage overview.
static const ApiEndpoint coverage = ApiEndpoint('/client/coverage');
/// Coverage stats.
static const ApiEndpoint coverageStats =
ApiEndpoint('/client/coverage/stats');
/// Core team.
static const ApiEndpoint coverageCoreTeam =
ApiEndpoint('/client/coverage/core-team');
/// Hubs list.
static const ApiEndpoint hubs = ApiEndpoint('/client/hubs');
/// Cost centers.
static const ApiEndpoint costCenters =
ApiEndpoint('/client/cost-centers');
/// Vendors.
static const ApiEndpoint vendors = ApiEndpoint('/client/vendors');
/// Vendor roles by ID.
static ApiEndpoint vendorRoles(String vendorId) =>
ApiEndpoint('/client/vendors/$vendorId/roles');
/// Hub managers by ID.
static ApiEndpoint hubManagers(String hubId) =>
ApiEndpoint('/client/hubs/$hubId/managers');
/// Team members.
static const ApiEndpoint teamMembers =
ApiEndpoint('/client/team-members');
/// View orders.
static const ApiEndpoint ordersView =
ApiEndpoint('/client/orders/view');
/// Order reorder preview.
static ApiEndpoint orderReorderPreview(String orderId) =>
ApiEndpoint('/client/orders/$orderId/reorder-preview');
/// Reports summary.
static const ApiEndpoint reportsSummary =
ApiEndpoint('/client/reports/summary');
/// Daily ops report.
static const ApiEndpoint reportsDailyOps =
ApiEndpoint('/client/reports/daily-ops');
/// Spend report.
static const ApiEndpoint reportsSpend =
ApiEndpoint('/client/reports/spend');
/// Coverage report.
static const ApiEndpoint reportsCoverage =
ApiEndpoint('/client/reports/coverage');
/// Forecast report.
static const ApiEndpoint reportsForecast =
ApiEndpoint('/client/reports/forecast');
/// Performance report.
static const ApiEndpoint reportsPerformance =
ApiEndpoint('/client/reports/performance');
/// No-show report.
static const ApiEndpoint reportsNoShow =
ApiEndpoint('/client/reports/no-show');
// ── Write ─────────────────────────────────────────────────────────────
/// Create one-time order.
static const ApiEndpoint ordersOneTime =
ApiEndpoint('/client/orders/one-time');
/// Create recurring order.
static const ApiEndpoint ordersRecurring =
ApiEndpoint('/client/orders/recurring');
/// Create permanent order.
static const ApiEndpoint ordersPermanent =
ApiEndpoint('/client/orders/permanent');
/// Edit order by ID.
static ApiEndpoint orderEdit(String orderId) =>
ApiEndpoint('/client/orders/$orderId/edit');
/// Cancel order by ID.
static ApiEndpoint orderCancel(String orderId) =>
ApiEndpoint('/client/orders/$orderId/cancel');
/// Create hub (same path as list hubs).
static const ApiEndpoint hubCreate = ApiEndpoint('/client/hubs');
/// Update hub by ID.
static ApiEndpoint hubUpdate(String hubId) =>
ApiEndpoint('/client/hubs/$hubId');
/// Delete hub by ID.
static ApiEndpoint hubDelete(String hubId) =>
ApiEndpoint('/client/hubs/$hubId');
/// Assign NFC to hub.
static ApiEndpoint hubAssignNfc(String hubId) =>
ApiEndpoint('/client/hubs/$hubId/assign-nfc');
/// Assign managers to hub.
static ApiEndpoint hubAssignManagers(String hubId) =>
ApiEndpoint('/client/hubs/$hubId/managers');
/// Approve invoice.
static ApiEndpoint invoiceApprove(String invoiceId) =>
ApiEndpoint('/client/billing/invoices/$invoiceId/approve');
/// Dispute invoice.
static ApiEndpoint invoiceDispute(String invoiceId) =>
ApiEndpoint('/client/billing/invoices/$invoiceId/dispute');
/// Submit coverage review.
static const ApiEndpoint coverageReviews =
ApiEndpoint('/client/coverage/reviews');
/// Cancel late worker assignment.
static ApiEndpoint coverageCancelLateWorker(String assignmentId) =>
ApiEndpoint('/client/coverage/late-workers/$assignmentId/cancel');
}

View File

@@ -0,0 +1,40 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart';
/// Core infrastructure endpoints (upload, signed URLs, LLM, verifications,
/// rapid orders).
abstract final class CoreEndpoints {
/// Upload a file.
static const ApiEndpoint uploadFile =
ApiEndpoint('/core/upload-file');
/// Create a signed URL for a file.
static const ApiEndpoint createSignedUrl =
ApiEndpoint('/core/create-signed-url');
/// Invoke a Large Language Model.
static const ApiEndpoint invokeLlm = ApiEndpoint('/core/invoke-llm');
/// Root for verification operations.
static const ApiEndpoint verifications =
ApiEndpoint('/core/verifications');
/// Get status of a verification job.
static ApiEndpoint verificationStatus(String id) =>
ApiEndpoint('/core/verifications/$id');
/// Review a verification decision.
static ApiEndpoint verificationReview(String id) =>
ApiEndpoint('/core/verifications/$id/review');
/// Retry a verification job.
static ApiEndpoint verificationRetry(String id) =>
ApiEndpoint('/core/verifications/$id/retry');
/// Transcribe audio to text for rapid orders.
static const ApiEndpoint transcribeRapidOrder =
ApiEndpoint('/core/rapid-orders/transcribe');
/// Parse text to structured rapid order.
static const ApiEndpoint parseRapidOrder =
ApiEndpoint('/core/rapid-orders/parse');
}

View File

@@ -0,0 +1,176 @@
import 'package:krow_core/src/services/api_service/api_endpoint.dart';
/// Staff-specific API endpoints (read and write).
abstract final class StaffEndpoints {
// ── Read ──────────────────────────────────────────────────────────────
/// Staff session data.
static const ApiEndpoint session = ApiEndpoint('/staff/session');
/// Staff dashboard overview.
static const ApiEndpoint dashboard = ApiEndpoint('/staff/dashboard');
/// Staff profile completion status.
static const ApiEndpoint profileCompletion =
ApiEndpoint('/staff/profile-completion');
/// Staff availability schedule.
static const ApiEndpoint availability = ApiEndpoint('/staff/availability');
/// Today's shifts for clock-in.
static const ApiEndpoint clockInShiftsToday =
ApiEndpoint('/staff/clock-in/shifts/today');
/// Current clock-in status.
static const ApiEndpoint clockInStatus =
ApiEndpoint('/staff/clock-in/status');
/// Payments summary.
static const ApiEndpoint paymentsSummary =
ApiEndpoint('/staff/payments/summary');
/// Payments history.
static const ApiEndpoint paymentsHistory =
ApiEndpoint('/staff/payments/history');
/// Payments chart data.
static const ApiEndpoint paymentsChart =
ApiEndpoint('/staff/payments/chart');
/// Assigned shifts.
static const ApiEndpoint shiftsAssigned =
ApiEndpoint('/staff/shifts/assigned');
/// Open shifts available to apply.
static const ApiEndpoint shiftsOpen = ApiEndpoint('/staff/shifts/open');
/// Pending shift assignments.
static const ApiEndpoint shiftsPending =
ApiEndpoint('/staff/shifts/pending');
/// Cancelled shifts.
static const ApiEndpoint shiftsCancelled =
ApiEndpoint('/staff/shifts/cancelled');
/// Completed shifts.
static const ApiEndpoint shiftsCompleted =
ApiEndpoint('/staff/shifts/completed');
/// Shift details by ID.
static ApiEndpoint shiftDetails(String shiftId) =>
ApiEndpoint('/staff/shifts/$shiftId');
/// Staff profile sections overview.
static const ApiEndpoint profileSections =
ApiEndpoint('/staff/profile/sections');
/// Personal info.
static const ApiEndpoint personalInfo =
ApiEndpoint('/staff/profile/personal-info');
/// Industries/experience.
static const ApiEndpoint industries =
ApiEndpoint('/staff/profile/industries');
/// Skills.
static const ApiEndpoint skills = ApiEndpoint('/staff/profile/skills');
/// Documents.
static const ApiEndpoint documents =
ApiEndpoint('/staff/profile/documents');
/// Attire items.
static const ApiEndpoint attire = ApiEndpoint('/staff/profile/attire');
/// Tax forms.
static const ApiEndpoint taxForms =
ApiEndpoint('/staff/profile/tax-forms');
/// Emergency contacts.
static const ApiEndpoint emergencyContacts =
ApiEndpoint('/staff/profile/emergency-contacts');
/// Certificates.
static const ApiEndpoint certificates =
ApiEndpoint('/staff/profile/certificates');
/// Bank accounts.
static const ApiEndpoint bankAccounts =
ApiEndpoint('/staff/profile/bank-accounts');
/// Benefits.
static const ApiEndpoint benefits = ApiEndpoint('/staff/profile/benefits');
/// Time card.
static const ApiEndpoint timeCard =
ApiEndpoint('/staff/profile/time-card');
/// Privacy settings.
static const ApiEndpoint privacy = ApiEndpoint('/staff/profile/privacy');
/// FAQs.
static const ApiEndpoint faqs = ApiEndpoint('/staff/faqs');
/// FAQs search.
static const ApiEndpoint faqsSearch = ApiEndpoint('/staff/faqs/search');
// ── Write ─────────────────────────────────────────────────────────────
/// Staff profile setup.
static const ApiEndpoint profileSetup =
ApiEndpoint('/staff/profile/setup');
/// Clock in.
static const ApiEndpoint clockIn = ApiEndpoint('/staff/clock-in');
/// Clock out.
static const ApiEndpoint clockOut = ApiEndpoint('/staff/clock-out');
/// Quick-set availability.
static const ApiEndpoint availabilityQuickSet =
ApiEndpoint('/staff/availability/quick-set');
/// Apply for a shift.
static ApiEndpoint shiftApply(String shiftId) =>
ApiEndpoint('/staff/shifts/$shiftId/apply');
/// Accept a shift.
static ApiEndpoint shiftAccept(String shiftId) =>
ApiEndpoint('/staff/shifts/$shiftId/accept');
/// Decline a shift.
static ApiEndpoint shiftDecline(String shiftId) =>
ApiEndpoint('/staff/shifts/$shiftId/decline');
/// Request a shift swap.
static ApiEndpoint shiftRequestSwap(String shiftId) =>
ApiEndpoint('/staff/shifts/$shiftId/request-swap');
/// Update emergency contact by ID.
static ApiEndpoint emergencyContactUpdate(String contactId) =>
ApiEndpoint('/staff/profile/emergency-contacts/$contactId');
/// Update tax form by type.
static ApiEndpoint taxFormUpdate(String formType) =>
ApiEndpoint('/staff/profile/tax-forms/$formType');
/// Submit tax form by type.
static ApiEndpoint taxFormSubmit(String formType) =>
ApiEndpoint('/staff/profile/tax-forms/$formType/submit');
/// Upload staff profile photo.
static const ApiEndpoint profilePhoto =
ApiEndpoint('/staff/profile/photo');
/// Upload document by ID.
static ApiEndpoint documentUpload(String documentId) =>
ApiEndpoint('/staff/profile/documents/$documentId/upload');
/// Upload attire by ID.
static ApiEndpoint attireUpload(String documentId) =>
ApiEndpoint('/staff/profile/attire/$documentId/upload');
/// Delete certificate by ID.
static ApiEndpoint certificateDelete(String certificateId) =>
ApiEndpoint('/staff/profile/certificates/$certificateId');
}

View File

@@ -1,5 +1,6 @@
import 'package:dio/dio.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:krow_core/src/services/api_service/endpoints/auth_endpoints.dart';
/// An interceptor that adds the Firebase Auth ID token to the Authorization
/// header and retries once on 401 with a force-refreshed token.
@@ -9,10 +10,10 @@ import 'package:firebase_auth/firebase_auth.dart';
/// endpoints DO require the token.
class AuthInterceptor extends Interceptor {
/// Auth paths that must NOT receive a Bearer token (no session exists yet).
static const List<String> _unauthenticatedPaths = <String>[
'/auth/client/sign-in',
'/auth/client/sign-up',
'/auth/staff/phone/start',
static final List<String> _unauthenticatedPaths = <String>[
AuthEndpoints.clientSignIn.path,
AuthEndpoints.clientSignUp.path,
AuthEndpoints.staffPhoneStart.path,
];
/// Tracks whether a 401 retry is in progress to prevent infinite loops.