Pant0x's picture
Deploy Ain El Aql Backend to HF Spaces (no secrets)
f315c76
|
Raw
History Blame Contribute Delete
11.8 kB

Ain El Aql Backend - Comprehensive Technical Documentation

1) Purpose and Scope

This document is the single-source technical overview for the Ain El Aql backend.

It covers:

  1. System architecture
  2. Authentication and authorization
  3. Role model and access scope
  4. Endpoint catalog and contracts
  5. End-to-end data flow
  6. Database model and relationships
  7. Validation, errors, and operational behavior
  8. Production readiness guidance

Primary implementation file:

  • API.py

Supporting documentation:

  • docs/API_REFERENCE.md
  • docs/BACKEND_ARCHITECTURE.md
  • docs/ENVIRONMENT_VARIABLES.md

2) System Architecture

The backend is a FastAPI monolith that combines:

  1. AI inference orchestration (local YOLO or remote model service)
  2. Supabase-backed auth, profile, data persistence, and storage
  3. Parking/session lifecycle and event feeds
  4. Pricing and occupancy engines
  5. Gate/payment decision logic

Runtime Components

  1. API framework: FastAPI
  2. CV/ML runtime: OpenCV, NumPy, Ultralytics YOLO
  3. Data/auth/storage backend: Supabase (Auth + PostgREST + Storage)
  4. Payment provider: Paymob (optional)

Inference Modes

  1. MODEL_INFERENCE_PROVIDER=local
    • Inference executed in this service.
  2. MODEL_INFERENCE_PROVIDER=remote
    • Backend calls external model runtime using MODEL_SERVICE_URL.

3) Authentication and Authorization

The backend supports two authentication paths:

  1. Supabase JWT bearer token
  2. Barrier/device static token

3.1 Supabase Token Auth

  • Header: Authorization: Bearer <supabase_access_token>
  • Validation endpoint: Supabase GET /auth/v1/user
  • On successful verification:
    • backend derives user id/email
    • backend auto-creates a minimal profiles row when missing (best effort)

Why auto-provision profile rows:

  • Prevent FK failures on writes referencing profiles.id.
  • Reduce silent persistence failures when auth users exist but profile rows do not.

3.2 Barrier/Device Token Auth

  • Header: Authorization: Bearer <barrier_token>
  • Token sources:
    • BARRIER_API_TOKEN (single token)
    • BARRIER_API_TOKENS (comma-separated tokens)
  • Comparison uses constant-time matching (hmac.compare_digest).
  • Returns synthetic auth context:
    • id = BARRIER_SYNTHETIC_USER_ID (default barrier-device)
    • role = barrier
    • auth_type = barrier_token

Important:

  • Barrier auth is intended for machine integrations (camera/barrier clients).
  • Barrier auth is not a substitute for end-user mobile/web sessions.

4) Role Model and Access Scope

Roles in runtime behavior:

  1. user
  2. admin
  3. security
  4. developer
  5. barrier (synthetic API role)

4.1 Scope Rules

  1. User scope:
    • Own records only
  2. Staff scope (admin, security):
    • Global records
    • optional for_user_id filtering on feed/history endpoints
  3. Barrier scope (barrier):
    • Global read scope for operational feeds/history and gate decision checks
    • Not treated as staff for privileged maintenance/payment confirmations
  4. Developer scope (developer):
    • Access to developer endpoints (/developer/*)

5) Endpoint Catalog

5.1 Public/Utility

  1. GET /
  2. GET /health
  3. GET /supabase/health
  4. GET /models

5.2 Developer

  1. GET /developer/models
  2. POST /developer/predict

5.3 Authentication

  1. POST /auth/register
  2. POST /auth/login
  3. POST /auth/otp/request
  4. POST /auth/otp/verify
  5. POST /auth/forgot-password
  6. POST /auth/reset-password/resolve-token
  7. POST /auth/reset-password
  8. GET /auth/reset-password-page
  9. GET /auth/reset-password-bridge

5.4 Profile and Vehicles

  1. PUT /profile/update
  2. POST /vehicles/add
  3. GET /vehicles/my
  4. PUT /vehicles/{vehicle_id}
  5. DELETE /vehicles/{vehicle_id}
  6. POST /vehicles/verify

5.5 Notifications

  1. POST /notifications/fcm-token
  2. GET /notifications/my

5.6 Inference and Model Runtime

  1. POST /predict
  2. POST /model/infer

5.7 Parking/Events/History

  1. GET /parking/locations
  2. GET /parking/occupancy
  3. GET /events/entered-cars
  4. GET /events/leaving-cars-within-5-minutes
  5. GET /events/new-cars
  6. GET /events/left-cars
  7. GET /events/inside-cars
  8. GET /parking/history

5.8 Payments and Gate

  1. POST /payments/paymob/create
  2. POST /payments/paymob/webhook
  3. POST /payments/manual/cash-confirm
  4. POST /gate/decision

5.9 Maintenance

  1. POST /admin/maintenance/weekly-refresh

6) End-to-End Data Flow

6.1 Predict Request Flow (POST /predict)

  1. Authenticate request (Supabase token or barrier token).
  2. Validate optional inputs:
    • event_type in {entry, exit, ocr_scan}
    • parking_location pattern
    • camera_source pattern
  3. Run inference pipeline (local or remote).
  4. Build normalized plate payload.
  5. Persist output to Supabase:
    • upload raw and processed images to storage buckets
    • resolve vehicle from OCR plate
    • resolve/create session depending on event type
    • create car_events row
    • optionally emit notification events
  6. Compute and return:
    • payment_status
    • pricing
    • gate_decision
    • persistence metadata

6.2 Vehicle Resolution Logic

The backend now matches OCR plates using both formats:

  1. Arabic plate fields: plate_letters_ar + plate_numbers_ar
  2. English plate fields: plate_letters_en + plate_numbers_en

Matching order:

  1. Owner-scoped lookup (when authenticated Supabase user id is available)
  2. Global lookup fallback

Effect:

  • Reduces false negatives where OCR returns one language format but not the other.

6.3 Session Lifecycle

  1. entry
    • create or reuse open session
  2. exit
    • use open session
    • if paid and within 5 minutes: close session (status=exited)
    • if paid but grace expired: keep open with status=overstayed
    • if unpaid: keep open (gate deny path)
  3. ocr_scan
    • read context only, no session state transition

6.4 Unmatched Fallback Flow

When a plate is detected but not linked to a registered vehicle/session:

  1. Event is still stored in car_events (with nullable vehicle_id/session_id).
  2. Backend builds inferred unmatched rows from entry/exit event streams by plate key.
  3. Inferred rows are merged into:
    • GET /parking/locations
    • GET /parking/occupancy
    • GET /events/inside-cars
    • GET /parking/history

Response markers for inferred rows:

  1. inferred_unmatched=true
  2. plate object (key/arabic/english)
  3. event_count

Occupancy responses also include source breakdown:

  1. inside_from_registered_sessions
  2. inside_from_inferred_unmatched

7) Database Model (Supabase)

Core relational tables:

  1. profiles
    • user identity/profile metadata
    • role and staff metadata
  2. vehicles
    • vehicle registration and ownership
  3. parking_sessions
    • parking lifecycle state
  4. car_events
    • entry/exit/scan event stream
  5. payment_transactions
    • payment ledger for paymob/manual cash

Notifications and app links:

  1. notification_device_tokens
  2. notification_events
  3. app_links

Key Relationships

  1. profiles.id -> auth.users.id
  2. vehicles.owner_id -> profiles.id
  3. parking_sessions.vehicle_id -> vehicles.id
  4. car_events.session_id -> parking_sessions.id (nullable)
  5. car_events.vehicle_id -> vehicles.id (nullable)

Storage Buckets

  1. SUPABASE_RAW_BUCKET (raw uploads)
  2. SUPABASE_PROCESSED_BUCKET (split/admin images)

8) Security and Data Integrity

8.1 RLS and Role Design

  • Supabase RLS is enabled for core business tables.
  • Backend writes are performed via service role credentials.
  • Client-facing authorization is enforced in API layer by user role/scope.

8.2 Notification Event Hardening

Current model:

  1. Notification content is server-owned.
  2. Authenticated users can read own notifications.
  3. Authenticated users can only mark own notifications as read.
  4. Client-side insert/delete/content edits are blocked.

8.3 Created-By FK Protection

For persistence writes:

  • created_by is now populated only for Supabase-authenticated users.
  • Barrier-auth requests do not inject synthetic ids into FK-backed columns.

This prevents FK violations and silent persistence drop scenarios.


9) Validation and Error Contract

Common input validations:

  1. Auth header format (Bearer ...)
  2. event_type allowed values
  3. parking location format
  4. camera source format
  5. file type and non-empty uploads
  6. payment amount positive integer rules

Common error statuses:

  1. 400 invalid input
  2. 401 auth missing/invalid/expired
  3. 403 role or scope violation
  4. 404 missing session/resource
  5. 502 upstream integration failure
  6. 503 missing critical configuration

10) Production Readiness Checklist

10.1 Required Environment

  1. SUPABASE_URL
  2. SUPABASE_ANON_KEY
  3. SUPABASE_SERVICE_ROLE_KEY
  4. SUPABASE_ENFORCE_AUTH=true (recommended)
  5. model runtime config (MODEL_INFERENCE_PROVIDER + remote/local settings)

Optional but recommended:

  1. PASSWORD_RESET_REDIRECT_URL
  2. BARRIER_API_TOKEN or BARRIER_API_TOKENS (if device auth is needed)
  3. pricing/capacity config
  4. paymob config if card payments enabled

10.2 Database Migration Baseline

Ensure latest SQL is applied, including:

  1. supabase/04_auth_profile_vehicle_upgrade.sql
  2. supabase/05_multi_vehicle_auth_notifications.sql
  3. supabase/06_profile_name_parts_upgrade.sql

10.3 Smoke Tests

  1. GET /health
  2. GET /supabase/health
  3. Auth login/register flow
  4. POST /predict (entry + exit)
  5. GET /parking/locations
  6. GET /events/inside-cars
  7. GET /parking/history
  8. Gate decision endpoint
  9. Password reset flow (bridge + page + resolver)

10.4 Operational Guardrails

  1. Rotate service secrets and barrier tokens regularly.
  2. Keep SUPABASE_SERVICE_ROLE_KEY backend-only.
  3. Monitor response.supabase.saved from /predict integrations.
  4. Alert on repeated saved=false responses and 5xx spikes.

11) Troubleshooting Guide

Symptom: feeds/history are empty

Checks:

  1. Confirm requests are authenticated and role scope is correct.
  2. Verify /predict responses include supabase.saved=true.
  3. Verify vehicle resolution fields (Arabic/English plate matching).
  4. Confirm sessions are being created (parking_sessions) and linked to events.
  5. If traffic is mostly unregistered, verify inferred rows are visible (inferred_unmatched=true).

Symptom: barrier token rejected

Checks:

  1. Token present as Bearer token
  2. BARRIER_API_TOKEN or BARRIER_API_TOKENS set in deployment env
  3. No hidden whitespace in configured token

Symptom: auth user exists but no data persists

Checks:

  1. Confirm profiles row exists for that auth user id.
  2. Confirm Supabase service role key is valid and backend can write tables.
  3. Inspect backend logs for persistence exceptions.

12) Notes on Backward Compatibility

  1. Existing Supabase auth clients continue to work unchanged.
  2. Barrier token support is additive.
  3. Feed/history response shape is preserved.
    • Added optional inferred markers and source-breakdown fields.
  4. Role checks remain strict for maintenance and payment confirmation endpoints.

13) Recommended Next Improvements

  1. Add structured audit logs for auth path used (supabase vs barrier).
  2. Add metrics counters for vehicle-match source (arabic, english, fallback).
  3. Add integration tests for:
    • missing-profile auto-provision
    • barrier gate decision authorization
    • plate matching variants (Arabic-only, English-only, mixed)
  4. Add a migration to introduce an explicit persistent barrier app role if database-level modeling is desired.