-- Migration: Application Roles + Permission Matrix -- Rename users.role -> users.app_role, create app_roles/permissions/app_role_permissions -- NOTE: users.role column is kept as-is. Do NOT rename it to app_role. -- The app_roles/permissions tables are additive and coexist with the legacy role column. -- 1. Create app_roles table CREATE TABLE IF NOT EXISTS app_roles ( id SERIAL PRIMARY KEY, slug VARCHAR(50) NOT NULL UNIQUE, name VARCHAR(100) NOT NULL, description TEXT, is_system BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW() ); -- 3. Create permissions table CREATE TABLE IF NOT EXISTS permissions ( id SERIAL PRIMARY KEY, code VARCHAR(100) NOT NULL UNIQUE, name VARCHAR(100) NOT NULL, description TEXT, module VARCHAR(50), created_at TIMESTAMP DEFAULT NOW() ); -- 4. Create app_role_permissions table CREATE TABLE IF NOT EXISTS app_role_permissions ( id SERIAL PRIMARY KEY, app_role_id INTEGER NOT NULL REFERENCES app_roles(id) ON DELETE CASCADE, permission_id INTEGER NOT NULL REFERENCES permissions(id) ON DELETE CASCADE, CONSTRAINT app_role_permissions_role_perm_key UNIQUE (app_role_id, permission_id) ); -- 5. Seed app_roles INSERT INTO app_roles (slug, name, description, is_system) VALUES ('admin', 'Администратор', 'Полный доступ ко всем функциям приложения', TRUE), ('user', 'Пользователь', 'Базовый доступ к задачам и чату', TRUE) ON CONFLICT (slug) DO NOTHING; -- 6. Seed permissions INSERT INTO permissions (code, name, description, module) VALUES ('super_admin.access', 'Доступ к супер-админке', 'Управление организациями на уровне супер-админа', 'system'), ('users.manage', 'Управление пользователями', 'Создание, редактирование и удаление пользователей', 'users'), ('roles.manage', 'Управление ролями', 'Создание и редактирование организационных ролей', 'users'), ('forms.manage', 'Управление формами', 'Создание и редактирование форм и полей', 'forms'), ('tasks.view_all', 'Видеть все задачи', 'Доступ ко всем задачам организации', 'tasks'), ('tasks.edit_all', 'Редактировать все задачи', 'Редактирование любых задач', 'tasks'), ('directories.manage', 'Управление справочниками', 'Создание и редактирование справочников', 'directories'), ('finance.view', 'Просмотр финансов', 'Доступ к модулю Финансы', 'finance'), ('finance.manage', 'Управление финансами', 'Редактирование финансовых данных', 'finance'), ('billing.view', 'Просмотр биллинга', 'Просмотр биллинговой информации', 'billing'), ('billing.manage', 'Управление биллингом', 'Управление биллингом и оплатой', 'billing'), ('settings.manage', 'Управление настройками', 'Настройки организации', 'settings'), ('automations.manage', 'Управление автоматизациями', 'Создание и редактирование автоматизаций', 'automations'), ('bots.manage', 'Управление ботами', 'Создание и настройка ботов', 'bots'), ('chat.manage', 'Управление чатами', 'Администрирование групповых чатов', 'chat'), ('reports.view', 'Просмотр отчётов', 'Доступ к отчётам', 'reports'), ('profile.edit', 'Редактирование профиля', 'Изменение собственного профиля', 'profile'), ('inbox.view', 'Доступ к inbox', 'Просмотр inbox и главной страницы', 'inbox') ON CONFLICT (code) DO NOTHING; -- 7. Assign permissions to admin (all permissions) INSERT INTO app_role_permissions (app_role_id, permission_id) SELECT ar.id, p.id FROM app_roles ar CROSS JOIN permissions p WHERE ar.slug = 'admin' ON CONFLICT ON CONSTRAINT app_role_permissions_role_perm_key DO NOTHING; -- 8. Assign minimal permissions to user INSERT INTO app_role_permissions (app_role_id, permission_id) SELECT ar.id, p.id FROM app_roles ar JOIN permissions p ON p.code IN ( 'profile.edit', 'inbox.view', 'chat.use', 'tasks.view_own' ) WHERE ar.slug = 'user' ON CONFLICT ON CONSTRAINT app_role_permissions_role_perm_key DO NOTHING; -- 9. Migrate existing users: fix corrupted roles from UserModal bug UPDATE users SET app_role = 'user' WHERE app_role NOT IN ('admin', 'user'); -- 10. Ensure all existing users have a valid app_role UPDATE users SET app_role = COALESCE(app_role, 'user');