feat(residential-toggle): port-level module gate for Residential
Adds a `residential_module_enabled` port setting (default ON) that hides/disables the entire Residential surface when an admin turns it off, mirroring the Tenancies / Invoices / Expenses module-toggle pattern. Disabling is a soft hide — residential clients/interests are preserved and reappear on re-enable. Surfaces gated: - Route guard: new residential/layout.tsx renders ModuleDisabledPage (covers all 5 residential pages) - Sidebar "Residential" section + mobile more-sheet tile (SSR-resolved residentialModuleByPort threaded layout → app-shell → sidebar) - Global search: residential client/interest buckets early-return at the shared chokepoint so disabled-port records don't dead-end - Public intake: /api/public/residential-inquiries 404s when off - Admin Switch in settings-manager (writes via settings PUT) Service TDD'd (residential-module.test.ts, 6 tests) plus a disabled-port rejection test on the public endpoint. tsc + lint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,9 +81,14 @@ const MORE_GROUPS: MoreGroup[] = [
|
||||
export function MoreSheet({
|
||||
open,
|
||||
onOpenChange,
|
||||
residentialModuleEnabled = true,
|
||||
}: {
|
||||
open: boolean;
|
||||
onOpenChange: (next: boolean) => void;
|
||||
/** Per-port residential-module gate, resolved SSR-side in the shell.
|
||||
* Hides the Residential tile when the module is off. Defaults to true
|
||||
* so a missing value keeps the feature visible (registry default). */
|
||||
residentialModuleEnabled?: boolean;
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const portSlug = pathname.split('/').filter(Boolean)[0] ?? 'port-nimara';
|
||||
@@ -98,6 +103,7 @@ export function MoreSheet({
|
||||
...g,
|
||||
items: g.items.filter((item) => {
|
||||
if (item.segment === 'website-analytics') return umamiConfigured;
|
||||
if (item.segment === 'residential/clients') return residentialModuleEnabled;
|
||||
return true;
|
||||
}),
|
||||
})).filter((g) => g.items.length > 0);
|
||||
|
||||
Reference in New Issue
Block a user