Spécifications de l'architecture
Spécifications techniques & Blueprints SaaS
Structure multi-tenant, schéma relationnel et stratégie d'évolution.
💡
Architecture multi-tenant partitionnée : chaque boutique possède un
tenant_id. Les requêtes filtrent impérativement par cette clé pour isoler inventaire, paiements et facturation de chaque marchand.📋 tenantsPostgreSQL
Contient les informations et la configuration des sous-boutiques (Multi-tenant).
| Colonne | Type | Description |
|---|---|---|
| id | uuid | Identifiant unique de la boutiquePRIMARY KEY DEFAULT gen_random_uuid() |
| slug | varchar(50) | Identifiant d'URL sous-domaine (ex: 'djelika-couture')UNIQUE NOT NULL |
| name | varchar(100) | Nom commercial de la boutiqueNOT NULL |
| logo_url | text | Lien vers l'image du logoNULL |
| banner_url | text | Lien vers l'image d'en-tête de la boutiqueNULL |
| description | text | Description textuelleNULL |
| owner_name | varchar(100) | Nom du gérantNOT NULL |
| owner_email | varchar(100) | Email de contact propriétaireNOT NULL |
| phone | varchar(30) | Numéro de téléphone WhatsApp professionnelNOT NULL |
| country | varchar(50) | Pays d'exploitation (Mali)NOT NULL |
| city | varchar(50) | Ville de domiciliation (Bamako, Sikasso, Ségou…)NOT NULL |
| address | text | Adresse physique exacteNOT NULL |
| primary_color | varchar(7) | Couleur primaire de l'interface en hexaDEFAULT '#223f6d' |
| secondary_color | varchar(7) | Couleur secondaire de l'interfaceDEFAULT '#b07c4f' |
| theme_font | varchar(50) | Police d'écriture styliséeDEFAULT 'Inter' |
| plan | varchar(15) | Type d'abonnement ('free', 'standard', 'premium')DEFAULT 'free' |
| commission_rate | numeric(5,2) | % prélevé sur les ventes directesDEFAULT 3.0 |
| currency | varchar(3) | Devise par défaut (FCFA / XOF au Mali)NOT NULL DEFAULT 'XOF' |
| created_at | timestamp | Date de création sur la plateformeDEFAULT timezone('utc'::text, now()) |
📋 productsPostgreSQL
Catalogue produits propre à chaque boutique (cloisonnement tenant_id).
| Colonne | Type | Description |
|---|---|---|
| id | uuid | Identifiant du produitPRIMARY KEY DEFAULT gen_random_uuid() |
| tenant_id | uuid | Association au tenant propriétaireREFERENCES tenants(id) ON DELETE CASCADE |
| name | varchar(150) | Nom de l'articleNOT NULL |
| description | text | Description marketingNULL |
| category | varchar(100) | Catégorie de premier niveauNOT NULL |
| subcategory | varchar(100) | Sous-catégorie optionnelleNULL |
| price | integer | Prix standard (FCFA)NOT NULL |
| promo_price | integer | Prix de réductionNULL |
| stock | integer | Quantité en inventaire physiqueNOT NULL DEFAULT 0 |
| image_url | text | Lien de la photo de gardeNOT NULL |
| gallery | jsonb | Liste d'images annexes en tableau JSONNULL |
| variants | jsonb | Caractéristiques configurables (tailles, couleurs, motifs)DEFAULT '[]' |
| is_featured | boolean | Afficher en vedette sur la page de gardeDEFAULT false |
| is_promo | boolean | Indicateur de réduction activeDEFAULT false |
| created_at | timestamp | Date d'enregistrementDEFAULT now() |
📋 ordersPostgreSQL
Commandes de clients enregistrées dans les boutiques.
| Colonne | Type | Description |
|---|---|---|
| id | uuid | Identifiant de la commandePRIMARY KEY |
| tenant_id | uuid | Tenant concerné par la venteREFERENCES tenants(id) |
| order_number | varchar(30) | Numéro de facture unique (ex: FAC-DJK-1002)UNIQUE NOT NULL |
| customer_name | varchar(150) | Nom complet du clientNOT NULL |
| customer_email | varchar(150) | Mail de contactNULL |
| customer_phone | varchar(30) | Téléphone WhatsApp pour la messagerieNOT NULL |
| address | text | Description physique de livraison (ex: Rue 224, Badalabougou)NOT NULL |
| delivery_zone_id | varchar(50) | Zone de livraison sélectionnéeNOT NULL |
| delivery_fee | integer | Frais calculés automatiquementNOT NULL |
| total_amount | integer | Total TTC encaisséNOT NULL |
| payment_method | varchar(20) | Mécanique: 'cod' (Livraison), 'mobile_money', 'bank_transfer'NOT NULL |
| payment_provider | varchar(30) | Opérateur Mobile Money: 'orange_money', 'moov_money', 'wave'NULL |
| payment_status | varchar(15) | Statut financier: 'pending', 'paid', 'failed'DEFAULT 'pending' |
| shipping_status | varchar(15) | Statut logistique: 'pending', 'validated', 'in_transit', 'delivered'DEFAULT 'pending' |
| created_at | timestamp | Date d'achatDEFAULT now() |
📋 order_itemsPostgreSQL
Lignes de détails au sein d'une commande (relation un-à-plusieurs).
| Colonne | Type | Description |
|---|---|---|
| id | uuid | Identifiant de lignePRIMARY KEY |
| order_id | uuid | Liaison vers la table parentREFERENCES orders(id) ON DELETE CASCADE |
| product_id | uuid | L'article achetéNOT NULL |
| product_name | varchar(200) | Nom du produit figé au jour de la venteNOT NULL |
| price | integer | Tarif unitaire d'achat ou promotionNOT NULL |
| quantity | integer | Quantité commandéeNOT NULL DEFAULT 1 |
| selected_variants | varchar(255) | Spécificités sélectionnées par l'acheteurNULL |
📋 shipping_zonesPostgreSQL
Grille de zonage tarifaire propre à chaque boutique locale.
| Colonne | Type | Description |
|---|---|---|
| id | uuid | Id de zonePRIMARY KEY |
| tenant_id | uuid | S'applique à la boutiqueREFERENCES tenants(id) ON DELETE CASCADE |
| name | varchar(100) | Ex: 'Bamako Rive Gauche', 'Sikasso ville'NOT NULL |
| fee | integer | Montant appliqué aux livraisonsNOT NULL DEFAULT 0 |
| estimated_time | varchar(50) | Délai (ex: '24h', 'Dans la journée')NULL |
📋 saas_subscriptionsPostgreSQL
Archives comptables SaaS, suivi de la facturation des boutiques (Orange Money / Wave / carte).
| Colonne | Type | Description |
|---|---|---|
| id | uuid | Id d'abonnementPRIMARY KEY |
| tenant_id | uuid | Boutique abonnéeREFERENCES tenants(id) |
| plan_type | varchar(15) | 'free', 'standard', 'premium'NOT NULL |
| billing_cycle | varchar(15) | 'monthly', 'yearly'NOT NULL |
| amount_paid | integer | Montant acquittéNOT NULL |
| status | varchar(15) | Statut d'abonnement ('active', 'past_due', 'cancelled')DEFAULT 'active' |
| expires_at | timestamp | Date anniversaire de paiementNOT NULL |