Skip to content

Cycle Plan: 2026-02-16 — Production Hardening

A) Current Findings & Risks

  • Admin Auth: Currently relies on X-Admin-Key header. This is a "bootstrap" mechanism and isn't linked to Supabase User identities.
  • Database Security: RLS is planned but not implemented. All tables are currently accessible if RLS isn't explicitly enabled and configured.
  • Ingestion Pipeline: /upload-curriculum is a standalone "manual" upload. It doesn't link to the references discovered by scrapers.
  • Multilingual RAG: Reranker has basic support, but the initial vector search recall for Arabic questions against French curriculum needs verification/tuning.

B) Proposed Changes (Phased)

Phase 1: Identity-Based Authorization & RLS

  • Goal: Shift from "Secret Key" to "JWT Role" for admin actions.
  • Action: Update auth.py to include a RequireAdmin dependency.
  • Action: Apply RLS Phase 1 to profiles, wallet, wallet_ledger, and usage_logs.

Phase 2: Reference-Driven Ingestion

  • Goal: Move from manual file uploads to "Ingest by Reference".
  • Action: Add POST /vector-embedding endpoint that accepts a reference_id.
  • Action: This endpoint will fetch the PDF from the reference URL, process it, and update the references status in the DB.

Phase 3: Multilingual Retrieval Hardening

  • Goal: Ensure Arabic questions find French content.
  • Action: Refine reranker.py prompt to explicitly handle cross-lingual relevance.
  • Action: Update /chat to include a user_id in the LangGraph state for better usage logging.

C) File-by-File Change List

File Path Change Description
app/core/auth.py Add get_current_admin dependency using JWT role check.
app/api/routers/scraping.py Replace verify_admin (key-based) with get_current_admin (role-based).
app/api/routers/upload.py Replace verify_admin with get_current_admin. Add /vector-embedding logic.
app/services/supabase_references.py Add get_reference_by_id and update_reference_status helpers.
db/migrations/20260216000006_rls_phase_1.sql New migration for RLS policies.
db/bootstrap.sql Append new migrations to remain the source of truth.
docs/10_current_state/api_inventory.md Update with new /vector-embedding endpoint.

D) DB Migration List

  1. 20260216000006_rls_phase_1.sql:
  2. Enable RLS on profiles, wallet, wallet_ledger, usage_logs.
  3. Add SELECT policies for owners.
  4. Restrict all write access to service_role.

E) External Actions Checklist

See docs/20_runbooks/external_actions_checklist.md for detailed SQL and environment steps.

F) Test Plan

  1. Auth Test: Call /scraping/sources with no auth (Success).
  2. Admin Test: Call /scraping/koutoubi/sync with Student JWT (Expect 403).
  3. Admin Test: Call /scraping/koutoubi/sync with Admin JWT (Expect 200).
  4. Ingestion Test: Call /vector-embedding with a valid reference_id. Verify Pinecone namespace is populated.
  5. RLS Test: Use a Student Supabase Key to try and read another user's wallet record (Should return empty/fail).

G) Rollback Strategy

  • DB: Run DROP POLICY ... or revert to previous migration state.
  • Code: Git revert to HEAD^.
  • Infra: Re-enable ADMIN_API_KEY requirement if JWT auth fails in production.