refactor: remove extension toggle system — compiled-in extensions are always active (#59)

The runtime toggle system (extension_toggles table, API routes, hooks, UI components)
added unnecessary complexity. Extensions controlled via extensions.config.json at build
time are now always active for all users. This removes ~835 lines of toggle-related code
including API routes, DB queries, the ExtensionToggleButton component, useEnabledExtensions
and useExtensionToggle hooks, and the toggle-check module. AI consent gating remains
unchanged.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-03-20 09:31:29 +01:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 38b658205d
commit cf77adaa0a
30 changed files with 115 additions and 833 deletions
@@ -47,7 +47,7 @@ Use `:paramName` — dispatcher extracts as `_paramName` search params:
## Dispatcher Flow
1. Extract `extensionId` and `routePath` from URL segments
2. Auth check (401) → toggle check via `isExtensionEnabled()` (403) → match method+path (404)
2. Auth check (401) → match method+path (404) → AI consent check (403 for AI extensions)
3. Extract path params → create `ExtensionContext` → call handler
## Settings Route Pattern
@@ -19,7 +19,7 @@ export default function MyExtensionWorkspace({ userId }: WorkspaceComponentProps
**3. Regenerate:** `npm run setup:extensions`
Render chain: `/e/general/my-extension` → auth+toggle check → `ExtensionWorkspaceShell` (breadcrumb+header) → your component.
Render chain: `/e/general/my-extension` → auth check → definition exists check → `ExtensionWorkspaceShell` (breadcrumb+header) → your component.
Set `"workspace": null` for extensions without a dedicated page (event-only, service-only, etc.).
@@ -45,15 +45,19 @@ Enabled extensions auto-appear in the "Tillägg" sidebar section as links to `/e
sidebarItems: [{ label: 'My Tool', icon: 'Wrench', path: '/tools/my-tool', order: 10 }]
```
## Toggle System
## Extension Enablement
Toggle state stored in `extension_toggles` table `(user_id, sector_slug, extension_slug, enabled)`. Checked server-side via `isExtensionEnabled()`. Toggle changes dispatch `extension-toggle-changed` custom event.
All compiled extensions are active for all users. To check if an extension is compiled in:
```typescript
import { ENABLED_EXTENSION_IDS } from '@/lib/extensions/_generated/enabled-extensions'
const isAvailable = ENABLED_EXTENSION_IDS.has('my-extension')
```
## Hooks
```typescript
const { extensions, isLoading, refresh } = useEnabledExtensions() // lib/extensions/hooks
const { enabled, isLoading, toggle } = useExtensionToggle('general', 'my-extension')
const { data, save, remove, getByKey } = useExtensionData('general', 'my-extension')
const { totals, monthly, totalNet } = useAccountTotals({ from, to, monthly: true })
```