fix(db): suivi seeds unifie + idempotence DDL + doc trou 0004 (#111)
This commit is contained in:
parent
a6dcb31c16
commit
ba2abbfae9
6 changed files with 124 additions and 43 deletions
46
db/README.md
46
db/README.md
|
|
@ -8,21 +8,51 @@ Transcription executable du MLD (`docs/merise/mld.md`, 21 tables) vers MariaDB 1
|
||||||
db/
|
db/
|
||||||
migrations/ migrations SQL versionnees, appliquees dans l'ordre lexicographique
|
migrations/ migrations SQL versionnees, appliquees dans l'ordre lexicographique
|
||||||
0001_init_schema.sql schema initial : 21 tables, FK, CHECK, index (InnoDB, utf8mb4)
|
0001_init_schema.sql schema initial : 21 tables, FK, CHECK, index (InnoDB, utf8mb4)
|
||||||
seeds/ donnees de demonstration (a venir : roles/permissions, allergenes, catalogue)
|
seeds/ donnees de reference (RBAC, allergenes, catalogue, variantes)
|
||||||
migrate.sh runner de migrations (idempotent)
|
migrate-container.sh runner de boot IN-CONTAINER (canonique, service wakdo-migrate)
|
||||||
|
migrate.sh runner de migrations cote HOTE (manuel, via docker exec)
|
||||||
|
seed.sh runner de seeds cote HOTE (manuel, via docker exec)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Appliquer les migrations
|
## Numerotation des migrations (trou 0004 assume)
|
||||||
|
|
||||||
|
Les migrations sautent `0004` : la sequence est `0001, 0002, 0003, 0005, 0006,
|
||||||
|
0007`. Ce n'est PAS un fichier manquant mais un desalignement historique assume :
|
||||||
|
le numero `0004` a ete consomme cote `seeds/` (`0004_menu_side_maxi.sql`) lors
|
||||||
|
d'un meme increment de travail, sans contrepartie cote `migrations/`. Le suivi se
|
||||||
|
fait par NOM DE FICHIER (`schema_migrations`), pas par numero contigu : le trou
|
||||||
|
est donc inoffensif (rien ne presuppose une sequence sans lacune). Convention
|
||||||
|
conservee : ne pas reattribuer `0004` cote migrations pour eviter toute confusion
|
||||||
|
avec le seed homonyme ; la prochaine migration prend le numero suivant disponible.
|
||||||
|
|
||||||
|
## Appliquer les migrations + seeds
|
||||||
|
|
||||||
|
Chemin canonique (boot de la stack) : le service one-shot `wakdo-migrate`
|
||||||
|
(`docker compose up`) execute `db/migrate-container.sh`, qui applique
|
||||||
|
`db/migrations/*.sql` (suivi : table `schema_migrations`) PUIS `db/seeds/*.sql`
|
||||||
|
(suivi : table `seeds_applied`), de maniere idempotente. Il se connecte a
|
||||||
|
`wakdo-db` par le reseau compose.
|
||||||
|
|
||||||
|
Chemin manuel (hote, via `docker exec`) :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash db/migrate.sh # applique les migrations en attente
|
bash db/migrate.sh # applique les migrations en attente
|
||||||
bash db/migrate.sh --status # liste l'etat sans rien appliquer
|
bash db/migrate.sh --status # liste l'etat des migrations sans rien appliquer
|
||||||
|
bash db/seed.sh # charge les seeds en attente
|
||||||
|
bash db/seed.sh --status # liste l'etat des seeds sans rien charger
|
||||||
```
|
```
|
||||||
|
|
||||||
Le runner cible le conteneur `wakdo-db` et lit les identifiants dans `.env`
|
Les runners hote ciblent le conteneur `wakdo-db` et lisent les identifiants dans
|
||||||
(`DB_NAME`, `DB_ROOT_PASSWORD`). Il maintient une table `schema_migrations`
|
`.env` (`DB_NAME`, `DB_ROOT_PASSWORD`).
|
||||||
(une ligne par fichier applique) : relancer ne rejoue que les nouvelles
|
|
||||||
migrations. La cible `bash db/migrate.sh` est destinee a appeler ce script.
|
### Suivi partage entre les deux chemins
|
||||||
|
|
||||||
|
Les runners hote et conteneur partagent les MEMES tables de suivi (memes noms,
|
||||||
|
memes colonnes `filename` / `applied_at`) : `schema_migrations` pour les
|
||||||
|
migrations, `seeds_applied` pour les seeds. Consequence : rejouer un chemin apres
|
||||||
|
l'autre ne replaye RIEN. (Auparavant `db/seed.sh` suivait une table distincte
|
||||||
|
`seed_history`, ce qui pouvait lui faire re-jouer des seeds deja charges par
|
||||||
|
`wakdo-migrate` et echouer sur une contrainte UNIQUE — corrige.)
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,12 @@
|
||||||
-- the application layer.
|
-- the application layer.
|
||||||
-- - No CREATE DATABASE / USE here: the target DB is chosen by the runner.
|
-- - No CREATE DATABASE / USE here: the target DB is chosen by the runner.
|
||||||
-- - No seed / INSERT data here (see db/seeds/0001_demo_data.sql).
|
-- - No seed / INSERT data here (see db/seeds/0001_demo_data.sql).
|
||||||
|
--
|
||||||
|
-- Idempotence (defense en profondeur, suivi par schema_migrations) : chaque table
|
||||||
|
-- est creee en CREATE TABLE IF NOT EXISTS. Index, cles uniques et contraintes
|
||||||
|
-- (FK / CHECK) sont declares INLINE dans le CREATE TABLE : ils ne sont donc pas
|
||||||
|
-- re-joues quand la table preexiste. Re-jouer ce fichier sur une base deja
|
||||||
|
-- migree ne modifie pas le schema (aucun ALTER autonome).
|
||||||
-- =============================================================================
|
-- =============================================================================
|
||||||
|
|
||||||
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
@ -29,7 +35,7 @@ SET FOREIGN_KEY_CHECKS = 0;
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.1 category — root table for the Catalogue sub-domain (no FK)
|
-- 4.1 category — root table for the Catalogue sub-domain (no FK)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE category (
|
CREATE TABLE IF NOT EXISTS category (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
name VARCHAR(60) NOT NULL,
|
name VARCHAR(60) NOT NULL,
|
||||||
slug VARCHAR(60) NOT NULL,
|
slug VARCHAR(60) NOT NULL,
|
||||||
|
|
@ -46,7 +52,7 @@ CREATE TABLE category (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.6 ingredient — root table for Ingredients & Stock (no FK)
|
-- 4.6 ingredient — root table for Ingredients & Stock (no FK)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE ingredient (
|
CREATE TABLE IF NOT EXISTS ingredient (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
name VARCHAR(120) NOT NULL,
|
name VARCHAR(120) NOT NULL,
|
||||||
unit VARCHAR(40) NOT NULL,
|
unit VARCHAR(40) NOT NULL,
|
||||||
|
|
@ -71,7 +77,7 @@ CREATE TABLE ingredient (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.8 allergen — reference table (INCO EU 1169/2011), no FK
|
-- 4.8 allergen — reference table (INCO EU 1169/2011), no FK
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE allergen (
|
CREATE TABLE IF NOT EXISTS allergen (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
code VARCHAR(30) NOT NULL,
|
code VARCHAR(30) NOT NULL,
|
||||||
name VARCHAR(80) NOT NULL,
|
name VARCHAR(80) NOT NULL,
|
||||||
|
|
@ -83,7 +89,7 @@ CREATE TABLE allergen (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.10 role — root table for RBAC (no FK)
|
-- 4.10 role — root table for RBAC (no FK)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE role (
|
CREATE TABLE IF NOT EXISTS role (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
code VARCHAR(40) NOT NULL,
|
code VARCHAR(40) NOT NULL,
|
||||||
label VARCHAR(80) NOT NULL,
|
label VARCHAR(80) NOT NULL,
|
||||||
|
|
@ -100,7 +106,7 @@ CREATE TABLE role (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.13 permission — reference table, catalogue frozen at 23 codes (no FK)
|
-- 4.13 permission — reference table, catalogue frozen at 23 codes (no FK)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE permission (
|
CREATE TABLE IF NOT EXISTS permission (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
code VARCHAR(60) NOT NULL,
|
code VARCHAR(60) NOT NULL,
|
||||||
label VARCHAR(120) NOT NULL,
|
label VARCHAR(120) NOT NULL,
|
||||||
|
|
@ -113,7 +119,7 @@ CREATE TABLE permission (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.21 login_throttle — per-source-IP brute-force throttle (no FK)
|
-- 4.21 login_throttle — per-source-IP brute-force throttle (no FK)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE login_throttle (
|
CREATE TABLE IF NOT EXISTS login_throttle (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
ip_address VARCHAR(45) NOT NULL,
|
ip_address VARCHAR(45) NOT NULL,
|
||||||
failed_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
failed_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
|
@ -128,7 +134,7 @@ CREATE TABLE login_throttle (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.2 product — depends on category
|
-- 4.2 product — depends on category
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE product (
|
CREATE TABLE IF NOT EXISTS product (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
category_id INT UNSIGNED NOT NULL,
|
category_id INT UNSIGNED NOT NULL,
|
||||||
name VARCHAR(120) NOT NULL,
|
name VARCHAR(120) NOT NULL,
|
||||||
|
|
@ -151,7 +157,7 @@ CREATE TABLE product (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.3 menu — depends on category, product
|
-- 4.3 menu — depends on category, product
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE menu (
|
CREATE TABLE IF NOT EXISTS menu (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
category_id INT UNSIGNED NOT NULL,
|
category_id INT UNSIGNED NOT NULL,
|
||||||
burger_product_id INT UNSIGNED NOT NULL,
|
burger_product_id INT UNSIGNED NOT NULL,
|
||||||
|
|
@ -177,7 +183,7 @@ CREATE TABLE menu (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.4 menu_slot — depends on menu (no audit fields)
|
-- 4.4 menu_slot — depends on menu (no audit fields)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE menu_slot (
|
CREATE TABLE IF NOT EXISTS menu_slot (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
menu_id INT UNSIGNED NOT NULL,
|
menu_id INT UNSIGNED NOT NULL,
|
||||||
name VARCHAR(80) NOT NULL,
|
name VARCHAR(80) NOT NULL,
|
||||||
|
|
@ -194,7 +200,7 @@ CREATE TABLE menu_slot (
|
||||||
-- 4.5 menu_slot_option — pure join table, composite PK
|
-- 4.5 menu_slot_option — pure join table, composite PK
|
||||||
-- depends on menu_slot, product
|
-- depends on menu_slot, product
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE menu_slot_option (
|
CREATE TABLE IF NOT EXISTS menu_slot_option (
|
||||||
menu_slot_id INT UNSIGNED NOT NULL,
|
menu_slot_id INT UNSIGNED NOT NULL,
|
||||||
product_id INT UNSIGNED NOT NULL,
|
product_id INT UNSIGNED NOT NULL,
|
||||||
PRIMARY KEY (menu_slot_id, product_id),
|
PRIMARY KEY (menu_slot_id, product_id),
|
||||||
|
|
@ -209,7 +215,7 @@ CREATE TABLE menu_slot_option (
|
||||||
-- 4.7 product_ingredient — join table with attributes, composite PK
|
-- 4.7 product_ingredient — join table with attributes, composite PK
|
||||||
-- depends on product, ingredient
|
-- depends on product, ingredient
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE product_ingredient (
|
CREATE TABLE IF NOT EXISTS product_ingredient (
|
||||||
product_id INT UNSIGNED NOT NULL,
|
product_id INT UNSIGNED NOT NULL,
|
||||||
ingredient_id INT UNSIGNED NOT NULL,
|
ingredient_id INT UNSIGNED NOT NULL,
|
||||||
quantity_normal SMALLINT UNSIGNED NOT NULL DEFAULT 1,
|
quantity_normal SMALLINT UNSIGNED NOT NULL DEFAULT 1,
|
||||||
|
|
@ -232,7 +238,7 @@ CREATE TABLE product_ingredient (
|
||||||
-- 4.9 ingredient_allergen — pure join table, composite PK
|
-- 4.9 ingredient_allergen — pure join table, composite PK
|
||||||
-- depends on ingredient, allergen
|
-- depends on ingredient, allergen
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE ingredient_allergen (
|
CREATE TABLE IF NOT EXISTS ingredient_allergen (
|
||||||
ingredient_id INT UNSIGNED NOT NULL,
|
ingredient_id INT UNSIGNED NOT NULL,
|
||||||
allergen_id INT UNSIGNED NOT NULL,
|
allergen_id INT UNSIGNED NOT NULL,
|
||||||
PRIMARY KEY (ingredient_id, allergen_id),
|
PRIMARY KEY (ingredient_id, allergen_id),
|
||||||
|
|
@ -246,7 +252,7 @@ CREATE TABLE ingredient_allergen (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.11 user — depends on role
|
-- 4.11 user — depends on role
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE user (
|
CREATE TABLE IF NOT EXISTS user (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
email VARCHAR(254) NOT NULL,
|
email VARCHAR(254) NOT NULL,
|
||||||
password_hash VARCHAR(255) NOT NULL,
|
password_hash VARCHAR(255) NOT NULL,
|
||||||
|
|
@ -275,7 +281,7 @@ CREATE TABLE user (
|
||||||
-- 4.12 role_visible_source — pure join table, composite PK
|
-- 4.12 role_visible_source — pure join table, composite PK
|
||||||
-- depends on role
|
-- depends on role
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE role_visible_source (
|
CREATE TABLE IF NOT EXISTS role_visible_source (
|
||||||
role_id INT UNSIGNED NOT NULL,
|
role_id INT UNSIGNED NOT NULL,
|
||||||
source ENUM('kiosk','counter','drive') NOT NULL,
|
source ENUM('kiosk','counter','drive') NOT NULL,
|
||||||
PRIMARY KEY (role_id, source),
|
PRIMARY KEY (role_id, source),
|
||||||
|
|
@ -287,7 +293,7 @@ CREATE TABLE role_visible_source (
|
||||||
-- 4.14 role_permission — pure join table, composite PK
|
-- 4.14 role_permission — pure join table, composite PK
|
||||||
-- depends on role, permission
|
-- depends on role, permission
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE role_permission (
|
CREATE TABLE IF NOT EXISTS role_permission (
|
||||||
role_id INT UNSIGNED NOT NULL,
|
role_id INT UNSIGNED NOT NULL,
|
||||||
permission_id INT UNSIGNED NOT NULL,
|
permission_id INT UNSIGNED NOT NULL,
|
||||||
PRIMARY KEY (role_id, permission_id),
|
PRIMARY KEY (role_id, permission_id),
|
||||||
|
|
@ -301,7 +307,7 @@ CREATE TABLE role_permission (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.15 customer_order — depends on user (acting_user_id)
|
-- 4.15 customer_order — depends on user (acting_user_id)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE customer_order (
|
CREATE TABLE IF NOT EXISTS customer_order (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
order_number VARCHAR(20) NOT NULL,
|
order_number VARCHAR(20) NOT NULL,
|
||||||
idempotency_key VARCHAR(36) NULL,
|
idempotency_key VARCHAR(36) NULL,
|
||||||
|
|
@ -336,7 +342,7 @@ CREATE TABLE customer_order (
|
||||||
-- 4.16 order_item — depends on customer_order, product, menu
|
-- 4.16 order_item — depends on customer_order, product, menu
|
||||||
-- polymorphic line (product XOR menu)
|
-- polymorphic line (product XOR menu)
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE order_item (
|
CREATE TABLE IF NOT EXISTS order_item (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
order_id INT UNSIGNED NOT NULL,
|
order_id INT UNSIGNED NOT NULL,
|
||||||
item_type ENUM('product','menu') NOT NULL,
|
item_type ENUM('product','menu') NOT NULL,
|
||||||
|
|
@ -370,7 +376,7 @@ CREATE TABLE order_item (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.17 order_item_selection — depends on order_item, menu_slot, product
|
-- 4.17 order_item_selection — depends on order_item, menu_slot, product
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE order_item_selection (
|
CREATE TABLE IF NOT EXISTS order_item_selection (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
order_item_id INT UNSIGNED NOT NULL,
|
order_item_id INT UNSIGNED NOT NULL,
|
||||||
menu_slot_id INT UNSIGNED NOT NULL,
|
menu_slot_id INT UNSIGNED NOT NULL,
|
||||||
|
|
@ -391,7 +397,7 @@ CREATE TABLE order_item_selection (
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
-- 4.18 order_item_modifier — depends on order_item, ingredient
|
-- 4.18 order_item_modifier — depends on order_item, ingredient
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE order_item_modifier (
|
CREATE TABLE IF NOT EXISTS order_item_modifier (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
order_item_id INT UNSIGNED NOT NULL,
|
order_item_id INT UNSIGNED NOT NULL,
|
||||||
ingredient_id INT UNSIGNED NOT NULL,
|
ingredient_id INT UNSIGNED NOT NULL,
|
||||||
|
|
@ -411,7 +417,7 @@ CREATE TABLE order_item_modifier (
|
||||||
-- 4.19 stock_movement — append-only audit log
|
-- 4.19 stock_movement — append-only audit log
|
||||||
-- depends on ingredient, customer_order, user
|
-- depends on ingredient, customer_order, user
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE stock_movement (
|
CREATE TABLE IF NOT EXISTS stock_movement (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
ingredient_id INT UNSIGNED NOT NULL,
|
ingredient_id INT UNSIGNED NOT NULL,
|
||||||
movement_type ENUM('sale','cancellation','restock','inventory_correction') NOT NULL,
|
movement_type ENUM('sale','cancellation','restock','inventory_correction') NOT NULL,
|
||||||
|
|
@ -437,7 +443,7 @@ CREATE TABLE stock_movement (
|
||||||
-- 4.20 audit_log — append-only sensitive-action log
|
-- 4.20 audit_log — append-only sensitive-action log
|
||||||
-- depends on user, role
|
-- depends on user, role
|
||||||
-- -----------------------------------------------------------------------------
|
-- -----------------------------------------------------------------------------
|
||||||
CREATE TABLE audit_log (
|
CREATE TABLE IF NOT EXISTS audit_log (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
actor_user_id INT UNSIGNED NULL,
|
actor_user_id INT UNSIGNED NULL,
|
||||||
actor_role_id INT UNSIGNED NULL,
|
actor_role_id INT UNSIGNED NULL,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
CREATE TABLE pin_throttle (
|
-- Idempotence (defense en profondeur) : CREATE TABLE IF NOT EXISTS. La cle
|
||||||
|
-- unique, l'index et la FK sont inline dans le CREATE TABLE, donc non re-joues
|
||||||
|
-- quand la table preexiste. Re-jouer ce fichier ne modifie pas le schema.
|
||||||
|
CREATE TABLE IF NOT EXISTS pin_throttle (
|
||||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
actor_user_id INT UNSIGNED NOT NULL,
|
actor_user_id INT UNSIGNED NOT NULL,
|
||||||
failed_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
failed_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,21 @@
|
||||||
|
|
||||||
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
ALTER TABLE customer_order
|
-- Idempotence : meme garde information_schema que 0006/0007 (re-jouable sans
|
||||||
ADD COLUMN service_tag VARCHAR(20) NULL AFTER service_mode;
|
-- erreur). On verifie l'absence de la colonne `service_tag` avant l'ALTER ;
|
||||||
|
-- si elle existe deja, on execute un no-op (DO 0). Le schema resultant est
|
||||||
|
-- inchange : seul l'ajout de la colonne (si absente) est joue.
|
||||||
|
SET @col_exists := (
|
||||||
|
SELECT COUNT(*) FROM information_schema.columns
|
||||||
|
WHERE table_schema = DATABASE() AND table_name = 'customer_order' AND column_name = 'service_tag'
|
||||||
|
);
|
||||||
|
|
||||||
|
SET @ddl := IF(
|
||||||
|
@col_exists = 0,
|
||||||
|
'ALTER TABLE customer_order
|
||||||
|
ADD COLUMN service_tag VARCHAR(20) NULL AFTER service_mode',
|
||||||
|
'DO 0'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,26 @@
|
||||||
|
|
||||||
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
ALTER TABLE ingredient
|
-- Idempotence : meme garde information_schema que 0007 (re-jouable sans erreur).
|
||||||
|
-- Les trois colonnes sont ajoutees ensemble ; l'existence de la premiere
|
||||||
|
-- (`energy_kcal_100g`) suffit donc a court-circuiter le groupe. Si elle existe
|
||||||
|
-- deja, on execute un no-op (DO 0). Le schema resultant est inchange.
|
||||||
|
SET @col_exists := (
|
||||||
|
SELECT COUNT(*) FROM information_schema.columns
|
||||||
|
WHERE table_schema = DATABASE() AND table_name = 'ingredient' AND column_name = 'energy_kcal_100g'
|
||||||
|
);
|
||||||
|
|
||||||
|
SET @ddl := IF(
|
||||||
|
@col_exists = 0,
|
||||||
|
'ALTER TABLE ingredient
|
||||||
ADD COLUMN energy_kcal_100g SMALLINT UNSIGNED NULL AFTER pack_label,
|
ADD COLUMN energy_kcal_100g SMALLINT UNSIGNED NULL AFTER pack_label,
|
||||||
ADD COLUMN nutrition_source VARCHAR(120) NULL AFTER energy_kcal_100g,
|
ADD COLUMN nutrition_source VARCHAR(120) NULL AFTER energy_kcal_100g,
|
||||||
ADD COLUMN nutrition_fetched_at DATETIME NULL AFTER nutrition_source;
|
ADD COLUMN nutrition_fetched_at DATETIME NULL AFTER nutrition_source',
|
||||||
|
'DO 0'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @ddl;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
-- energy_kcal_100g : apport energetique pour 100 g (SMALLINT UNSIGNED suffit ; les
|
-- energy_kcal_100g : apport energetique pour 100 g (SMALLINT UNSIGNED suffit ; les
|
||||||
-- valeurs reelles restent < 1000). nutrition_source : provenance ("OpenFoodFacts").
|
-- valeurs reelles restent < 1000). nutrition_source : provenance ("OpenFoodFacts").
|
||||||
|
|
|
||||||
22
db/seed.sh
22
db/seed.sh
|
|
@ -1,11 +1,19 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# Wakdo - seed runner.
|
# Wakdo - seed runner (hote, via `docker exec`).
|
||||||
#
|
#
|
||||||
# Applique les fichiers db/seeds/*.sql dans l'ordre lexicographique, de maniere
|
# Applique les fichiers db/seeds/*.sql dans l'ordre lexicographique, de maniere
|
||||||
# idempotente : une table seed_history enregistre les fichiers deja charges.
|
# idempotente : la table seeds_applied enregistre les fichiers deja charges.
|
||||||
# Les seeds doivent etre joues APRES les migrations (les tables doivent exister).
|
# Les seeds doivent etre joues APRES les migrations (les tables doivent exister).
|
||||||
#
|
#
|
||||||
|
# Contrepartie hote de db/migrate.sh : meme role que la phase seed du service de
|
||||||
|
# boot wakdo-migrate (db/migrate-container.sh), mais lance manuellement depuis
|
||||||
|
# l'hote. Le suivi DOIT utiliser la MEME table que le runner conteneur
|
||||||
|
# (seeds_applied) pour que les deux interoperent : rejouer l'un apres l'autre ne
|
||||||
|
# replaye RIEN. Auparavant ce script suivait une table distincte (seed_history),
|
||||||
|
# ce qui lui faisait re-jouer des seeds deja charges par wakdo-migrate (INSERT
|
||||||
|
# bruts -> echec sur contrainte UNIQUE).
|
||||||
|
#
|
||||||
# Cible : le service docker-compose `wakdo-db`. Identifiants lus dans .env.
|
# Cible : le service docker-compose `wakdo-db`. Identifiants lus dans .env.
|
||||||
#
|
#
|
||||||
# Usage :
|
# Usage :
|
||||||
|
|
@ -34,7 +42,9 @@ if [ ! -d "$SEEDS_DIR" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
db "$DB_NAME" -e "CREATE TABLE IF NOT EXISTS seed_history (
|
# Meme schema de suivi que db/migrate-container.sh (seeds_applied) : nom de table
|
||||||
|
# et colonnes identiques, pour que les deux runners partagent le meme journal.
|
||||||
|
db "$DB_NAME" -e "CREATE TABLE IF NOT EXISTS seeds_applied (
|
||||||
filename VARCHAR(255) NOT NULL PRIMARY KEY,
|
filename VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||||
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"
|
||||||
|
|
@ -47,7 +57,7 @@ if [ "${1:-}" = "--status" ]; then
|
||||||
echo "[seed] etat des seeds (base $DB_NAME) :"
|
echo "[seed] etat des seeds (base $DB_NAME) :"
|
||||||
for f in "${files[@]}"; do
|
for f in "${files[@]}"; do
|
||||||
base="$(basename "$f")"
|
base="$(basename "$f")"
|
||||||
n="$(db "$DB_NAME" -N -s -e "SELECT COUNT(*) FROM seed_history WHERE filename='$base';")"
|
n="$(db "$DB_NAME" -N -s -e "SELECT COUNT(*) FROM seeds_applied WHERE filename='$base';")"
|
||||||
[ "$n" = "0" ] && echo " PENDING $base" || echo " loaded $base"
|
[ "$n" = "0" ] && echo " PENDING $base" || echo " loaded $base"
|
||||||
done
|
done
|
||||||
exit 0
|
exit 0
|
||||||
|
|
@ -56,11 +66,11 @@ fi
|
||||||
loaded=0
|
loaded=0
|
||||||
for f in "${files[@]}"; do
|
for f in "${files[@]}"; do
|
||||||
base="$(basename "$f")"
|
base="$(basename "$f")"
|
||||||
n="$(db "$DB_NAME" -N -s -e "SELECT COUNT(*) FROM seed_history WHERE filename='$base';")"
|
n="$(db "$DB_NAME" -N -s -e "SELECT COUNT(*) FROM seeds_applied WHERE filename='$base';")"
|
||||||
if [ "$n" = "0" ]; then
|
if [ "$n" = "0" ]; then
|
||||||
echo "[seed] chargement de $base ..."
|
echo "[seed] chargement de $base ..."
|
||||||
db "$DB_NAME" < "$f"
|
db "$DB_NAME" < "$f"
|
||||||
db "$DB_NAME" -e "INSERT INTO seed_history (filename) VALUES ('$base');"
|
db "$DB_NAME" -e "INSERT INTO seeds_applied (filename) VALUES ('$base');"
|
||||||
loaded=$((loaded + 1))
|
loaded=$((loaded + 1))
|
||||||
else
|
else
|
||||||
echo "[seed] $base deja charge, ignore"
|
echo "[seed] $base deja charge, ignore"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue