| ← All Docs AI / Codex Rules

AI / Codex Rules

Mandatory Read before making any changes Last updated: September 2026

Development rules and guidelines for AI assistants working on the AquaDealers codebase. Following these rules prevents regressions, duplicated code, and broken business logic.

Before Changing Anything

Complete all 11 checks before writing any code. Skipping these is the #1 cause of regressions.
1
Inspect existing architecture. Read App.tsx for routes. Check the feature directory structure under src/features/. Understand where the change belongs.
2
Find existing implementation. Grep before writing new code. The codebase has 27 modals, 33 forms, and extensive utilities. Whatever you need probably exists already.
3
Reuse existing components. Check src/components/ui/ (23 components). Button has 9 variants, Card has 5, Modal has focus trap + portal. Don't create new UI primitives.
4
Check related workflows. A bill change affects: inventory (FIFO lots), farmer.total_due (triggers), cash_book, payment_allocations, transaction_events. Map the full impact before editing.
5
Check mobile AND desktop. Layout split at lg: (1024px). Billing has separate mobile (3-step wizard) and desktop (2-step side-by-side) flows. Test both.
6
Check permissions. FeatureGate gates features by subscription plan. Staff permissions are JSONB-based. Both may need updating for new features.
7
Check database impact. Core writes go through RPCs (create_bill_v2, process_return, etc.). Never bypass RPCs with direct inserts — they skip validation, triggers, and audit trails.
8
Check business rules. Financial calculations must match RPC logic exactly. GST is per-item (not flat). Farmer due is trigger-recalculated. Don't duplicate calculation logic.
9
Check edge cases. Cancellation: same-day + unpaid only. Stock: never goes negative. Walk-in: full payment required. Credit limit: warning, not block.
10
Test the implementation. Run npm test (Vitest unit tests) and npm run test:e2e (Playwright). Test at both mobile and desktop viewports.
11
Update documentation when behavior changes. Keep docs pages in public/documents/ current.

Never Do

Hard rules. No exceptions.

Architecture Reference

Directory Structure

src/
├── admin/          # Admin portal (separate layout, own routes)
├── components/
│   ├── layout/     # AppLayout, Sidebar, BottomNav, PageShell
│   ├── ui/         # 23 shared UI components
│   └── auth/       # ProtectedRoute, FeatureGate, PlanGate
├── features/       # Feature modules (one directory per domain)
│   └── [feature]/
│       ├── pages/      # Route-level components (React.lazy loaded)
│       ├── components/ # Feature-specific UI
│       ├── hooks/      # Feature-specific React hooks
│       ├── services/   # Supabase queries and RPC calls
│       └── utils/      # PDF generators, formatters, helpers
├── hooks/          # Shared hooks (useAuth, useBranch, etc.)
├── lib/            # Shared utilities (supabase, telemetry, PDF, WhatsApp)
├── stores/         # Zustand stores (auth, cart, subscription, branch, staff)
└── types/          # TypeScript type definitions

Key Files

FileLinesPurpose
ProductSelector.tsx~1519Product catalog + cart for billing. The most complex UI component. Handles search, categories, FIFO lot display, farmer-specific pricing.
InventoryDetailPage.tsx~1444Stock detail view with individual lots, movement history, rate adjustments, and expiry tracking.
NewBillPage.tsx~800Bill creation wizard. Orchestrates mobile 3-step and desktop 2-step flows.
useCheckout.ts~300Bill save logic. Builds the RPC payload, handles offline queuing, manages optimistic updates.
billPdfGenerator.ts~200PDF generation using html2canvas + jsPDF. Renders bill HTML to canvas, converts to PDF.
whatsAppService.ts~150Phone number normalization, wa.me URL generation, API message sending via edge function.
whatsAppMessages.ts~30010 WhatsApp message templates (bill, payment, reminder, statement, etc.).
telemetry.ts~80PostHog analytics + Sentry error tracking initialization and configuration.
queryClient.ts~50React Query configuration: staleTime, gcTime, offline persistence with IndexedDB.
supabase.ts~30Supabase client initialization with the publishable anon key.

Critical Data Flow

Bill Creation Flow

User selects products → useCheckout builds payload → supabase.rpc('create_bill_v2', payload) → RPC atomically: validates stock, consumes FIFO lots, creates bill + items, allocates payment, updates farmer.total_due via trigger, logs transaction event → React Query cache invalidated → PDF generated client-side → optional WhatsApp notification.

Offline Sync Flow

Bill created offline with client_ref UUID → stored in IndexedDB via React Query persistence → on reconnect, create_bill_v2 called with same client_ref → RPC checks for existing bill with that client_ref → returns existing if found (idempotent), creates new if not.