import { sdk } from '../sdk' import { configFile } from '../file-models/config.json' const { InputSpec, Value } = sdk // Multi-tenant mode (a.k.a. cloud mode) turns the self-hosted Recaps // into a multi-user app served over the web. Adds email + magic-link // auth, per-user libraries, per-user keysat licenses, and BTCPay-based // subscriptions. The .s9pk defaults to single-mode (one operator, no // auth) so installing Recaps doesn't surprise anyone — multi is the // deliberate opt-in for operators who want to host the app for others. // // Prerequisites before enabling: // 1. StartOS System SMTP must be configured + tested. Magic-link // emails fail otherwise. // 2. "Set Recaps public URL" action must be run with the ClearNet URL // where your Recaps will live (e.g. https://recap.example.com), // so the sign-in emails contain a working link. // 3. A keysat issuer the relay trusts must be reachable, since each // cloud user gets a keysat-minted license at signup. // // Switching back to single mode is non-destructive — multi-tenant data // (the user DB at /data/recap.db) stays on disk and is restored if you // flip back to multi later. The operator-owner's library lives under // /data/history/owner/ in either mode. const inputSpec = InputSpec.of({ mode: Value.select({ name: 'Mode', description: 'Single = original self-hosted experience (one operator, no auth). Multi = cloud mode (email/magic-link auth, multi-user, BTCPay subscriptions). Switching takes effect on next service restart.', default: 'single', values: { single: 'Single (self-hosted, no accounts)', multi: 'Multi (cloud, email auth + subscriptions)', }, }), }) export const enableMultiTenantMode = sdk.Action.withInput( 'enable-multi-tenant-mode', async ({ effects }) => ({ name: 'Enable Multi-Tenant Mode', description: 'Switch Recaps between single-user (self-hosted) and multi-tenant (cloud) modes. Multi mode adds email-based sign-in, per-user libraries, and BTCPay subscriptions. Configure SMTP and the public URL before enabling.', warning: 'Switching to multi mode requires StartOS SMTP to be configured and the Recaps public URL set. The service restarts on save.', allowedStatuses: 'any', group: 'Multi-Tenant', visibility: 'enabled', }), inputSpec, async ({ effects }) => { const config = await configFile.read().once() return { mode: (config?.recap_mode as 'single' | 'multi') || 'single' } }, async ({ effects, input }) => { await configFile.merge(effects, { recap_mode: input.mode }) return null }, )