feat(tenants): seed all editable lookups per tenant; reserve system-shared class #189
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/pms-259-seed-lookups-system-shared-class"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Under the personal-tenant-per-user isolation model (PMS-255) every user owns their own copy of the editable lookup / configuration tables, so a freshly provisioned tenant must start with a sensible default set instead of empty status / priority / type / work-type lists.
Extend
TenantService::copy_default_configto seed the full editable-lookup set from the migration-023 default-tenant rows, re-scoped to the new tenant: business_hours, ticket_categories (parents + children), ticket_queues, time_rounding_rules, tax_rates, kb_categories, rate_cards + rate_card_items, and sla_policies + sla_targets now seed alongside the statuses / priorities / types / work types / task statuses / asset types / module config / notification templates that were already copied. Inter-lookup foreign keys (sla_policies -> business_hours, sla_targets -> sla_policies / ticket_priorities, rate_card_items -> rate_cards / work_types, child categories -> parents) are re-linked to the new tenant's freshly copied rows by name. The whole copy now runs in one transaction and is idempotent: it skips entirely when the tenant already holds ticket_statuses rows, so a retried provisioning never double-seeds.Reserve the system-shared read-only class structurally (migration 038): a
tenant_id IS NULLrow means "global / system-shared". The migration-024 tenant_isolation RLS policy is recreated with anOR tenant_id IS NULLread clause so global rows are visible to every tenant, amokosh_guard_system_shared_row()trigger function forbids writes to global rows unless the session setsapp.allow_system_writes = 'on', andmokosh_enable_system_shared(table)lets a table opt in later (drop the NOT NULL, attach the guard). No table opts in and no global row exists yet; this only reserves the room. Flipping the tenant match fail-closed and adding WITH CHECK stays with PMS-257.Record the table classification and the system-shared mechanism in dev-docs/rls-per-user-isolation.md, including the confirmed borderline calls (business_hours is editable-lookup; payment_gateway_configs and email_mailboxes are per-tenant business rows, not lookups). Add tests/personal_tenant_seed.rs: a fresh user gets the full default lookup set isolated from other users and the seed is idempotent, and the system-shared guard rejects an unprivileged global write but accepts a privileged one.
#PMS-259
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com