# dushansenura/stokia architecture

> Architecture diagram of the GitHub repository dushansenura/stokia, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/dushansenura/stokia
- Repository: https://github.com/dushansenura/stokia

## Overview

Stokia is a daily inventory and estimated-sales product for small shops, with a Next.js web app and an Expo phone app. The central workflow is morning stock entry: shops record counts and movements, the system reconciles stock to estimate the previous day’s sales, and users review dashboards and monthly reports. Products and packaging define the catalog and unit conversions; reports and analytics present derived results. The phone app and web PWA support offline queues and conflict handling. Edges rely on README statements or shown source references; unsampled areas are represented at their existing directory paths.

Main entry points: [`src/app`](https://github.com/dushansenura/stokia/tree/main/src/app) (Web app), [`src/server/actions`](https://github.com/dushansenura/stokia/tree/main/src/server/actions) (Server actions), [`src/app/api/v1`](https://github.com/dushansenura/stokia/tree/main/src/app/api/v1) (Phone API routes), [`src/features/inventory/count-entry.ts`](https://github.com/dushansenura/stokia/blob/main/src/features/inventory/count-entry.ts) (Count entry rules)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web experience"]
  node_web_app["Web app"]
  node_auth_ui["Sign-in and setup<br/>[auth-forms.tsx]"]
  node_stock_ui["Morning count"]
  node_movement_ui["Stock movements<br/>[movement-forms.tsx]"]
  node_product_ui["Product catalog"]
  node_packaging_ui["Packaging tools"]
  node_dashboard_ui["Dashboard and analytics"]
  node_reports_ui["Reports"]
  node_settings_ui["Settings and team"]
end

subgraph group_domain["Inventory and insights"]
  node_count_entry["Count entry rules<br/>[count-entry.ts]"]
  node_sales_calc["Estimated sales<br/>[inferred-sales.ts]"]
  node_reconcile["Stock reconciliation<br/>[reconcile.ts]"]
  node_packaging_calc["Unit conversion<br/>[packaging.ts]"]
  node_analytics["Analytics aggregation<br/>[aggregate.ts]"]
  node_report_logic["Report generation<br/>[report.ts]"]
end

subgraph group_server["Server and persistence"]
  node_web_actions["Server actions"]
  node_api_routes["Phone API routes"]
  node_api_auth["API authentication<br/>[v1.ts]"]
  node_session["Session context<br/>[session.ts]"]
  node_repositories["Data repositories"]
end

subgraph group_offline["Offline and sync"]
  node_queue_engine["Offline queue rules<br/>[queue-engine.ts]"]
  node_web_sync["Web sync provider<br/>[sync-provider.tsx]"]
end

subgraph group_mobile["Phone app"]
  node_phone["Phone app"]
  node_phone_features["Phone features"]
  node_phone_api["Phone API client<br/>[api-client.ts]"]
  node_phone_queue["Phone offline queue"]
end

node_shop_user(("Shop user"))
node_supabase[("Supabase database")]

node_shop_user -->|"uses"| node_web_app
node_shop_user -->|"uses"| node_phone
node_web_app -.->|"presents"| node_auth_ui
node_web_app -.->|"presents"| node_stock_ui
node_web_app -.->|"presents"| node_movement_ui
node_web_app -.->|"presents"| node_product_ui
node_web_app -.->|"presents"| node_packaging_ui
node_web_app -.->|"presents"| node_dashboard_ui
node_web_app -.->|"presents"| node_reports_ui
node_web_app -.->|"presents"| node_settings_ui
node_stock_ui -->|"submits counts"| node_count_entry
node_count_entry -->|"converts units"| node_packaging_calc
node_count_entry -->|"reconciles stock"| node_reconcile
node_reconcile -.->|"estimates sales"| node_sales_calc
node_movement_ui -.->|"records movements"| node_web_actions
node_web_actions -.->|"uses"| node_repositories
node_product_ui -.->|"manages catalog"| node_web_actions
node_packaging_ui -->|"previews conversion"| node_packaging_calc
node_dashboard_ui -.->|"shows insights"| node_analytics
node_reports_ui -.->|"renders reports"| node_report_logic
node_report_logic -->|"uses aggregates"| node_analytics
node_settings_ui -.->|"configures shop"| node_web_actions
node_web_actions -.->|"resolves session"| node_session
node_session -->|"reads membership"| node_supabase
node_repositories -.->|"reads and writes"| node_supabase
node_api_routes -->|"authenticates"| node_api_auth
node_api_routes -.->|"serves data"| node_repositories
node_api_routes -.->|"accesses data"| node_supabase
node_phone -->|"presents"| node_phone_features
node_phone_features -->|"requests data"| node_phone_api
node_phone_api -->|"calls versioned API"| node_api_routes
node_web_sync -->|"uses queue rules"| node_queue_engine
node_phone_queue -->|"shares queue rules"| node_queue_engine
node_phone_features -->|"queues offline work"| node_phone_queue

click node_web_app "https://github.com/dushansenura/stokia/tree/main/src/app"
click node_auth_ui "https://github.com/dushansenura/stokia/blob/main/src/components/shared/auth-forms.tsx"
click node_stock_ui "https://github.com/dushansenura/stokia/blob/main/src/components/stock/morning-stock-entry.tsx"
click node_movement_ui "https://github.com/dushansenura/stokia/blob/main/src/components/movements/movement-forms.tsx"
click node_product_ui "https://github.com/dushansenura/stokia/tree/main/src/components/products"
click node_packaging_ui "https://github.com/dushansenura/stokia/tree/main/src/components/packaging"
click node_dashboard_ui "https://github.com/dushansenura/stokia/tree/main/src/components/dashboard"
click node_reports_ui "https://github.com/dushansenura/stokia/tree/main/src/components/reports"
click node_settings_ui "https://github.com/dushansenura/stokia/tree/main/src/components/settings"
click node_count_entry "https://github.com/dushansenura/stokia/blob/main/src/features/inventory/count-entry.ts"
click node_sales_calc "https://github.com/dushansenura/stokia/blob/main/src/lib/calculations/inferred-sales.ts"
click node_reconcile "https://github.com/dushansenura/stokia/blob/main/src/lib/calculations/reconcile.ts"
click node_packaging_calc "https://github.com/dushansenura/stokia/blob/main/src/lib/calculations/packaging.ts"
click node_analytics "https://github.com/dushansenura/stokia/blob/main/src/features/analytics/aggregate.ts"
click node_report_logic "https://github.com/dushansenura/stokia/blob/main/src/features/reports/report.ts"
click node_web_actions "https://github.com/dushansenura/stokia/tree/main/src/server/actions"
click node_api_routes "https://github.com/dushansenura/stokia/tree/main/src/app/api/v1"
click node_api_auth "https://github.com/dushansenura/stokia/blob/main/src/server/api/v1.ts"
click node_session "https://github.com/dushansenura/stokia/blob/main/src/server/services/session.ts"
click node_repositories "https://github.com/dushansenura/stokia/tree/main/src/server/repositories"
click node_queue_engine "https://github.com/dushansenura/stokia/blob/main/src/lib/offline/queue-engine.ts"
click node_web_sync "https://github.com/dushansenura/stokia/blob/main/src/providers/sync-provider.tsx"
click node_phone "https://github.com/dushansenura/stokia/tree/main/mobile/src/app"
click node_phone_features "https://github.com/dushansenura/stokia/tree/main/mobile/src/features"
click node_phone_api "https://github.com/dushansenura/stokia/blob/main/mobile/src/lib/api-client.ts"
click node_phone_queue "https://github.com/dushansenura/stokia/tree/main/mobile/src/offline"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_web_app,node_auth_ui,node_stock_ui,node_movement_ui,node_product_ui,node_packaging_ui,node_dashboard_ui,node_reports_ui,node_settings_ui,node_shop_user toneBlue
class node_count_entry,node_sales_calc,node_reconcile,node_packaging_calc,node_analytics,node_report_logic,node_supabase toneAmber
class node_web_actions,node_api_routes,node_api_auth,node_session,node_repositories toneMint
class node_queue_engine,node_web_sync toneRose
class node_phone,node_phone_features,node_phone_api,node_phone_queue toneIndigo
```

## Components

### Web experience

- [Web app](https://github.com/dushansenura/stokia/tree/main/src/app): `src/app`
- [Sign-in and setup](https://github.com/dushansenura/stokia/blob/main/src/components/shared/auth-forms.tsx): `src/components/shared/auth-forms.tsx`
- [Morning count](https://github.com/dushansenura/stokia/blob/main/src/components/stock/morning-stock-entry.tsx): `src/components/stock/morning-stock-entry.tsx`
- [Stock movements](https://github.com/dushansenura/stokia/blob/main/src/components/movements/movement-forms.tsx): `src/components/movements/movement-forms.tsx`
- [Product catalog](https://github.com/dushansenura/stokia/tree/main/src/components/products): `src/components/products`
- [Packaging tools](https://github.com/dushansenura/stokia/tree/main/src/components/packaging): `src/components/packaging`
- [Dashboard and analytics](https://github.com/dushansenura/stokia/tree/main/src/components/dashboard): `src/components/dashboard`
- [Reports](https://github.com/dushansenura/stokia/tree/main/src/components/reports): `src/components/reports`
- [Settings and team](https://github.com/dushansenura/stokia/tree/main/src/components/settings): `src/components/settings`

### Inventory and insights

- [Count entry rules](https://github.com/dushansenura/stokia/blob/main/src/features/inventory/count-entry.ts): `src/features/inventory/count-entry.ts`
- [Estimated sales](https://github.com/dushansenura/stokia/blob/main/src/lib/calculations/inferred-sales.ts): `src/lib/calculations/inferred-sales.ts`
- [Stock reconciliation](https://github.com/dushansenura/stokia/blob/main/src/lib/calculations/reconcile.ts): `src/lib/calculations/reconcile.ts`
- [Unit conversion](https://github.com/dushansenura/stokia/blob/main/src/lib/calculations/packaging.ts): `src/lib/calculations/packaging.ts`
- [Analytics aggregation](https://github.com/dushansenura/stokia/blob/main/src/features/analytics/aggregate.ts): `src/features/analytics/aggregate.ts`
- [Report generation](https://github.com/dushansenura/stokia/blob/main/src/features/reports/report.ts): `src/features/reports/report.ts`

### Server and persistence

- [Server actions](https://github.com/dushansenura/stokia/tree/main/src/server/actions): `src/server/actions`
- [Phone API routes](https://github.com/dushansenura/stokia/tree/main/src/app/api/v1): `src/app/api/v1`
- [API authentication](https://github.com/dushansenura/stokia/blob/main/src/server/api/v1.ts): `src/server/api/v1.ts`
- [Session context](https://github.com/dushansenura/stokia/blob/main/src/server/services/session.ts): `src/server/services/session.ts`
- [Data repositories](https://github.com/dushansenura/stokia/tree/main/src/server/repositories): `src/server/repositories`

### Offline and sync

- [Offline queue rules](https://github.com/dushansenura/stokia/blob/main/src/lib/offline/queue-engine.ts): `src/lib/offline/queue-engine.ts`
- [Web sync provider](https://github.com/dushansenura/stokia/blob/main/src/providers/sync-provider.tsx): `src/providers/sync-provider.tsx`

### Phone app

- [Phone app](https://github.com/dushansenura/stokia/tree/main/mobile/src/app): `mobile/src/app`
- [Phone features](https://github.com/dushansenura/stokia/tree/main/mobile/src/features): `mobile/src/features`
- [Phone API client](https://github.com/dushansenura/stokia/blob/main/mobile/src/lib/api-client.ts): `mobile/src/lib/api-client.ts`
- [Phone offline queue](https://github.com/dushansenura/stokia/tree/main/mobile/src/offline): `mobile/src/offline`

### Other components

- **Shop user**
- **Supabase database**

## Connections

- Shop user → Web app: uses
- Shop user → Phone app: uses
- Web app → Sign-in and setup: presents
- Web app → Morning count: presents
- Web app → Stock movements: presents
- Web app → Product catalog: presents
- Web app → Packaging tools: presents
- Web app → Dashboard and analytics: presents
- Web app → Reports: presents
- Web app → Settings and team: presents
- Morning count → Count entry rules: submits counts
- Count entry rules → Unit conversion: converts units (evidence: `src/features/inventory/count-entry.ts`)
- Count entry rules → Stock reconciliation: reconciles stock (evidence: `src/features/inventory/count-entry.ts`)
- Stock reconciliation → Estimated sales: estimates sales
- Stock movements → Server actions: records movements
- Server actions → Data repositories: uses
- Product catalog → Server actions: manages catalog
- Packaging tools → Unit conversion: previews conversion (evidence: `src/components/packaging/conversion-preview.tsx`)
- Dashboard and analytics → Analytics aggregation: shows insights
- Reports → Report generation: renders reports
- Report generation → Analytics aggregation: uses aggregates (evidence: `src/features/reports/report.ts`)
- Settings and team → Server actions: configures shop
- Server actions → Session context: resolves session
- Session context → Supabase database: reads membership (evidence: `src/server/services/session.ts`)
- Data repositories → Supabase database: reads and writes
- Phone API routes → API authentication: authenticates (evidence: `src/app/api/v1/movements/route.ts`)
- Phone API routes → Data repositories: serves data (evidence: `src/app/api/v1/reports/route.ts`)
- Phone API routes → Supabase database: accesses data
- Phone app → Phone features: presents
- Phone features → Phone API client: requests data
- Phone API client → Phone API routes: calls versioned API
- Web sync provider → Offline queue rules: uses queue rules (evidence: `src/lib/offline/queue-engine.ts`)
- Phone offline queue → Offline queue rules: shares queue rules (evidence: `src/lib/offline/queue-engine.ts`)
- Phone features → Phone offline queue: queues offline work
