From 652e3f91fc15a0e1bd786852cd9fa4cc62f5403e Mon Sep 17 00:00:00 2001 From: BOHA Date: Wed, 3 Jun 2026 23:26:34 +0200 Subject: [PATCH] fix(warehouse): add migration for warehouse permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The warehouse module v1.8.0 deploy created the warehouse tables via Prisma migration but left the corresponding permissions (warehouse.view/operate/ manage/inventory) and admin role assignments un-inserted, because those rows only existed in prisma/seed.ts, which is dev-only and cannot be run against production. This migration inserts the same 4 permissions seed.ts would (with identical display_name and description) and assigns them to the admin role. INSERT IGNORE makes it idempotent and preserves existing role assignments. No data is modified or deleted. Also strengthens CLAUDE.md: every database change or manipulation must be a tracked Prisma migration. No external SQL, no seed-only data, no manual fixes — reviewable, reversible, reproducible from a fresh checkout. --- CLAUDE.md | 19 ++++++++++++ .../migration.sql | 29 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 prisma/migrations/20260603230000_add_warehouse_permissions/migration.sql diff --git a/CLAUDE.md b/CLAUDE.md index 0184764..0e2ecb3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -289,6 +289,23 @@ When entity A embeds/references entity B, A's mutation handlers invalidate B's d **Golden rule: NEVER use `prisma db push`.** It bypasses migration history and causes drift between the schema and migration tracking. Always use `prisma migrate dev` for every schema change. +**Every database change or manipulation must be a tracked Prisma migration.** This includes: + +- Schema changes (tables, columns, indexes, constraints) — via `prisma migrate dev` +- Permission/role/seed data changes — via a migration that does the INSERTs/DELETEs explicitly +- Lookup data, default settings, or any other row-level baseline that production needs +- Backfills, data fixes, and one-shot corrections that should be in sync across environments + +**What is NOT acceptable:** + +- Running raw SQL against production (`mysql -e "..."`, `npx prisma db execute`, `pm2 exec`) +- `npx prisma db seed` as the only way to populate data (seed is dev-only convenience; prod must run the same SQL via a migration) +- "I'll fix it in the seed file" or "I'll add a row manually" without a migration to back it + +The reason: every change to the production database must be reviewable, reversible, and reproducible from a fresh checkout. External SQL commands and seed-only changes cause drift — prod and dev diverge, rollback gets harder with every manual change, and the next deploy surprises us. + +If you need to insert/update/seed data on production, write a migration. The migration's `migration.sql` is a normal SQL file — `INSERT INTO ...`, `UPDATE ...`, `DELETE ...` are all valid. Prisma will run it via `prisma migrate deploy` like any other migration. + ### Making schema changes ``` @@ -369,6 +386,8 @@ npx prisma migrate resolve --applied 10. **Czech locale hardcoded** — Error messages, month names, and some business logic strings are Czech. This is intentional. +11. **Seed file is dev-only** — `prisma/seed.ts` is for local dev convenience. It is **not** the production data source. Any data the production database must have (permissions, default roles, baseline rows) belongs in a migration's `migration.sql`, not in the seed file. `npx prisma db seed` must never be run against production. + --- ## Release Process diff --git a/prisma/migrations/20260603230000_add_warehouse_permissions/migration.sql b/prisma/migrations/20260603230000_add_warehouse_permissions/migration.sql new file mode 100644 index 0000000..7e72e8e --- /dev/null +++ b/prisma/migrations/20260603230000_add_warehouse_permissions/migration.sql @@ -0,0 +1,29 @@ +-- Add warehouse module permissions and assign them to the admin role. +-- These rows used to be created by `prisma/seed.ts`, which is dev-only and +-- must not be run against production (per CLAUDE.md). This migration is +-- idempotent: re-running it is a no-op. +-- +-- The 4 permissions match `prisma/seed.ts` lines 284-308 exactly. + +-- 1. Insert the 4 warehouse permissions (INSERT IGNORE skips on duplicate +-- name, so re-running the migration is safe). +INSERT IGNORE INTO `permissions` (`name`, `display_name`, `module`, `description`, `created_at`) VALUES + ('warehouse.view', 'Zobrazit sklad', 'warehouse', 'Prohlížet stav skladu, položky, reporty a historii pohybů', NOW()), + ('warehouse.operate', 'Příjem a výdej', 'warehouse', 'Vytvářet a potvrzovat příjmy, výdeje a rezervace', NOW()), + ('warehouse.manage', 'Správa skladu', 'warehouse', 'Spravovat katalog materiálů, dodavatele, lokace a kategorie', NOW()), + ('warehouse.inventory', 'Inventura', 'warehouse', 'Vytvářet a potvrzovat inventurní sčítkání', NOW()); + +-- 2. Assign all 4 permissions to the admin role. INSERT IGNORE on the +-- composite primary key (role_id, permission_id) makes this idempotent +-- and preserves any other role assignments that already exist. +INSERT IGNORE INTO `role_permissions` (`role_id`, `permission_id`) +SELECT r.id, p.id +FROM `roles` r +CROSS JOIN `permissions` p +WHERE r.name = 'admin' + AND p.name IN ( + 'warehouse.view', + 'warehouse.operate', + 'warehouse.manage', + 'warehouse.inventory' + );