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.