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
| File | Purpose |
|---|---|
package.json | Dependencies, scripts |
vite.config.ts | Vite config, PWA plugin, path aliases, manual chunks |
tsconfig.app.json | TypeScript for app source |
tsconfig.node.json | TypeScript for Vite config |
vitest.config.ts | Vitest test config |
tailwind.config.js | Tailwind CSS |
postcss.config.js | PostCSS (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
| Path | Purpose |
|---|---|
main.tsx | App entry, React root |
App.tsx | Root 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
| Path | Component | Auth | Layout |
|---|---|---|---|
/ | LoadingRedirect | - | - |
/sign-in, /login | SignInPage | - | - |
/loading | LoadingRedirect | - | - |
/discovery | DiscoveryCatalogPage | Public | DiscoveryLayout |
/discovery/product/:productId | DiscoveryProductDetailPage | Public | DiscoveryLayout |
/onboarding | OnboardingPage | Required | - |
/dashboard | Dashboard | Required | AuthenticatedLayout |
/main | MainPage | Required | AuthenticatedLayout |
/main/discovery | DiscoveryCatalogMainView | Required | AuthenticatedLayout |
/main/discovery/product/:productId | DiscoveryProductDetailInAppPage | Required | AuthenticatedLayout |
/return-reasons | ReturnReasonPage | Required | AuthenticatedLayout |
/return-policies | ReturnPolicyPage | Required | AuthenticatedLayout |
/returns/lookup | ReceiptLookupPage | Required | AuthenticatedLayout |
/returns/process | ReturnProcessingPage | Required | AuthenticatedLayout |
/exchanges/process | ExchangeProcessingPage | Required | AuthenticatedLayout |
/pricing | PriceListPage | Required | AuthenticatedLayout |
/pricing/new | PriceListFormPage (create) | Required | AuthenticatedLayout |
/pricing/:id/edit | PriceListFormPage (edit) | Required | AuthenticatedLayout |
/pricing/:id | PriceListDetailPage | Required | AuthenticatedLayout |
* | 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:
| Pattern | Examples | Purpose |
|---|---|---|
*Page.tsx | ProductPage, InventoryPage | Full-page container |
*Form.tsx | ProductForm, InventoryAdjustmentForm | Create/edit form |
*List.tsx | ProductList, BillsList | List/table view |
*Modal.tsx | BillDetailModal, DiscountModal | Modal dialogs |
*Search.tsx | PurchaseOrderSearch | Search/filter for lists |
*ItemRow.tsx | PurchaseOrderItemRow | Row component for line items |
Services (API Layer)
Services live in src/services/ and mirror backend modules. Each service typically:
- Uses
src/lib/api.tsfor 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,useAuthuseProducts,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)
| Script | Purpose |
|---|---|
pnpm dev | Dev server (5173) |
pnpm build | Production build |
pnpm preview | Preview production build |
pnpm test | Vitest |
pnpm lint | Biome lint |
pnpm format | Biome format |
Key Conventions
- Path alias
@maps tosrc/. - Forms use React Hook Form + Zod; validation schemas in
schemas/or inline. - Data fetching via TanStack Query and service functions.
- Multi-tenancy:
businessIdand oftenlocationIdare required for business data. - i18n: All user-facing strings use
useTranslation()and translation keys ini18n/locales/. - PWA: Uses
vite-plugin-pwa; discovery and API routes may be cached for offline use.