fix(flags): close CRM/accounting feature-gating gaps from the audit
A sweep of every CRM/accounting toggle found surfaces still reachable
with their flag OFF. Adds a shared requireFeatureFlag middleware (the two
existing per-file copies predate it) and closes the gaps:
- Hours logging: only createEntry checked the flag — edit/delete/bill and
the list/summary routes were permission-only. Gate all six
/hour-entries routes on the hoursLogging master so a disabled feature
can't be read, mutated, or invoiced via a direct API hit.
- Installment plans: PUT /deals/:uuid/installment-plan mutates invoices
but wasn't bills-gated; add requireFeatureFlag('bills').
- Customer invoice PDF: /invoices/:id/pdf lacked the feature_bills check
the list + quotes routes have. Also fixes the quotes-PDF gate, which
read req.customer.feature_quotes (never populated → silent no-op).
- Customer contracts: /contracts + /contracts/:id/pdf were gated by
neither the master nor a per-customer column.
Per-customer contracts override (the missing counterpart):
- Migration 131 adds customer_accounts.feature_contracts, default TRUE so
existing customers keep their Contracts tab (preserve-visuals).
- Effective resolver now contractsMaster AND feature_contracts; admin
detail page gains the toggle; service/validator/serializer wired.
Cleanups:
- Drop stale `taxReport` from the sidebar's Clients-reveal list (Tax moved
to Accounting); add the missing `projects` so it mirrors the context
derivation.
- SettingsPage tab-snap effect now depends on flags.accounting.
- Fix stale taxReport "forced off when bills off" comment (it's accounting).
This commit is contained in:
@@ -30,6 +30,9 @@ export interface CustomerAccountSummary {
|
||||
/** Per-customer hour logging (migration 129). When on, the customer
|
||||
* detail page renders the "Hours" section card. */
|
||||
featureHoursLogging?: boolean;
|
||||
/** Per-customer contracts override (migration 131). Defaults true —
|
||||
* existing customers keep their Contracts tab. */
|
||||
featureContracts?: boolean;
|
||||
/** Default hourly rate in minor units (e.g. CHF 150.00 = 15000).
|
||||
* null when admin hasn't set one — each entry then requires a
|
||||
* per-block override. */
|
||||
@@ -157,6 +160,7 @@ export const customerAdminService = {
|
||||
featureQuotes: 'feature_quotes',
|
||||
featureBills: 'feature_bills',
|
||||
featureHoursLogging: 'feature_hours_logging',
|
||||
featureContracts: 'feature_contracts',
|
||||
// Hour-logging default rate (migration 129).
|
||||
hourlyRateMinor: 'hourly_rate_minor',
|
||||
// CRM billing cadence (migration 102 + 128).
|
||||
|
||||
Reference in New Issue
Block a user