Consolidation pass: HR-only access, effective-dated mutations, data integrity guards, test suite
Reworks the app from a two-role (hr_admin/manager) model to a single HR-only role gated by profiles.is_active, fixes transfer/promote/karenz/ reorg RPCs to actually defer future-dated changes via a new pending_org_changes table instead of writing them immediately (applied by a daily Vercel Cron route), makes reorg undo append-only instead of deleting history, adds Karenz-return and history-date integrity guards, deprecates the salary column, and adds explicit schema grants + perf indexes needed to run against a fresh (non-hosted) Postgres instance. Adds vitest unit + integration test suites (the latter against a real local Supabase instance) covering all of the above, plus lint/typecheck/ build wiring (`npm run check`).
This commit is contained in:
33
supabase/migrations/20260714120400_performance_indexes.sql
Normal file
33
supabase/migrations/20260714120400_performance_indexes.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
-- Performance indexes (spec §15).
|
||||
--
|
||||
-- Existing indexes already cover employees(team_id/division_id/manager_id/
|
||||
-- status), employee_history(employee_id, event_date desc), positions(team_id/
|
||||
-- status), audit_log(occurred_at desc), and the new pending_org_changes
|
||||
-- table's own indexes (see its migration). This adds the gaps: location-based
|
||||
-- filtering, entry/exit date range queries (dashboard "upcoming" widget +
|
||||
-- Eintritte/Austritte reports), personnel-number lookup (also enforces the
|
||||
-- uniqueness a personnel number should have, which the identity column
|
||||
-- alone did not), reorg/audit foreign-key lookups, and trigram search
|
||||
-- support for the employee list's free-text search box.
|
||||
|
||||
create unique index if not exists idx_employees_personnel_number on employees (personnel_number);
|
||||
create index if not exists idx_employees_location_id on employees (location_id);
|
||||
create index if not exists idx_employees_entry_date on employees (entry_date);
|
||||
create index if not exists idx_employees_exit_date on employees (exit_date) where exit_date is not null;
|
||||
create index if not exists idx_employees_karenz_return_date on employees (karenz_return_date) where karenz_return_date is not null;
|
||||
|
||||
create index if not exists idx_audit_log_target_employee_id on audit_log (target_employee_id) where target_employee_id is not null;
|
||||
create index if not exists idx_employee_history_reorg_scenario_id on employee_history (reorg_scenario_id) where reorg_scenario_id is not null;
|
||||
create index if not exists idx_employee_history_event_type on employee_history (event_type);
|
||||
create index if not exists idx_reorg_scenarios_applied on reorg_scenarios (applied, applied_at desc);
|
||||
create index if not exists idx_positions_division_id on positions (division_id);
|
||||
|
||||
-- Free-text search over name/title (Mitarbeiter:innen list search box) —
|
||||
-- trigram index so ILIKE '%term%' queries can use an index instead of a
|
||||
-- sequential scan.
|
||||
create extension if not exists pg_trgm;
|
||||
|
||||
create index if not exists idx_employees_name_trgm
|
||||
on employees using gin ((first_name || ' ' || last_name) gin_trgm_ops);
|
||||
create index if not exists idx_employees_job_title_trgm
|
||||
on employees using gin (job_title gin_trgm_ops);
|
||||
Reference in New Issue
Block a user