| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { API_V1, CREDENTIALS } from "../apiContract"; |
|
|
| export type ApiResult<T> = { ok: true; data: T } | { ok: false; status: number; message: string }; |
|
|
| async function call<T>(path: string): Promise<ApiResult<T>> { |
| try { |
| const res = await fetch(`${API_V1}/platform-admin${path}`, { credentials: CREDENTIALS }); |
| let body: unknown = null; |
| try { |
| body = await res.json(); |
| } catch { |
| |
| } |
| if (!res.ok) { |
| const err = (body as { error?: { message?: string } } | null)?.error; |
| const message = |
| res.status >= 500 |
| ? "Something went wrong on our side. Try again in a moment." |
| : err?.message || |
| (res.status === 403 |
| ? "This surface is not available to your account." |
| : "That could not be loaded."); |
| return { ok: false, status: res.status, message }; |
| } |
| return { ok: true, data: body as T }; |
| } catch { |
| return { ok: false, status: 0, message: "The server could not be reached." }; |
| } |
| } |
|
|
| |
| export interface TenantRow { |
| slug: string; |
| name: string; |
| |
| source: string; |
| status: string; |
| domains: string[]; |
| modules: string[] | "all"; |
| |
| storeRepo: string; |
| storePrefix: string; |
| error: string; |
| users: number; |
| admins: number; |
| databases: number | null; |
| rows: number | null; |
| connectors: number | null; |
| connectorsPaused?: number | null; |
| automations: number | null; |
| automationsEnabled?: number | null; |
| keychainLocked?: boolean | null; |
| errors?: string[]; |
| } |
|
|
| export interface Overview { |
| tenants: TenantRow[]; |
| totals: { |
| tenants: number; |
| users: number; |
| orphanUsers: number; |
| databases: number; |
| rows: number; |
| automations: number; |
| unknownTenants: number; |
| }; |
| storeAvailable: boolean; |
| generatedAt: string; |
| tookMs: number; |
| } |
|
|
| export interface PlatformUser { |
| username: string; |
| name: string; |
| email: string; |
| tenant: string; |
| role: string; |
| active: boolean; |
| |
| lastLogin: string; |
| lastActive: string; |
| platformAdmin: boolean; |
| } |
|
|
| export interface DatabaseRow { |
| tenant: string; |
| key: string; |
| label: string; |
| source: string; |
| createdBy: string; |
| created: string; |
| fields: number; |
| rowCount: number; |
| } |
|
|
| export interface ConnectorRow { |
| tenant: string; |
| key: string; |
| label: string; |
| type: string; |
| source: string; |
| active: boolean; |
| paused: boolean; |
| } |
|
|
| export interface AutomationRow { |
| tenant: string; |
| id: string; |
| name: string; |
| kind: string; |
| enabled: boolean; |
| cron: string; |
| |
| runsPerDay: number | null; |
| state: string; |
| lastRunAt: string; |
| lastSummary: string; |
| runsRetained: number; |
| failedRetained: number; |
| createdBy: string; |
| created: string; |
| } |
|
|
| export interface FleetCost { |
| cadence: string; |
| invocationsPerMonth: number; |
| freeRequestsPct: number; |
| freeSchedulerPct: number; |
| lambdaMb: number; |
| usd: number; |
| fleetRunsPerDay: number; |
| unknownCadence: number; |
| basis: string; |
| } |
|
|
| export interface AwsReport { |
| available: boolean; |
| text: string; |
| note: string; |
| } |
|
|
| export function getOverview(): Promise<ApiResult<Overview>> { |
| return call<Overview>("/overview"); |
| } |
|
|
| |
| const q = (tenant?: string) => (tenant ? `?tenant=${encodeURIComponent(tenant)}` : ""); |
|
|
| export function getUsers( |
| tenant?: string |
| ): Promise<ApiResult<{ users: PlatformUser[]; count: number; stampsNote: string }>> { |
| return call(`/users${q(tenant)}`); |
| } |
|
|
| export function getDatabases( |
| tenant?: string |
| ): Promise< |
| ApiResult<{ |
| databases: DatabaseRow[]; |
| count: number; |
| rows: number; |
| errors: Record<string, string>; |
| }> |
| > { |
| return call(`/databases${q(tenant)}`); |
| } |
|
|
| export function getConnectors( |
| tenant?: string |
| ): Promise< |
| ApiResult<{ |
| connectors: ConnectorRow[]; |
| count: number; |
| keychainLocked: Record<string, boolean>; |
| errors: Record<string, string>; |
| note: string; |
| }> |
| > { |
| return call(`/connectors${q(tenant)}`); |
| } |
|
|
| export function getAutomations( |
| tenant?: string |
| ): Promise< |
| ApiResult<{ |
| automations: AutomationRow[]; |
| count: number; |
| enabled: number; |
| historyRetained: number; |
| cost: FleetCost; |
| errors: Record<string, string>; |
| tickEnabled: boolean; |
| }> |
| > { |
| return call(`/automations${q(tenant)}`); |
| } |
|
|
| export function getAws(days = 7): Promise<ApiResult<{ days: number; report: AwsReport }>> { |
| return call(`/aws?days=${encodeURIComponent(String(days))}`); |
| } |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| export interface ReleaseEnv { |
| env: string; |
| space: string; |
| |
| version: string | null; |
| note: string | null; |
| |
| stage: string | null; |
| } |
|
|
| export interface ReleaseTag { |
| version: string; |
| sha: string; |
| date: string; |
| subject: string; |
| } |
|
|
| export interface ReleasesPayload { |
| |
| here: string; |
| environments: ReleaseEnv[]; |
| releases: ReleaseTag[]; |
| |
| promote: string; |
| } |
|
|
| export function getReleases(): Promise<ApiResult<ReleasesPayload>> { |
| return call("/releases"); |
| } |
|
|