-- 004_tasks_rbac.sql -- Manual one-shot: the `tasks` permission module (8 tags), a `tasks_management` -- bundle holding them, and the bundle attached to the staff roles that work the -- task list. Mirrors 001's idempotent pattern; applied automatically at startup -- by alembic_setup.run_manual_sql() and recorded in manual_migrations. -- -- The all_access bundle is a fixed id list seeded before this module existed, -- so system_administrator gets tasks access through THIS bundle, not that one. -- Users must log in again after this applies — permissions are resolved from -- the DB per request, but the frontend caches the list from /users/me. -- ============================================================================= -- 1. The 8 tasks.* permission tags -- ============================================================================= INSERT INTO app.permission_tags (tag_name, module, action, description, created_at, updated_at, is_active, is_deleted) VALUES ('tasks.view', 'tasks', 'view', NULL, NOW(), NOW(), true, false), ('tasks.create', 'tasks', 'create', NULL, NOW(), NOW(), true, false), ('tasks.edit', 'tasks', 'edit', NULL, NOW(), NOW(), true, false), ('tasks.delete', 'tasks', 'delete', NULL, NOW(), NOW(), true, false), ('tasks.approve', 'tasks', 'approve', NULL, NOW(), NOW(), true, false), ('tasks.export', 'tasks', 'export', NULL, NOW(), NOW(), true, false), ('tasks.manage', 'tasks', 'manage', NULL, NOW(), NOW(), true, false), ('tasks.configure', 'tasks', 'configure', NULL, NOW(), NOW(), true, false) ON CONFLICT (tag_name) DO NOTHING; -- ============================================================================= -- 2. Bundle holding all eight tasks tags -- ============================================================================= INSERT INTO app.permissions (name, description, permission_tags, is_system, created_at, updated_at, is_active, is_deleted) SELECT 'tasks_management', 'Recruiting task list: view, create, complete and manage tasks', ( SELECT COALESCE(jsonb_agg(id ORDER BY id), '[]'::jsonb) FROM app.permission_tags WHERE is_deleted = false AND module = 'tasks' ), true, NOW(), NOW(), true, false WHERE NOT EXISTS ( SELECT 1 FROM app.permissions WHERE name = 'tasks_management' ); -- ============================================================================= -- 3. Attach the bundle to the staff roles (idempotent; same role list as 001) -- ============================================================================= UPDATE app.roles r SET permissions = COALESCE(r.permissions, '[]'::jsonb) || jsonb_build_array(p.id), updated_at = NOW() FROM app.permissions p WHERE p.name = 'tasks_management' AND r.role_name IN ( 'system_administrator', 'hr_administrator', 'recruiter', 'hiring_manager', 'department_head', 'ceo' ) AND NOT (COALESCE(r.permissions, '[]'::jsonb) @> jsonb_build_array(p.id));