- Server checks PIN against env (super admin) + NocoDB Users table
- Session stores name + role (admin/viewer)
- Admin: sees Settings page (seasons + users management)
- Viewer: sees Dashboard + Comparison only, no Settings
- Users CRUD on Settings page: add name + PIN + role, delete
- Settings link + nav hidden for non-admin users
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Server: POST /auth/login (verify PIN, set httpOnly cookie)
- Server: GET /auth/check, POST /auth/logout
- Client: Login page shown when not authenticated
- Session persists 7 days via httpOnly cookie
- PIN stored server-side only (ADMIN_PIN env var)
- Dashboard loads data only after successful auth
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Server: seasons CRUD routes + generic NocoDB helpers
- Client: Settings page at /settings with inline add/edit/delete
- Seasons stored in NocoDB Seasons table
- Vite proxy: /api/seasons routed to Express server
- Nav links added (desktop + mobile)
- Locale keys for EN + AR
- Seasons loaded non-blocking on app mount
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ETL writes District column to NocoDB DailySales
- Museums mapped: Hiraa (Revelation, Holy Quraan, Trail, Makkah, VIP)
AsSaffiyah (Creation Story, Best of Creation)
- District filter added to Dashboard and Comparison (cascades to museum)
- District Performance chart added (desktop + mobile)
- Locale keys added for both EN and AR
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace NocoDB museum data (Districts/Museums/DailyStats) with ERP API
- Client fetches via server proxy (/api/erp/sales) — no credentials in browser
- Aggregate transaction-level ERP data into daily/museum/channel records
- Replace "district" dimension with "channel" (B2C/HiHala, POS, B2B, etc.)
- Add product-to-museum mapping (46 products → 6 museums)
- NocoDB retained only for PilgrimStats
- Remove old server/index.js (replaced by modular TS in server/src/)
- Update all components, types, and locale files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Default to light theme instead of system preference, and update
dashboard subtitle to reflect VivaTicket as the data source.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename Revenue to GrossRevenue, add NetRevenue (excl. VAT)
- Add VAT toggle (Incl/Excl) on Dashboard and Comparison pages
- Add offline mode with localStorage caching (24h validity)
- Add refresh button and offline indicator in nav
- Remove Google Sheets fallback (archived to dataService.legacy.js)
- Add AR/EN translations for new UI elements