Files
PleinR/drizzle/meta/0000_snapshot.json
Claude 7e22ec50d4 Implémente le site Plein R (Accueil + Backend) sur Next.js + Postgres + Docker
Application unique Next.js (App Router, TypeScript) servant :
- Accueil public : héro, recherche, métiers, promotions, mises à l'honneur
  (données issues de Postgres)
- Backend authentifié avec RBAC : tableau de bord, adhérents (CRUD), modération
  des promotions, administrateurs, espace adhérent (publication avec aperçu)

Technique :
- Drizzle ORM + drizzle-kit (migrations versionnées) sur driver pg
- Auth.js v5 (credentials, sessions JWT), rôles admin/moderator/editor/member
- Middleware de protection de /backend + gardes par rôle dans chaque vue
- Server actions pour toutes les mutations (vérif auth + capacité + revalidate)
- Design fidèle aux maquettes (design-system CSS, animations, responsive)

Conteneurisation :
- 1 conteneur applicatif (sortie standalone) + 1 conteneur Postgres externe
- docker-compose avec healthcheck ; migrations + seed au démarrage
- scripts migrate/seed bundlés (esbuild) pour un runtime sans devDeps

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
2026-06-26 12:06:21 +00:00

483 lines
11 KiB
JSON

{
"id": "bf4dd99e-65a5-4e31-9d25-5fce8e585460",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.activity_log": {
"name": "activity_log",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"dot": {
"name": "dot",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'#2C6FB3'"
},
"message": {
"name": "message",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.categories": {
"name": "categories",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"slug": {
"name": "slug",
"type": "varchar(80)",
"primaryKey": false,
"notNull": true
},
"label": {
"name": "label",
"type": "varchar(120)",
"primaryKey": false,
"notNull": true
},
"accent": {
"name": "accent",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'#E0A63C'"
},
"tint": {
"name": "tint",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'#f6efdc'"
},
"sort": {
"name": "sort",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"categories_slug_unique": {
"name": "categories_slug_unique",
"nullsNotDistinct": false,
"columns": [
"slug"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.members": {
"name": "members",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"category_id": {
"name": "category_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"city": {
"name": "city",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"address": {
"name": "address",
"type": "varchar(240)",
"primaryKey": false,
"notNull": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "member_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"highlighted": {
"name": "highlighted",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"logo_url": {
"name": "logo_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"members_category_id_categories_id_fk": {
"name": "members_category_id_categories_id_fk",
"tableFrom": "members",
"tableTo": "categories",
"columnsFrom": [
"category_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.membership_requests": {
"name": "membership_requests",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": false
},
"message": {
"name": "message",
"type": "text",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "request_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'new'"
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.promotions": {
"name": "promotions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"title": {
"name": "title",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"text": {
"name": "text",
"type": "text",
"primaryKey": false,
"notNull": false
},
"category": {
"name": "category",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"badge": {
"name": "badge",
"type": "varchar(40)",
"primaryKey": false,
"notNull": false
},
"image_url": {
"name": "image_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"member_id": {
"name": "member_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "promo_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"valid_until": {
"name": "valid_until",
"type": "varchar(120)",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"promotions_member_id_members_id_fk": {
"name": "promotions_member_id_members_id_fk",
"tableFrom": "promotions",
"tableTo": "members",
"columnsFrom": [
"member_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(200)",
"primaryKey": false,
"notNull": true
},
"password_hash": {
"name": "password_hash",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"role": {
"name": "role",
"type": "role",
"typeSchema": "public",
"primaryKey": false,
"notNull": true,
"default": "'member'"
},
"member_id": {
"name": "member_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"users_email_idx": {
"name": "users_email_idx",
"columns": [
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"users_member_id_members_id_fk": {
"name": "users_member_id_members_id_fk",
"tableFrom": "users",
"tableTo": "members",
"columnsFrom": [
"member_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {
"public.member_status": {
"name": "member_status",
"schema": "public",
"values": [
"active",
"pending"
]
},
"public.promo_status": {
"name": "promo_status",
"schema": "public",
"values": [
"pending",
"live",
"expired",
"rejected"
]
},
"public.request_status": {
"name": "request_status",
"schema": "public",
"values": [
"new",
"approved",
"rejected"
]
},
"public.role": {
"name": "role",
"schema": "public",
"values": [
"admin",
"moderator",
"editor",
"member"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}