diff --git a/backend/prisma/migrations/20260916040000_preset_rows/migration.sql b/backend/prisma/migrations/20260916040000_preset_rows/migration.sql index d074bff..eb1e60e 100644 --- a/backend/prisma/migrations/20260916040000_preset_rows/migration.sql +++ b/backend/prisma/migrations/20260916040000_preset_rows/migration.sql @@ -1,78 +1,85 @@ -- 역할 프리셋 기본 구성을 행으로 적재한다(2026-09-16) — 이제 기능모듈 화면에서 자리마다 켜고 끌 수 있다. -- 코드(shared/rbac/presets.ts)의 값을 그대로 옮긴 것이고, 이 행이 하나도 없으면 코드 기본값이 쓰인다. -INSERT INTO "access_control" ("subject_type", "subject_ref", "module_code", "enabled", "memo") VALUES - ('preset', 'sales_mgr', 'addon.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'customer.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'doc.send.email', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'doc.send.sign', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'doc.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'notify.push', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'order.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'order.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'quote.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'quote.edit', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'stats.all', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'sales_mgr', 'stats.own', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'addon.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'basedata.dims', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'basedata.makerprice', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'basedata.optiondb', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'basedata.weights', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'checklist.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'doc.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'notify.push', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'order.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'order.control', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'order.remove', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'order.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'quote.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'quote.edit', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'stats.all', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'pm', 'stats.own', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'addon.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'basedata.makerprice', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'checklist.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'doc.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'notify.push', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'order.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'order.control', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'order.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'quote.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'quote.edit', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'stats.all', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'prod_mgr', 'stats.own', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'addon.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'doc.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'notify.push', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'order.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'quote.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'quote.edit', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'stats.all', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'exec', 'stats.own', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'account.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'addon.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'addon.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'basedata.dims', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'basedata.holiday', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'basedata.makerprice', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'basedata.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'basedata.optiondb', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'basedata.weights', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'checklist.manage', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'customer.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'doc.send.email', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'doc.send.sign', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'doc.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'notify.assign', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'notify.push', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'order.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'order.control', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'order.remove', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'order.view', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'quote.confirm', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'quote.create', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'quote.delete', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'quote.edit', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'stats.all', true, '프리셋 기본값 — 기능모듈 화면에서 고친다'), - ('preset', 'master', 'stats.own', true, '프리셋 기본값 — 기능모듈 화면에서 고친다') +-- +-- ⚠️ **없는 모듈은 건너뛴다.** 기능모듈 행은 시드(db/seed/feature_module.csv)가 넣는다 — 마이그레이션만 돌린 +-- 빈 DB(CI 검증)에는 아직 없어서 외래키에 걸렸다. 있는 것만 넣고, 나머지는 시드 뒤 화면에서 켠다. +INSERT INTO "access_control" ("subject_type", "subject_ref", "module_code", "enabled", "memo") +SELECT 'preset'::"SubjectType", v.ref, v.code, true, '프리셋 기본값 — 기능모듈 화면에서 고친다' +FROM (VALUES + ('sales_mgr', 'addon.view'), + ('sales_mgr', 'customer.view'), + ('sales_mgr', 'doc.send.email'), + ('sales_mgr', 'doc.send.sign'), + ('sales_mgr', 'doc.view'), + ('sales_mgr', 'notify.push'), + ('sales_mgr', 'order.confirm'), + ('sales_mgr', 'order.view'), + ('sales_mgr', 'quote.confirm'), + ('sales_mgr', 'quote.edit'), + ('sales_mgr', 'stats.all'), + ('sales_mgr', 'stats.own'), + ('pm', 'addon.manage'), + ('pm', 'basedata.dims'), + ('pm', 'basedata.makerprice'), + ('pm', 'basedata.optiondb'), + ('pm', 'basedata.weights'), + ('pm', 'checklist.manage'), + ('pm', 'doc.view'), + ('pm', 'notify.push'), + ('pm', 'order.confirm'), + ('pm', 'order.control'), + ('pm', 'order.remove'), + ('pm', 'order.view'), + ('pm', 'quote.confirm'), + ('pm', 'quote.edit'), + ('pm', 'stats.all'), + ('pm', 'stats.own'), + ('prod_mgr', 'addon.manage'), + ('prod_mgr', 'basedata.makerprice'), + ('prod_mgr', 'checklist.manage'), + ('prod_mgr', 'doc.view'), + ('prod_mgr', 'notify.push'), + ('prod_mgr', 'order.confirm'), + ('prod_mgr', 'order.control'), + ('prod_mgr', 'order.view'), + ('prod_mgr', 'quote.confirm'), + ('prod_mgr', 'quote.edit'), + ('prod_mgr', 'stats.all'), + ('prod_mgr', 'stats.own'), + ('exec', 'addon.view'), + ('exec', 'doc.view'), + ('exec', 'notify.push'), + ('exec', 'order.view'), + ('exec', 'quote.confirm'), + ('exec', 'quote.edit'), + ('exec', 'stats.all'), + ('exec', 'stats.own'), + ('master', 'account.manage'), + ('master', 'addon.manage'), + ('master', 'addon.view'), + ('master', 'basedata.dims'), + ('master', 'basedata.holiday'), + ('master', 'basedata.makerprice'), + ('master', 'basedata.manage'), + ('master', 'basedata.optiondb'), + ('master', 'basedata.weights'), + ('master', 'checklist.manage'), + ('master', 'customer.view'), + ('master', 'doc.send.email'), + ('master', 'doc.send.sign'), + ('master', 'doc.view'), + ('master', 'notify.assign'), + ('master', 'notify.push'), + ('master', 'order.confirm'), + ('master', 'order.control'), + ('master', 'order.remove'), + ('master', 'order.view'), + ('master', 'quote.confirm'), + ('master', 'quote.create'), + ('master', 'quote.delete'), + ('master', 'quote.edit'), + ('master', 'stats.all'), + ('master', 'stats.own') +) AS v(ref, code) +WHERE EXISTS (SELECT 1 FROM "feature_module" f WHERE f."code" = v.code) ON CONFLICT ("subject_type", "subject_ref", "module_code") DO NOTHING; diff --git a/backend/prisma/seed.ts b/backend/prisma/seed.ts index fc8b832..334badd 100644 --- a/backend/prisma/seed.ts +++ b/backend/prisma/seed.ts @@ -99,7 +99,8 @@ async function main() { active: bool(r['active']), })); const acs = csv('access_control.csv').map(r => ({ - subject_type: r['subject_type'] as 'role' | 'user', + // 'preset' = 역할 프리셋 구성(관리자 안의 자리) — 2026-09-16 + subject_type: r['subject_type'] as 'role' | 'user' | 'preset', subject_ref: r['subject_ref']!, module_code: r['module_code']!, enabled: bool(r['enabled']), diff --git a/db/seed/access_control.csv b/db/seed/access_control.csv index 9e5a35b..234684f 100644 --- a/db/seed/access_control.csv +++ b/db/seed/access_control.csv @@ -28,3 +28,77 @@ role,MAKER,order.control,Y, role,MAKER,doc.view,Y, role,MAKER,notify.push,Y, role,ADMIN,customer.view,Y,프리셋 도입 전과 같게 — 관리자 기본 +preset,sales_mgr,addon.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,customer.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,doc.send.email,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,doc.send.sign,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,doc.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,notify.push,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,order.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,order.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,quote.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,quote.edit,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,stats.all,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,sales_mgr,stats.own,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,addon.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,basedata.dims,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,basedata.makerprice,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,basedata.optiondb,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,basedata.weights,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,checklist.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,doc.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,notify.push,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,order.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,order.control,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,order.remove,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,order.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,quote.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,quote.edit,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,stats.all,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,pm,stats.own,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,addon.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,basedata.makerprice,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,checklist.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,doc.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,notify.push,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,order.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,order.control,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,order.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,quote.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,quote.edit,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,stats.all,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,prod_mgr,stats.own,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,addon.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,doc.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,notify.push,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,order.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,quote.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,quote.edit,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,stats.all,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,exec,stats.own,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,account.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,addon.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,addon.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,basedata.dims,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,basedata.holiday,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,basedata.makerprice,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,basedata.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,basedata.optiondb,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,basedata.weights,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,checklist.manage,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,customer.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,doc.send.email,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,doc.send.sign,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,doc.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,notify.assign,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,notify.push,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,order.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,order.control,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,order.remove,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,order.view,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,quote.confirm,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,quote.create,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,quote.delete,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,quote.edit,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,stats.all,Y,프리셋 기본값 — 기능모듈 화면에서 고친다 +preset,master,stats.own,Y,프리셋 기본값 — 기능모듈 화면에서 고친다