Files
pn-new-crm/src/lib/db/seed-permissions.ts
Matt d8f739a7c2 feat(rbac): GDPR export becomes a toggleable clients.gdpr_export permission
Previously the GDPR export trigger + download routes were gated by
admin.manage_settings, so sales roles couldn't run a client data export.
Per request, make it a dedicated, toggleable permission that's on by
default for sales-capable roles and hides the button when withheld.

- New RolePermissions leaf clients.gdpr_export (+ PERMISSION_CATALOG entry);
  strict type forces every role map + fixture to declare it.
- Granted true for super_admin / director / sales_manager / sales_agent;
  false for viewer / residential_partner.
- GDPR export POST (trigger) and [exportId] GET (download) re-gated from
  admin.manage_settings -> clients.gdpr_export.
- GdprExportButton visibility now keys off clients.gdpr_export, so toggling
  it off per-user hides the function entirely.
- Migration 0098 backfills the key onto existing role rows (idempotent).

Verified end-to-end as a Sales user: trigger (202) -> worker build (ready)
-> list (200) -> download (200). 1664 vitest pass; tsc + eslint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 13:20:31 +02:00

513 lines
13 KiB
TypeScript

/**
* Seed-time permission maps for the six system roles.
*
* Kept in their own module so both `seed.ts` (realistic) and
* `seed-synthetic.ts` can share them without drift, and so the
* giant role/permission grids don't pollute the seed orchestrator.
*
* Keep in sync with `src/lib/db/schema/users.ts → RolePermissions`
* and `src/components/admin/roles/role-form.tsx → DEFAULT_PERMISSIONS`.
*/
import type { RolePermissions } from './schema/users';
export const ALL_PERMISSIONS: RolePermissions = {
clients: {
view: true,
create: true,
edit: true,
delete: true,
merge: true,
export: true,
gdpr_export: true,
},
interests: {
view: true,
create: true,
edit: true,
delete: true,
change_stage: true,
override_stage: true,
generate_eoi: true,
export: true,
},
berths: { view: true, edit: true, import: true, manage_waiting_list: true, update_prices: true },
documents: {
view: true,
create: true,
edit: true,
send_for_signing: true,
upload_signed: true,
delete: true,
manage_folders: true,
},
expenses: {
view: true,
create: true,
edit: true,
delete: true,
export: true,
scan_receipt: true,
},
invoices: {
view: true,
create: true,
edit: true,
delete: true,
send: true,
record_payment: true,
export: true,
},
payments: { view: true, record: true, delete: true },
files: { view: true, upload: true, edit: true, delete: true, manage_folders: true },
email: { view: true, send: true, configure_account: true },
reminders: {
view_own: true,
view_all: true,
create: true,
edit_own: true,
edit_all: true,
assign_others: true,
},
calendar: { connect: true, view_events: true },
reports: { view_dashboard: true, view_analytics: true, export: true },
document_templates: { view: true, generate: true, manage: true },
yachts: { view: true, create: true, edit: true, delete: true, transfer: true },
companies: { view: true, create: true, edit: true, delete: true },
memberships: { view: true, manage: true },
tenancies: { view: true, manage: true, cancel: true },
admin: {
manage_users: true,
view_audit_log: true,
manage_settings: true,
manage_webhooks: true,
manage_reports: true,
manage_custom_fields: true,
manage_forms: true,
manage_tags: true,
system_backup: true,
permanently_delete_clients: true,
},
residential_clients: { view: true, create: true, edit: true, delete: true },
residential_interests: {
view: true,
create: true,
edit: true,
delete: true,
change_stage: true,
},
inquiries: {
view: true,
manage: true,
},
client_groups: {
view: true,
manage: true,
},
};
// DIRECTOR_PERMISSIONS is defined just below SALES_MANAGER_PERMISSIONS — it is a
// senior-title twin of the single "Sales" role with identical capabilities and
// no admin/settings access (reserved for Super Admin). Kept there so it can
// reference the sales map directly.
export const SALES_MANAGER_PERMISSIONS: RolePermissions = {
clients: {
view: true,
create: true,
edit: true,
delete: false,
merge: true,
export: true,
gdpr_export: true,
},
interests: {
view: true,
create: true,
edit: true,
delete: false,
change_stage: true,
override_stage: true,
generate_eoi: true,
export: true,
},
berths: { view: true, edit: true, import: false, manage_waiting_list: true, update_prices: true },
documents: {
view: true,
create: true,
edit: true,
send_for_signing: true,
upload_signed: true,
delete: false,
manage_folders: true,
},
expenses: {
view: true,
create: true,
edit: true,
delete: false,
export: true,
scan_receipt: true,
},
invoices: {
view: true,
create: true,
edit: true,
delete: false,
send: true,
record_payment: true,
export: true,
},
payments: { view: true, record: true, delete: true },
files: { view: true, upload: true, edit: true, delete: false, manage_folders: true },
email: { view: true, send: true, configure_account: true },
reminders: {
view_own: true,
view_all: true,
create: true,
edit_own: true,
edit_all: true,
assign_others: true,
},
calendar: { connect: true, view_events: true },
reports: { view_dashboard: true, view_analytics: true, export: true },
document_templates: { view: true, generate: true, manage: false },
yachts: { view: true, create: true, edit: true, delete: false, transfer: true },
companies: { view: true, create: true, edit: true, delete: false },
memberships: { view: true, manage: true },
tenancies: { view: true, manage: true, cancel: true },
admin: {
manage_users: false,
view_audit_log: false,
manage_settings: false,
manage_webhooks: false,
manage_reports: false,
manage_custom_fields: false,
manage_forms: false,
manage_tags: true,
system_backup: false,
permanently_delete_clients: false,
},
residential_clients: { view: false, create: false, edit: false, delete: false },
residential_interests: {
view: false,
create: false,
edit: false,
delete: false,
change_stage: false,
},
inquiries: {
view: true,
manage: true,
},
client_groups: {
view: true,
manage: true,
},
};
// Director is now a senior-title twin of the single "Sales" role: identical
// capabilities, no admin/settings access (admin stays Super-Admin-only). It
// remains a distinct, selectable role purely so the title can differ.
export const DIRECTOR_PERMISSIONS: RolePermissions = SALES_MANAGER_PERMISSIONS;
export const SALES_AGENT_PERMISSIONS: RolePermissions = {
clients: {
view: true,
create: true,
edit: true,
delete: false,
merge: false,
export: true,
gdpr_export: true,
},
interests: {
view: true,
create: true,
edit: true,
delete: false,
change_stage: true,
override_stage: true,
generate_eoi: true,
export: true,
},
berths: { view: true, edit: true, import: false, manage_waiting_list: true, update_prices: true },
documents: {
view: true,
create: true,
edit: true,
send_for_signing: true,
upload_signed: true,
delete: false,
manage_folders: false,
},
expenses: {
view: true,
create: true,
edit: true,
delete: false,
export: true,
scan_receipt: true,
},
invoices: {
view: true,
create: true,
edit: true,
delete: false,
send: true,
record_payment: true,
export: true,
},
payments: { view: true, record: true, delete: true },
files: { view: true, upload: true, edit: false, delete: false, manage_folders: false },
email: { view: true, send: true, configure_account: true },
reminders: {
view_own: true,
view_all: false,
create: true,
edit_own: true,
edit_all: false,
assign_others: false,
},
calendar: { connect: true, view_events: true },
reports: { view_dashboard: true, view_analytics: true, export: true },
document_templates: { view: true, generate: true, manage: false },
yachts: { view: true, create: true, edit: true, delete: false, transfer: false },
companies: { view: true, create: true, edit: false, delete: false },
memberships: { view: true, manage: false },
tenancies: { view: true, manage: true, cancel: false },
admin: {
manage_users: false,
view_audit_log: false,
manage_settings: false,
manage_webhooks: false,
manage_reports: false,
manage_custom_fields: false,
manage_forms: false,
manage_tags: true,
system_backup: false,
permanently_delete_clients: false,
},
residential_clients: { view: false, create: false, edit: false, delete: false },
residential_interests: {
view: false,
create: false,
edit: false,
delete: false,
change_stage: false,
},
inquiries: {
view: true,
manage: true,
},
client_groups: {
view: true,
manage: true,
},
};
export const VIEWER_PERMISSIONS: RolePermissions = {
clients: {
view: true,
create: false,
edit: false,
delete: false,
merge: false,
export: false,
gdpr_export: false,
},
interests: {
view: true,
create: false,
edit: false,
delete: false,
change_stage: false,
override_stage: false,
generate_eoi: false,
export: false,
},
berths: {
view: true,
edit: false,
import: false,
manage_waiting_list: false,
update_prices: false,
},
documents: {
view: true,
create: false,
edit: false,
send_for_signing: false,
upload_signed: false,
delete: false,
manage_folders: false,
},
expenses: {
view: true,
create: false,
edit: false,
delete: false,
export: false,
scan_receipt: false,
},
invoices: {
view: true,
create: false,
edit: false,
delete: false,
send: false,
record_payment: false,
export: false,
},
payments: { view: true, record: false, delete: false },
files: { view: true, upload: false, edit: false, delete: false, manage_folders: false },
email: { view: true, send: false, configure_account: false },
reminders: {
view_own: true,
view_all: false,
create: false,
edit_own: false,
edit_all: false,
assign_others: false,
},
calendar: { connect: false, view_events: true },
reports: { view_dashboard: true, view_analytics: false, export: false },
document_templates: { view: true, generate: false, manage: false },
yachts: { view: true, create: false, edit: false, delete: false, transfer: false },
companies: { view: true, create: false, edit: false, delete: false },
memberships: { view: true, manage: false },
tenancies: { view: true, manage: false, cancel: false },
admin: {
manage_users: false,
view_audit_log: false,
manage_settings: false,
manage_webhooks: false,
manage_reports: false,
manage_custom_fields: false,
manage_forms: false,
manage_tags: false,
system_backup: false,
permanently_delete_clients: false,
},
residential_clients: { view: false, create: false, edit: false, delete: false },
residential_interests: {
view: false,
create: false,
edit: false,
delete: false,
change_stage: false,
},
inquiries: {
view: true,
manage: false,
},
client_groups: {
view: true,
manage: false,
},
};
// Residential Partner - for an outside party who handles residential
// inquiries on the marina's behalf. Sees only the residential pages and
// nothing else; can't see marina clients, yachts, berths, EOIs, etc.
export const RESIDENTIAL_PARTNER_PERMISSIONS: RolePermissions = {
clients: {
view: false,
create: false,
edit: false,
delete: false,
merge: false,
export: false,
gdpr_export: false,
},
interests: {
view: false,
create: false,
edit: false,
delete: false,
change_stage: false,
override_stage: false,
generate_eoi: false,
export: false,
},
berths: {
view: false,
edit: false,
import: false,
manage_waiting_list: false,
update_prices: false,
},
documents: {
view: false,
create: false,
edit: false,
send_for_signing: false,
upload_signed: false,
delete: false,
manage_folders: false,
},
expenses: {
view: false,
create: false,
edit: false,
delete: false,
export: false,
scan_receipt: false,
},
invoices: {
view: false,
create: false,
edit: false,
delete: false,
send: false,
record_payment: false,
export: false,
},
payments: { view: false, record: false, delete: false },
files: { view: false, upload: false, edit: false, delete: false, manage_folders: false },
email: { view: false, send: false, configure_account: false },
reminders: {
view_own: true,
view_all: false,
create: true,
edit_own: true,
edit_all: false,
assign_others: false,
},
calendar: { connect: false, view_events: false },
reports: { view_dashboard: false, view_analytics: false, export: false },
document_templates: { view: false, generate: false, manage: false },
yachts: { view: false, create: false, edit: false, delete: false, transfer: false },
companies: { view: false, create: false, edit: false, delete: false },
memberships: { view: false, manage: false },
tenancies: { view: false, manage: false, cancel: false },
admin: {
manage_users: false,
view_audit_log: false,
manage_settings: false,
manage_webhooks: false,
manage_reports: false,
manage_custom_fields: false,
manage_forms: false,
manage_tags: false,
system_backup: false,
permanently_delete_clients: false,
},
residential_clients: { view: true, create: true, edit: true, delete: false },
residential_interests: {
view: true,
create: true,
edit: true,
delete: false,
change_stage: true,
},
inquiries: {
view: false,
manage: false,
},
client_groups: {
view: false,
manage: false,
},
};