Saltar al contenido principal

FlowPOS Frontend PWA — App Structure (AI Context Document)

Use this document to onboard another AI or developer to the frontend-pwa codebase.

Overview​

FlowPOS Frontend PWA is a Progressive Web App for a multi-tenant SaaS Point-of-Sale and Business Management System. It serves restaurant and retail workflows, including kitchen displays, POS, inventory, and discovery catalogs.

  • Framework: Vite 6 + React 19
  • UI: Shadcn/ui, Lucide Icons, Tailwind CSS
  • Routing: React Router 7
  • State: TanStack Query 5
  • Forms: React Hook Form + Zod + @hookform/resolvers
  • i18n: i18next
  • Auth: Firebase
  • Real-time: Socket.IO (restaurant)
  • Dev port: 5173

Root Configuration Files​

FilePurpose
package.jsonDependencies, scripts
vite.config.tsVite config, PWA plugin, path aliases, manual chunks
tsconfig.app.jsonTypeScript for app source
tsconfig.node.jsonTypeScript for Vite config
vitest.config.tsVitest test config
tailwind.config.jsTailwind CSS
postcss.config.jsPostCSS (for Tailwind)

Path Aliases (vite.config.ts)​

  • @ → ./src
  • @flowpos-workspace/backend-database → ../../packages/backend/database/src
  • @flowpos-workspace/global → ../../packages/global
  • @flowpos-workspace/global-policies → ../../packages/global/policies/src

Source Structure (src/)​

Entry & App Shell​

PathPurpose
main.tsxApp entry, React root
App.tsxRoot component, provider tree, routing

Provider Tree (from App.tsx)​

React.StrictMode
└── I18nextProvider
└── AuthProvider
└── ThemeProvider
└── QueryClientProvider
└── BusinessProvider
└── LocationProvider
├── ServiceWorkerRegister
├── Toaster / Sonner
└── BrowserRouter

Routing Structure​

Top-Level Routes​

PathComponentAuthLayout
/LoadingRedirect--
/sign-in, /loginSignInPage--
/loadingLoadingRedirect--
/discoveryDiscoveryCatalogPagePublicDiscoveryLayout
/discovery/product/:productIdDiscoveryProductDetailPagePublicDiscoveryLayout
/onboardingOnboardingPageRequired-
/dashboardDashboardRequiredAuthenticatedLayout
/mainMainPageRequiredAuthenticatedLayout
/main/discoveryDiscoveryCatalogMainViewRequiredAuthenticatedLayout
/main/discovery/product/:productIdDiscoveryProductDetailInAppPageRequiredAuthenticatedLayout
/return-reasonsReturnReasonPageRequiredAuthenticatedLayout
/return-policiesReturnPolicyPageRequiredAuthenticatedLayout
/returns/lookupReceiptLookupPageRequiredAuthenticatedLayout
/returns/processReturnProcessingPageRequiredAuthenticatedLayout
/exchanges/processExchangeProcessingPageRequiredAuthenticatedLayout
/pricingPriceListPageRequiredAuthenticatedLayout
/pricing/newPriceListFormPage (create)RequiredAuthenticatedLayout
/pricing/:id/editPriceListFormPage (edit)RequiredAuthenticatedLayout
/pricing/:idPriceListDetailPageRequiredAuthenticatedLayout
*NotFound--

MainPage Content (form-based navigation)​

MainPage uses location.state?.selectedForm or ?form= to render a single form/screen. Navigation is handled by TreeMenu / CollapsedTreeMenu with onSelect(path).

Form keys (selectedForm):

  • newBusiness, ThemeColorPreview
  • /forms/BusinessPage, /forms/BusinessBillPage, /forms/LocationPage
  • /forms/InviteUserPage, /forms/InvitationActionPage, /forms/UsersPage
  • /forms/AddressesPage, /forms/FormsPage, /forms/UserProfilePage, /forms/AboutPage
  • /forms/UnitOfMeasurePage, /forms/CurrencyPage, /forms/ExchangeRatePage, /forms/ModulePage, /forms/PaymentMethodPage
  • /system/ParameterCatalogPage, /system/EntityParametersPage
  • /forms/CategoryPage, /forms/BrandPage, /forms/StylePage, /forms/ModelPage, /forms/ColorPage, /forms/SizePage, /forms/AttributePage
  • /forms/SupplierPage, /forms/EmployeePage, /forms/ProductPage, /forms/ServicePage
  • /forms/InventoryPage, /forms/InventoryDetailSerialPage, /forms/InventoryDetailBatchPage
  • /forms/purchaseOrder, /forms/goodsReceivedNote, /forms/purchase
  • /forms/ProductionRunPage, /forms/ProductionFormulaPage
  • /forms/TaxDefinitionPage
  • /forms/TransferRequestPage, /forms/InventoryTransferPage, /forms/TransferDispatchNotePage, /forms/TransferGoodsReceiptPage
  • /forms/StockCountSessionsPage, /forms/StockCountTasksPage, /forms/StockCountMyTasksPage
  • /forms/ServiceBookingPage, /forms/CashRegisterPage, /forms/CashRegisterGuidePage, /forms/SafePage
  • Restaurant: restaurantDining, restaurantOrders, restaurantKds, restaurantExpo, restaurantKitchenLoad, restaurantPackingScanner, restaurantKitchenStations, restaurantExternalPlatformMappings, restaurantReservations, restaurantWaitlist, restaurantPriceRules, restaurantMenus
  • /forms/contractorAssignment, /forms/BookingPlatformPage, /forms/ServiceTypePage
  • /forms/AccountsPayableDashboardPage, /forms/AccountsReceivableDashboardPage
  • /forms/AccountsPayablePage, /forms/AccountsPayableReportsPage, /forms/AccountsReceivablePage, /forms/AccountsReceivableReportsPage
  • /forms/InventoryAdjustmentPage, /forms/CustomerPage, /forms/sale, /forms/quotePage
  • /forms/TemplateManagementPage, /forms/LocationTemplateConfigPage
  • /forms/CommunicationsHistoryPage, /forms/CommunicationStatsPage, /forms/SendCommunicationPage
  • /forms/RecipientGroupsPage, /forms/RecipientRulesPage
  • /forms/GlobalPreferencesManagementPage, /forms/CustomerPreferencesPage
  • /forms/TemplatesManagementPage, /forms/TemplateEditorPage
  • /forms/ImportCenterDashboardPage, /forms/ImportWizardPage, /forms/ImportJobsPage
  • /forms/BillingDashboardPage, /forms/BillingReportsPage
  • /forms/DamagedItemsPage, /forms/BundleRulesPage, /forms/RetailReservationsPage
  • /forms/ReturnReasonPage, /forms/ReturnPolicyPage
  • Metabase: DashboardPage, DashboardFormPage, DashboardInstancePage, DashboardModulePage, DashboardRolePage
  • /forms/testReports (TestDashboard)

Directory Layout (src/)​

src/
├── App.tsx
├── main.tsx
├── vite-env.d.ts
├── assets/ # Static assets, background.ts
├── components/ # Reusable UI and form components
│ ├── common/ # Shared (selectors, inputs, buttons, layout)
│ ├── discovery/ # Discovery catalog (QR, kiosk)
│ ├── documents/ # Document delivery, PDF panel
│ ├── forms/ # Feature-specific forms (one folder per domain)
│ │ ├── about/
│ │ ├── accounts-payable/
│ │ ├── accounts-receivable/
│ │ ├── address/
│ │ ├── attribute/
│ │ ├── billing/
│ │ ├── booking-platform/
│ │ ├── brand/
│ │ ├── bundle-rules/
│ │ ├── business/
│ │ ├── cash-register/
│ │ ├── category/
│ │ ├── color/
│ │ ├── communication-preferences/
│ │ ├── communication-templates/
│ │ ├── communications/
│ │ ├── contractor-assignment/
│ │ ├── currency/
│ │ ├── customer/
│ │ ├── damaged-items/
│ │ ├── data-import/
│ │ ├── discount-rules/
│ │ ├── discounts/
│ │ ├── employee/
│ │ ├── exchange-rates/
│ │ ├── forms/
│ │ ├── goods-received-note/
│ │ ├── inventory/
│ │ ├── inventory-adjustment/
│ │ ├── inventory-detail/
│ │ ├── inventory-detail-batch/
│ │ ├── inventory-detail-serial/
│ │ ├── inventory-transfer/
│ │ ├── invitation/
│ │ ├── invite/
│ │ ├── invoice-notes/
│ │ ├── location/
│ │ ├── material-consumption/
│ │ ├── model/
│ │ ├── module/
│ │ ├── payment-method/
│ │ ├── pricing/
│ │ ├── product/
│ │ ├── production-formula/
│ │ ├── production-run/
│ │ ├── purchase/
│ │ ├── purchase-order/
│ │ ├── queue/
│ │ ├── quote/
│ │ ├── recipient-groups/
│ │ ├── recipient-rules/
│ │ ├── register/
│ │ ├── restaurant/ # Restaurant POS, KDS, expo, kitchen, etc.
│ │ ├── retail-reservations/
│ │ ├── return-policy/
│ │ ├── return-reason/
│ │ ├── safe/
│ │ ├── sale/
│ │ ├── service/
│ │ ├── service-booking/
│ │ ├── service-type/
│ │ ├── shared/
│ │ ├── size/
│ │ ├── stock-count-entry/
│ │ ├── stock-count-session/
│ │ ├── stock-count-task/
│ │ ├── stock-count-variance/
│ │ ├── style/
│ │ ├── supplier/
│ │ ├── tax-definition/
│ │ ├── transfer-dispatch-note/
│ │ ├── transfer-goods-receipt/
│ │ ├── transfer-request/
│ │ ├── uom/
│ │ └── user/
│ ├── onboarding/
│ ├── system/ # Metabase, entity parameters, parameter catalog
│ ├── templates/ # Location templates, template management
│ ├── TreeMenu/
│ └── ui/ # Shadcn primitives (button, dialog, etc.)
├── constants/ # App constants, parameter types
├── contexts/ # React contexts
│ ├── AuthContext
│ ├── BusinessContext / BusinessProvider
│ ├── LocationProvider
│ ├── ThemeProvider
│ └── useCurrentBusiness
├── features/ # Feature-specific logic (e.g. reports)
├── hooks/ # Custom hooks
├── i18n/ # i18next config, locales (en, es, es-GT, es-ES, es-MX)
├── layouts/ # AuthenticatedLayout, DiscoveryLayout
├── lib/ # API client, constants
├── pages/ # Route-level page components
│ ├── Dashboard
│ ├── MainPage
│ ├── NotFound
│ ├── OnboardingPage
│ ├── SignInPage
│ ├── LoadingRedirect
│ ├── UserProfilePage
│ ├── discovery/
│ ├── exchanges/
│ └── returns/
├── schemas/ # Zod schemas
├── services/ # API service functions (by domain)
├── test/ # test-utils, setup
└── types/ # TypeScript types

Form Component Conventions​

Each form domain under components/forms/<domain>/ typically has:

PatternExamplesPurpose
*Page.tsxProductPage, InventoryPageFull-page container
*Form.tsxProductForm, InventoryAdjustmentFormCreate/edit form
*List.tsxProductList, BillsListList/table view
*Modal.tsxBillDetailModal, DiscountModalModal dialogs
*Search.tsxPurchaseOrderSearchSearch/filter for lists
*ItemRow.tsxPurchaseOrderItemRowRow component for line items

Services (API Layer)​

Services live in src/services/ and mirror backend modules. Each service typically:

  • Uses src/lib/api.ts for HTTP (GET, POST, PATCH, DELETE)
  • Uses TanStack Query in components via hooks/use*.ts
  • Follows multi-tenant scoping (businessId, locationId)

Examples: productService.ts, inventoryService.ts, accountsPayableService.ts, restaurantReservationsService.ts, pricingService.ts, etc.


Hooks​

src/hooks/ contains data-fetching and app hooks:

  • useUserData, useAuth
  • useProducts, useProductNamesByIds, useInventory, useSuppliers, etc.
  • useRestaurantWebSocket, useScanner, useOfflineQueue, use-mobile

Shared Packages​

  • @flowpos-workspace/backend-database: Kysely types, enums
  • @flowpos-workspace/global: Shared enums, types, validators
  • @flowpos-workspace/global-policies: Policies

Scripts (package.json)​

ScriptPurpose
pnpm devDev server (5173)
pnpm buildProduction build
pnpm previewPreview production build
pnpm testVitest
pnpm lintBiome lint
pnpm formatBiome format

Key Conventions​

  1. Path alias @ maps to src/.
  2. Forms use React Hook Form + Zod; validation schemas in schemas/ or inline.
  3. Data fetching via TanStack Query and service functions.
  4. Multi-tenancy: businessId and often locationId are required for business data.
  5. i18n: All user-facing strings use useTranslation() and translation keys in i18n/locales/.
  6. PWA: Uses vite-plugin-pwa; discovery and API routes may be cached for offline use.