Mobile-first write-off approval, audit, and Iiko posting for store teams.
Store Writeoff Control lets a sender capture damaged or unusable inventory with photo proof, route the request to a reviewer, and post approved write-offs to Iiko from trusted server code. It is intentionally small: one Next.js app, one Supabase project, raw SQL migrations, and a retryable integration job queue.
- Creates write-off requests with outlet, product lines, quantity, photo proof, comment, and optional employee deduction.
- Routes requests by role:
sender,reviewer, andadmin. - Lets reviewers approve or reject requests with an immutable audit trail.
- Posts approved requests to Iiko through server-only integration code.
- Retries failed Iiko jobs through a protected Vercel Cron route.
- Keeps photos in a private Supabase Storage bucket with signed URLs.
- Gives admins a settings screen for outlet-to-Iiko mapping.
- Next.js 16.2.9 App Router, React 19.2.7, and TypeScript 5.9.3
- Tailwind CSS 4.3.1
- Supabase Auth, Postgres, Storage, RLS,
@supabase/ssr0.7.0, and@supabase/supabase-js2.108.2 - Raw SQL migrations in
supabase/migrations postgresfor direct SQL, with a service-role Supabase RPC fallback- Vercel Cron for background Iiko retries
- Zod for server-action validation
npm install
Copy-Item .env.example .env.local
npm run devFill .env.local with Supabase credentials before signing in. For local UI and
workflow development, IIKO_MODE=auto is enough: the app falls back to the demo
Iiko gateway when live Iiko credentials are missing.
Open http://localhost:3000. The root route sends authenticated users to the
first page their role can use.
The database schema lives in SQL migrations and is designed around RLS plus server-side use cases:
supabase link --project-ref <project-ref>
supabase db push --linked --dry-run
supabase db push --linkedImportant
Verify the linked Supabase project before applying migrations. This workspace
is currently linked to gufokukibouyuyzfqcll.
Core tables:
profiles: app role and display name for each Supabase Auth user.outlets,employees,products: active reference data and Iiko mappings.writeoff_requests,writeoff_lines: the request aggregate.iiko_jobs: retry state for posting approved write-offs.audit_events: append-only business and integration history.
npm run dev
npm run format:check
npm run lint
npm run typecheck
npm run build
npm run ciOptional showcase data can be loaded after linking Supabase and setting a demo password:
$env:WRITE_OFF_DEMO_PASSWORD="change-me"
node scripts/seed-showcase-data.mjssrc/app Next.js routes, layouts, route handlers
src/widgets Screen-level UI blocks
src/features Server actions for user workflows
src/entities Domain-facing UI types and small fragments
src/shared Config, validation, generic UI, utilities
src/server/domain Pure write-off rules and domain types
src/server/application Use cases and ports
src/server/infrastructure SQL, Supabase, storage, and Iiko adapters
supabase/migrations Database, RLS, storage, and RPC migrations
docs Architecture, integration, and dev notesThe main architectural rule is simple: browser code never talks to Iiko and never receives service credentials. UI actions call application use cases; use cases coordinate domain rules, persistence, storage, audit, and integration ports.
- Architecture explains layers, request state, persistence, RLS, and runtime boundaries.
- Iiko Integration documents live/demo mode, mapping requirements, retry behavior, and operational checks.
- Development covers environment variables, Supabase setup, demo data, deployment, and verification commands.