# Siya9a Maroc — App Knowledge Base > AI agents: read this file before working on anything related to Siya9a. ## Overview **Siya9a Maroc** is the #1 Moroccan driving licence (permis de conduire) preparation app. It ships as: - A **Flutter Android app** on Google Play - A **Flutter Web app** hosted on Vercel (student exam portal) - A **Nuxt 4 Console** (school admin dashboard) on the VPS --- ## Domains | URL | Purpose | Hosting | |-----|---------|---------| | `https://siya9a.devit.ma/` | Student web exam portal | Vercel (CNAME) | | `https://ecole-siya9a.devit.ma/` | School admin console | VPS `145.223.96.119` | | `https://siya9a.devit.ma/api/` | REST API | VPS (via Nginx proxy) | --- ## Repository ``` d:\code\devit\siya9a\ ├── lib\ ← Flutter app (Dart) │ ├── pages\ │ ├── providers\ ← Riverpod providers (telemetry_provider.dart) │ └── services\ ← school_api.dart (schoolApiBaseUrl) ├── test\ │ ├── home_layout_test.dart │ └── text_scale_test.dart ├── server\ │ ├── api\ ← Elysia/Bun REST API │ │ ├── src\ │ │ │ ├── db\ ← Drizzle ORM (PostgreSQL) │ │ │ └── routes\ │ │ └── Dockerfile │ ├── console\ ← Nuxt 4 school admin console │ │ ├── app\pages\ │ │ └── Dockerfile │ ├── db\ │ │ ├── migrations\ ← SQL migrations (0000–0011+) │ │ └── seed.ts │ └── deploy\ │ ├── deploy.ps1 ← Windows deploy script (run from this machine) │ ├── remote.sh ← Bash script executed on the VPS │ ├── docker-compose.prod.yml │ └── nginx\ │ └── siya9a.conf ← Nginx template (__DOMAIN__ placeholder) ``` --- ## Tech Stack | Layer | Technology | |-------|-----------| | Mobile app | Flutter / Dart | | Web app | Flutter Web (compiled, hosted on Vercel) | | Admin console | Nuxt 4 (SSR, Node/Bun) | | API | Elysia on Bun 1.4 | | Database | PostgreSQL 18 (Docker, `siya9a_db_data` volume) | | ORM | Drizzle ORM | | Containerisation | Docker Compose (`docker-compose.prod.yml`) | | Reverse proxy | Nginx (on VPS host, not inside Docker) | | SSL | Let's Encrypt / Certbot (auto-renew) | | CDN | Cloudflare (devit.ma zone) | --- ## Key Configuration ### Flutter app - **`lib/services/school_api.dart`** — `schoolApiBaseUrl` → `https://ecole-siya9a.devit.ma/api` - **`lib/providers/telemetry_provider.dart`** — `baseUrl` → `https://siya9a.devit.ma` ### API `.env` (on VPS at `/root/code/apps/siya9a/.env`) ```env POSTGRES_PASSWORD= ADMIN_EMAIL=admin@ecole-siya9a.devit.ma ADMIN_PASSWORD= CONSOLE_ORIGIN=https://siya9a.devit.ma,https://siya9a.vercel.app DOMAIN=ecole-siya9a.devit.ma ``` > ⚠️ **Never edit `.env` directly on VPS.** Update `server/deploy/remote.sh` instead. ### Google Cloud OAuth (project `siya9a-509223`) - Client: `Siya9a Web Console` - Authorized JS origins: `https://ecole-siya9a.devit.ma`, `https://siya9a.devit.ma` - Authorized redirect URIs: `https://ecole-siya9a.devit.ma/auth/callback`, etc. --- ## Deployment ### Deploy the full stack (API + Console) to VPS ```powershell # From d:\code\devit\siya9a\server\deploy\ .\deploy.ps1 # or explicitly: .\deploy.ps1 -Domain ecole-siya9a.devit.ma -SshHost badil ``` ### Deploy only the Flutter web app Push to `main` → Vercel auto-deploys to `siya9a.vercel.app` + `siya9a.devit.ma`. ### Run migrations manually ```bash ssh badil "cd /root/code/apps/siya9a && \ docker compose -f deploy/docker-compose.prod.yml --env-file .env \ exec -T api bun api/src/db/migrate.ts" ``` --- ## Database - **Engine:** PostgreSQL 18 (Alpine) - **Size:** ~66 MB (as of 2026-09-21) - **Tables (27):** learners, schools, rooms, memberships, plans, exam_runs, progress_events, learner_stats, learner_fees, learner_payments, learner_profiles, learner_reports, memberships, blacklist, bank_reviews, bank_submissions, audit_log, feedback, practical_evaluations, school_announcements, school_assignments, school_lessons, school_vehicles, room_answers, room_participants, public_room_answers, public_room_guests - **Backups:** Auto-dumped with `pg_dump` before every deploy. Stored in `/root/code/apps/siya9a/backups/`. Last 10 retained. --- ## Ports (on VPS, loopback only) | Port | Service | |------|---------| | `4240` | Elysia API | | `4242` | Nuxt console (mapped from container's `3000`) | --- ## Monitoring Health check: `GET https://ecole-siya9a.devit.ma/api/ready` Expected response: `{"ok":true,"db":true}`