Phase 4: Org chart (Mitarbeiter/Positionen/Reorganisation) + one more RLS bugfix
- components/orgchart/: 3-way segmented view sharing one server fetch
(switching tabs doesn't refetch):
- EmployeeTree: expand/collapse hierarchy from the CEO down, search with
auto-expand-to-match and highlighting, "Bereiche anzeigen" /
"Alles einklappen".
- PositionTree: models the org *structure* (GF -> Bereichsleitung ->
Abteilung -> Teamleitung -> grouped IC positions by title, expandable
to the actual holders) independent of who's currently in it, plus
dashed rows for open requisitions linking to /positions.
- ReorgWorkbench: batch multiple moves (employees / whole team / whole
department / whole division as source, always a specific team as
target), live headcount-impact table, apply via the existing
apply_reorg RPC, and an undo card wired to undo_reorg.
Bug found via live apply+undo testing: undo_reorg's cleanup DELETE on
employee_history silently matched zero rows, because that table has no
DELETE policy at all (by design, for audit immutability) - RLS filters
DELETE-eligible rows to none rather than erroring. Added
supabase/functions_3.sql: a policy scoped to hr_admin deleting only rows
that carry a reorg_scenario_id, so every other history event type stays
genuinely immutable. Verified live: apply moves an employee and updates
the headcount table correctly; undo reverts team/division/manager AND
now actually removes the Reorganisation history entries it created.
Simplification flagged here (not hidden): the spec's "Ganzes Team /
Ganze Abteilung / Ganzer Bereich" reorg moves the structural org unit
itself to a new division; this implementation resolves all four move
kinds down to individual employee moves against a specific target team,
since the schema's team->department->division chain doesn't support
freely reparenting a team object without also picking a department. The
workbench UI, headcount-impact math, and apply/undo all work correctly
under this model - only the exact "move the team as a unit" semantics
differs from the literal spec wording.
This commit is contained in:
15
supabase/functions_3.sql
Normal file
15
supabase/functions_3.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Addendum to supabase/schema.sql + functions.sql — run after those.
|
||||
--
|
||||
-- employee_history intentionally has no UPDATE/DELETE policy (§4.9's
|
||||
-- "unveraenderbar" / append-only requirement). But undo_reorg needs to
|
||||
-- remove the specific history rows a reorg created — found via live
|
||||
-- testing: the DELETE inside undo_reorg silently matched 0 rows under RLS
|
||||
-- (no error, since RLS just filters DELETE-eligible rows to none), leaving
|
||||
-- Reorganisation entries behind after an otherwise-successful undo.
|
||||
--
|
||||
-- Scope the exception as narrowly as possible: hr_admin may delete a
|
||||
-- history row only if it carries a reorg_scenario_id, i.e. only rows
|
||||
-- apply_reorg created. Eintritt/Austritt/Beförderung/etc. rows (always
|
||||
-- reorg_scenario_id IS NULL) remain fully immutable.
|
||||
create policy "history_delete_admin_reorg_undo" on employee_history for delete
|
||||
using (is_hr_admin() and reorg_scenario_id is not null);
|
||||
Reference in New Issue
Block a user