Aller au contenu principal

Modèle de données

Postgres 16 + pgvector (embeddings 1024-d) + PostGIS (geography(Point, 4326)), via Drizzle ORM. Le schéma fait foi : apps/api/src/db/schema.ts. Les migrations vivent dans apps/api/drizzle/ (la migration initiale installe l'extension vector).

Il n'y a pas de table users — l'identité vit dans Auth0. Les FK logiques vers les utilisateurs sont des user_id = sub Auth0 (texte), non contraints.

Enums Postgres

EnumValeurs
tracking_statuscontacted, doing, done, refused
notification_statusqueued, sent, no_contact, failed
service_sourceuser, google_scrape
import_statuspending, running, done, failed
tracking_status ≠ statut dashboard

L'enum bas niveau tracking_status (contacted/doing/done/refused) est l'état backend. Côté dashboard web, les pills de demandes (a-valider/en-cours/terminee) sont une projection UI ; ne pas confondre les deux. Voir apps/web.

Invariants notables

  • Slugs immuables : services.slug et user_profiles.slug sont écrits une fois et jamais régénérés (stabilité des URLs = invariant SEO). Cf. apps/api/src/lib/slug.ts.
  • Images ≤ 3 : check cardinality(images_url) <= 3 sur tasks et services.
  • Une review par (task, author) : index unique reviews_task_author_uidx ; rating contraint entre 1 et 5.
  • Un tracking par (task, service) : index unique trackings_task_service_uidx.
  • Snapshots de review : author_name / author_picture sont figés à la création (pas de relookup Auth0 par ligne).