Files
recap/startos/actions/setTenantDefaultCredits.ts
Keysat 0ae59f3550 Add multi-tenant cloud mode: self-serve purchase, credit metering, core-decoupling
Introduces RECAP_MODE=multi alongside single-mode self-host:
- Tenant auth + accounts (magic-link via System SMTP), per-tenant credit pool,
  anonymous trial minting with per-IP/-64 caps
- Self-serve Pro/Max purchase: inline Lightning (BTCPay) + card (Zaprite),
  prepaid 30-day periods, expiry-reminder emails
- Core-decoupling: relay owns cloud tier/expiry keyed by Recaps user-id
- SQLite (better-sqlite3) schema for multi-mode; filesystem unchanged for single
- StartOS actions/versions through 0.2.155
2026-06-13 14:25:05 -05:00

57 lines
2.0 KiB
TypeScript

import { sdk } from '../sdk'
import { configFile } from '../file-models/config.json'
const { InputSpec, Value } = sdk
// When a self-hosted Recaps is running in multi-tenant mode, the
// operator can invite family members / guests to sign up on their
// domain. New tenants start with this many credits drawn from the
// operator's relay credit pool (i.e., the operator pays for them).
//
// Default 5 is generous enough to try, tight enough that running a
// public sign-up doesn't immediately drain the operator. Set to 0 to
// disable auto-allocation (operator must explicitly grant credits to
// each tenant before they can summarize).
//
// Doesn't apply to Grant's canonical cloud Recaps — cloud users have
// their own keysat licenses + relay-side credit pools, so the relay's
// per-tier quotas handle their initial credit allowance directly.
const inputSpec = InputSpec.of({
credits: Value.number({
name: 'Default credits per new tenant',
description:
'When a new user signs up on this multi-tenant Recaps, they start with this many credits. Charged against your relay credit pool when they summarize. Set to 0 to require manual approval before any tenant can summarize.',
required: true,
default: 5,
integer: true,
min: 0,
max: 1000,
}),
})
export const setTenantDefaultCredits = sdk.Action.withInput(
'set-tenant-default-credits',
async ({ effects }) => ({
name: 'Set Default Tenant Credits',
description:
"How many credits new sign-ups get for free on your multi-tenant Recaps. Charged against your relay credit pool. Default: 5.",
warning: null,
allowedStatuses: 'any',
group: 'Multi-Tenant',
visibility: 'enabled',
}),
inputSpec,
async ({ effects }) => {
const config = await configFile.read().once()
return { credits: config?.tenant_default_credits ?? 5 }
},
async ({ effects, input }) => {
await configFile.merge(effects, { tenant_default_credits: input.credits })
return null
},
)