Completes the arcadia-admin operator surface for the integration registry and the capability/route-guard framework it depends on. - Integration registry: route + Data-group nav entry + `platform.integrations` capability; the in-app client now delegates to the shared `@crema/integration-registry-client` lib (vite alias + tsconfig); the operator Integrations page (committed earlier) is now reachable. - Capability gating: capabilities map + route-guard + jwt helpers + the apps/plan/entitlements routes and supporting tenants/session changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
114 lines
3.2 KiB
TypeScript
114 lines
3.2 KiB
TypeScript
// Arcadia tenants API helpers.
|
|
//
|
|
// Hand-rolled because /api/v1/admin/tenants isn't covered by arcadia's
|
|
// OpenAPI spec (controller hasn't been wired into OpenApiSpex yet — same
|
|
// "ok"-placeholder issue as some other admin endpoints). When the spec
|
|
// gains coverage, switch to `arcadia.typed.GET("/api/v1/admin/tenants", ...)`
|
|
// and drop these manual types.
|
|
|
|
import type { ArcadiaClient } from "@crema/arcadia-client"
|
|
|
|
export type TenantStatus = "active" | "suspended" | "deactivated" | string
|
|
|
|
export interface TenantPlan {
|
|
name: string
|
|
limits: Record<string, unknown>
|
|
}
|
|
|
|
export interface TenantBranding {
|
|
logo_url: string | null
|
|
favicon_url: string | null
|
|
primary_color: string | null
|
|
secondary_color: string | null
|
|
accent_color: string | null
|
|
custom_css: string | null
|
|
settings: Record<string, unknown>
|
|
}
|
|
|
|
export interface TenantSettings {
|
|
timezone?: string
|
|
currency?: string
|
|
[key: string]: unknown
|
|
}
|
|
|
|
export interface TenantLocalization {
|
|
locale: string
|
|
timezone: string
|
|
currency: string
|
|
settings: Record<string, unknown>
|
|
}
|
|
|
|
export interface Tenant {
|
|
id: string
|
|
slug: string
|
|
name: string
|
|
status: TenantStatus
|
|
plan: TenantPlan
|
|
branding: TenantBranding
|
|
settings: TenantSettings
|
|
localization: TenantLocalization
|
|
email_settings: Record<string, unknown>
|
|
notification_settings: Record<string, unknown>
|
|
metadata: Record<string, unknown>
|
|
inserted_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export interface TenantListParams {
|
|
q?: string
|
|
status?: TenantStatus
|
|
page?: number
|
|
per_page?: number
|
|
}
|
|
|
|
export async function listTenants(
|
|
arcadia: ArcadiaClient,
|
|
params?: TenantListParams,
|
|
): Promise<Tenant[]> {
|
|
const queryParams: Record<string, string | number | boolean | null | undefined> | undefined = params
|
|
? { q: params.q, status: params.status, page: params.page, per_page: params.per_page }
|
|
: undefined
|
|
const res = await arcadia.GET<{ data: Tenant[] }>("/api/v1/admin/tenants", { params: queryParams })
|
|
return res.data
|
|
}
|
|
|
|
export async function getTenant(arcadia: ArcadiaClient, id: string): Promise<Tenant> {
|
|
const res = await arcadia.GET<{ data: Tenant }>(`/api/v1/admin/tenants/${id}`)
|
|
return res.data
|
|
}
|
|
|
|
export async function suspendTenant(arcadia: ArcadiaClient, id: string): Promise<Tenant> {
|
|
const res = await arcadia.POST<{ data: Tenant }>(`/api/v1/admin/tenants/${id}/suspend`)
|
|
return res.data
|
|
}
|
|
|
|
export async function activateTenant(arcadia: ArcadiaClient, id: string): Promise<Tenant> {
|
|
const res = await arcadia.POST<{ data: Tenant }>(`/api/v1/admin/tenants/${id}/activate`)
|
|
return res.data
|
|
}
|
|
|
|
export async function deactivateTenant(arcadia: ArcadiaClient, id: string): Promise<Tenant> {
|
|
const res = await arcadia.POST<{ data: Tenant }>(`/api/v1/admin/tenants/${id}/deactivate`)
|
|
return res.data
|
|
}
|
|
|
|
export interface ProvisionTenantInput {
|
|
tenant: { name: string; slug: string }
|
|
admin_user: {
|
|
email: string
|
|
password: string
|
|
first_name: string
|
|
last_name: string
|
|
}
|
|
}
|
|
|
|
export async function provisionTenant(
|
|
arcadia: ArcadiaClient,
|
|
input: ProvisionTenantInput,
|
|
): Promise<Tenant> {
|
|
const res = await arcadia.POST<{ data: Tenant }>("/api/v1/admin/tenants/provision", {
|
|
body: input,
|
|
})
|
|
return res.data
|
|
}
|