feat: import row validation + KB/process per-item ACLs
Continuing the audit backlog and finishing the permissions UI. Import validation (recurring audit finding): - Added importMembersSchema / importPaymentsCsvSchema. importMembers and importPaymentsCsv now validate per row (a single bad row no longer rejects the whole file), lowercase emails, normalize dates through flexibleDateTime(), enforce tier/platform enums and positive finite amounts, and return a `skipped` count instead of silently dropping invalid rows. Permissions UI completion: - OpsAclEditor is now wired into the KB/process viewer modal (admin/board), with entity type derived from the `process` tag. Per-item Ops access control now covers secrets + KB + processes, matching "all ops facilities stuff". Left as-is with rationale in HANDOFF: /ops + /import denial paths (unreachable behind the layout gate or already a clear non-leaking denial); members-row make-area-lead shortcut (Customize -> Area leads fully covers assignment); types/database.ts + docs regen (pure hygiene, zero runtime/security impact, still tracked). 271/271 tests pass. Build clean. No migration this pass.
This commit is contained in:
@@ -19,6 +19,8 @@ All notable changes to this project are documented here. Format follows [Keep a
|
||||
- `/settings` is gated server-side to admins before any space/integration data is fetched.
|
||||
|
||||
### Fixed
|
||||
- Bulk import (`importMembers`, `importPaymentsCsv`) now validates every row with Zod: lowercased emails, `flexibleDateTime` date normalization, enum-checked platform/tier, positive finite amounts. Invalid rows are skipped and counted (returned as `skipped`) instead of silently dropped; one bad row no longer rejects the whole file.
|
||||
- Per-item Ops access control now also covers knowledge base and process entries (wired into the viewer modal), not just secrets.
|
||||
- `revealSecret` no longer silently returns the stale plaintext column when a row is marked encrypted but has no ciphertext; it surfaces the corruption instead.
|
||||
- `upsertAreaLead` rejects a null/empty area code (Postgres treats NULLs as distinct in unique constraints, which had allowed duplicate area-lead rows).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user