Modèle de données

PostgreSQL 17 + Prisma — entités principales groupées par module, conventions de schéma, migration depuis MongoDB.

Stack et accès

La plateforme utilise PostgreSQL 17 comme base de données relationnelle. L'accès se fait exclusivement via Prisma (version 6) en tant qu'ORM. Le schéma source est app/mypromo/prisma/schema.prisma.

Les migrations sont gérées par Prisma Migrate :

pnpm -C app/mypromo run db:migrate          # migration dev (crée un fichier de migration)
pnpm -C app/mypromo run db:migrate:deploy   # migration de déploiement (CI/prod)
pnpm -C app/mypromo run db:generate         # génération du client Prisma
pnpm -C app/mypromo run db:studio           # interface visuelle Prisma Studio

Contexte historique

Le schéma conserve des @@map vers les noms des anciennes collections issues de la migration depuis MongoDB. Les noms de tables PostgreSQL correspondent donc aux noms de collections d'origine (user, session, campaigns, stores, etc.) pour assurer la continuité du code applicatif. MongoDB n'est plus utilisé — PostgreSQL est la seule base de données de production.

Conventions du schéma

  • Clé primaire : String @id @default(cuid()). Les ObjectId MongoDB ont été abandonnés.
  • Énumérations : modélisées en String ; la validation se fait au niveau application/Zod pour limiter la friction avec Better Auth et le code typé en unions de chaînes.
  • Value-objects 1-1 : aplatis en colonnes préfixées (ex. legalAddressStreet, georefNormCity).
  • Tableaux de sous-documents : convertis en tables enfant avec clé étrangère.
  • Champs réellement schemaless : typés Json.
  • Références inter-entités : colonnes String (clé métier ou cuid) + index, sans contrainte FK base de données (préserve l'accès par id du code existant).

Module auth — Authentification et organisations

Better Auth (tables de session)

Table (@@map)Modèle PrismaRôle
userUserCompte utilisateur, rôle (admin/distributor/industrial), 2FA, ban
sessionSessionSessions actives, impersonation admin
accountAccountComptes OAuth/credentials liés à un user
verificationVerificationTokens de vérification (magic link, e-mail)
twoFactorTwoFactorSecret TOTP et codes de secours

User porte des champs applicatifs additionnels : role, status, actorType, organizationId, firstName, lastName, phoneNumber, cguVersionAccepted.

Organisations et membres

Table (@@map)Modèle PrismaRôle
organizationsOrganizationOrganisation (distributeur, industriel) avec statut KYB, données légales
organization_membersOrganizationMemberAppartenance d'un user à une organisation, rôle de membre
auth_organization_invitationsOrganizationInvitationInvitations par email, cycle de vie (pending/accepted/expired)
organization_billing_profilesOrganizationBillingProfileDonnées de facturation, signataire, IBAN, conditions de paiement
auth_printer_supplier_profilesPrinterSupplierProfileProfil imprimeur : données légales, contraintes fichiers, invitation

KYB et signatures

Table (@@map)Modèle PrismaRôle
auth_company_verification_cacheAuthCompanyVerificationCacheCache des vérifications Pappers (SIREN), TTL, compteur d'usage
auth_authorized_signatoriesAuthAuthorizedSignatorySignataires autorisés associés à un cache de vérification
auth_signature_requestsAuthSignatureRequestDemandes de signature Yousign (statut, liens, métadonnées)
auth_signature_webhook_eventsAuthSignatureWebhookEventÉvénements webhook Yousign reçus, statut de traitement

Catalogue de marques industrielles

Table (@@map)Modèle PrismaRôle
organization_industrial_catalogsOrganizationIndustrialCatalogCatalogue de marques d'une organisation industrielle
organization_industrial_brandsOrganizationIndustrialBrandMarques déclarées dans le catalogue
organization_industrial_brand_productsOrganizationIndustrialBrandProductProduits associés à une marque

Logs de sécurité

Table (@@map)Modèle PrismaRôle
security_audit_logSecurityAuditLogÉvénements de sécurité (type, acteur, IP, contexte)

Templates de documents

Table (@@map)Modèle PrismaRôle
document_templatesDocumentTemplateTemplates Markdown versionnés (CGU, mandats) avec statut draft/published
document_template_variablesDocumentTemplateVariableVariables déclarées d'un template (nom, type, required)
document_template_audit_logsDocumentTemplateAuditLogHistorique des actions sur les templates

Module catalog — Magasins et espaces publicitaires

Magasins

Table (@@map)Modèle PrismaRôle
storesStoreMagasin (organisation distributeur, SIRET, adresse, géolocalisation, audience)
store_interest_signalsStoreInterestSignalSignaux d'intérêt exprimés par un industriel pour un magasin

Store embarque les données de géoréférencement (latitude, longitude, champs georef*) et d'audience (audienceCustomerFlowPerDay, audienceCatchmentArea).

Espaces publicitaires

Table (@@map)Modèle PrismaRôle
ad_spacesAdSpaceEspace publicitaire (type de support, dimensions, tarif journalier, statut, lien vers le type et la demande d'origine)
ad_space_photosAdSpacePhotoPhotos de l'espace, positionnées
ad_space_availability_windowsAdSpaceAvailabilityWindowFenêtres de disponibilité d'un espace
ad_space_periodic_pricing_rulesAdSpacePeriodicPricingRuleRègles de tarification périodiques (jour de semaine, semaine du mois)
ad_space_event_pricing_rulesAdSpaceEventPricingRuleRègles de tarification événementielles (plage de dates)

Catalogue mobilier promotionnel

Table (@@map)Modèle PrismaRôle
promo_furniture_typesPromoFurnitureTypeType de mobilier (dimensions, surfaces, volumes)
promo_furniture_type_placement_imagesPromoFurnitureTypePlacementImageImages de positionnement associées à un type de mobilier
promo_furniture_type_documentsPromoFurnitureTypeDocumentDocuments techniques d'un type de mobilier
promo_furniture_type_catalog_visualsPromoFurnitureTypeCatalogVisualVisuels catalogue (gabarits) d'un type de mobilier
promo_furniture_type_quadsPromoFurnitureTypeQuadPositionnement d'une zone imprimable sur l'image d'un type (4 points)
promo_furniture_type_rental_pricesPromoFurnitureTypeRentalPriceTarif locatif mensuel borné dans le temps (date-à-date) d'un type de mobilier
promo_furnituresPromoFurnitureInstance physique de mobilier (numéro de série unique, magasin/espace affectés)
furniture_requestsFurnitureRequestDemande de meuble d'un distributeur (magasin, statut pending/approved/rejected, motif)
furniture_request_itemsFurnitureRequestItemLigne d'une demande de meuble (type de mobilier, quantité)
promo_print_filesPromoPrintFileFichier d'impression (code unique, fichier asset, types compatibles)
promo_print_file_compatible_typesPromoPrintFileCompatibleTypeAssociation entre un fichier d'impression et les types de mobilier compatibles
promo_print_jobsPromoPrintJobOrdre d'impression d'un fichier pour un industriel (statut, localisation)

Catalogue enseignes

Table (@@map)Modèle PrismaRôle
catalog_enseignesCatalogEnseigneRéférentiel des enseignes (code, label, logo, ordre de tri)

Module campaigns — Campagnes, réservations, médias

Campagnes

Table (@@map)Modèle PrismaRôle
campaignsCampaignCampagne marketing (organisation industrielle, dates, budget, brief)
campaign_product_snapshotsCampaignProductSnapshotSnapshot des produits au moment de la création de la campagne
campaign_templatesCampaignTemplateModèle réutilisable de campagne
campaign_template_product_snapshotsCampaignTemplateProductSnapshotSnapshot des produits d'un template
campaign_cart_itemsCampaignCartItemÉléments en cours de panier (espace publicitaire + créneau sélectionné)

Shortlists

Table (@@map)Modèle PrismaRôle
industrial_shortlistsIndustrialShortlistListe de magasins favoris d'un industriel (nom, couleur, défaut)
industrial_shortlist_storesIndustrialShortlistStoreEntrée de magasin dans une shortlist

Réservations

Table (@@map)Modèle PrismaRôle
reservationsReservationRéservation d'un espace publicitaire (statut, pricing, contre-proposition, mode de support d'impression)
reservation_print_reused_facesReservationPrintReusedFaceFaces d'impression réutilisées dans une réservation en mode hybride/reuse
reservation_messagesReservationMessageMessages échangés sur une réservation, avec statut de modération
plaque_ordersPlaqueOrderCommande de plaques physiques liée à une réservation (quantité, logistique)

Médias et logs

Table (@@map)Modèle PrismaRôle
media_assetsMediaFichier media uploadé (kind, statut, URL de stockage)
audit_logsAuditLogLog d'audit applicatif général (action, entité, acteur, IP)

Module billing — Facturation

Table (@@map)Modèle PrismaRôle
billing_reservation_financialsBillingReservationFinancialFinancier d'une réservation (montants, commission, dépôt, solde, statut)
billing_payment_ordersBillingPaymentOrderOrdre de paiement (SEPA DD, statut, clé d'idempotence)
billing_invoicesBillingInvoiceFacture émise (numéro unique, montants HT/TVA/TTC, statut)
billing_ledger_entriesBillingLedgerEntryÉcriture de ledger comptable (direction, code compte, montant)
invoicesInvoiceFacture simplifiée (organisation, totaux net/taxe/gross)
billing_sepa_mandatesSepaMandateMandat SEPA (référence, statut, date de signature/révocation)

Module einvoicing — Facturation électronique

Table (@@map)Modèle PrismaRôle
einvoice_transmissionsEinvoiceTransmissionTransmission d'une facture au provider e-invoicing (statut, tentatives, hash)
einvoice_webhook_eventsEinvoiceWebhookEventÉvénements webhook reçus du provider, statut de traitement

Module notifications — E-mails transactionnels

Table (@@map)Modèle PrismaRôle
notification_email_queueEmailQueueItemFile d'e-mails en attente d'envoi (event, contexte, tentatives, verrou)
notification_email_dead_letterEmailDeadLetterE-mails ayant épuisé toutes les tentatives

Impression (print) — Domaine transverse

Table (@@map)Modèle PrismaRôle
print_assetsPrintAssetAsset PDF déduplicé par hash de contenu (organisation industrielle, métadonnées techniques)
print_ordersPrintOrderOrdre d'impression lié à une réservation (statut, imprimeur, livraison)
print_order_linesPrintOrderLineLigne d'un ordre d'impression (zone, qualifiers, asset, BAT)
reservation_print_preflightsReservationPrintPreflightRapport de preflight PDF par zone/qualifier d'une réservation
print_shipment_addressesPrintShipmentAddressAdresses de livraison enregistrées par organisation
printable_zonesPrintableZoneZone imprimable / face (titre, dimensions) avec gabarits téléchargeables — les vrais fichiers d'impression vierges vivent ici, pas sur le type
printable_zone_gabaritsPrintableZoneGabaritGabarit d'une zone imprimable (URL, format, label)
promo_furniture_type_facesPromoFurnitureTypeFaceTable de jointure plusieurs-à-plusieurs entre PrintableZone (face) et PromoFurnitureType : une même face peut être réutilisée sur plusieurs types de meuble

Fichiers — Registre central

Table (@@map)Modèle PrismaRôle
filesFileRegistrySource de vérité des fichiers uploadés (contextId, scopeSegments, MIME, visibilité, soft delete)

FileRegistry est le registre unique des fichiers de la plateforme. Les URLs de fichiers exposées en API pointent vers /api/files/... et sont résolues dynamiquement depuis ce registre. Les entités métier ne stockent que ces URLs — jamais de chemins absolus locaux.


Résolution des conflits SIRET

Table (@@map)Modèle PrismaRôle
siret_claim_conflictsSiretClaimConflictConflits de revendication de SIRET entre organisations, suivi de résolution