api-client.ts is now a thin delegating class (263 LOC) backed by: - api-client-types.ts (84) — shared types, config, FetchContext - api-client-state.ts (120) — state CRUD + export - api-client-projects.ts (160) — project management - api-client-wiki.ts (116) — wiki knowledge base - api-client-operations.ts (299) — checkpoints, flow, modules, UCCA, import, screening endpoints.ts is now a barrel (25 LOC) aggregating the 4 existing domain files (endpoints-python-core, endpoints-python-gdpr, endpoints-python-ops, endpoints-go). All files stay under the 500-line hard cap. Build verified with `npx next build`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
161 lines
3.8 KiB
TypeScript
161 lines
3.8 KiB
TypeScript
/**
|
|
* SDK API Client — Project management methods.
|
|
* (listProjects, createProject, updateProject, getProject,
|
|
* archiveProject, restoreProject, permanentlyDeleteProject)
|
|
*/
|
|
|
|
import { FetchContext } from './api-client-types'
|
|
import { ProjectInfo } from './types'
|
|
|
|
/**
|
|
* List all projects for the current tenant
|
|
*/
|
|
export async function listProjects(
|
|
ctx: FetchContext,
|
|
includeArchived = true
|
|
): Promise<{ projects: ProjectInfo[]; total: number }> {
|
|
const response = await ctx.fetchWithRetry<{ projects: ProjectInfo[]; total: number }>(
|
|
`${ctx.baseUrl}/projects?tenant_id=${encodeURIComponent(ctx.tenantId)}&include_archived=${includeArchived}`,
|
|
{
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': ctx.tenantId,
|
|
},
|
|
}
|
|
)
|
|
return response
|
|
}
|
|
|
|
/**
|
|
* Create a new project
|
|
*/
|
|
export async function createProject(
|
|
ctx: FetchContext,
|
|
data: {
|
|
name: string
|
|
description?: string
|
|
customer_type?: string
|
|
copy_from_project_id?: string
|
|
}
|
|
): Promise<ProjectInfo> {
|
|
const response = await ctx.fetchWithRetry<ProjectInfo>(
|
|
`${ctx.baseUrl}/projects?tenant_id=${encodeURIComponent(ctx.tenantId)}`,
|
|
{
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': ctx.tenantId,
|
|
},
|
|
body: JSON.stringify({
|
|
...data,
|
|
tenant_id: ctx.tenantId,
|
|
}),
|
|
}
|
|
)
|
|
return response
|
|
}
|
|
|
|
/**
|
|
* Update an existing project
|
|
*/
|
|
export async function updateProject(
|
|
ctx: FetchContext,
|
|
projectId: string,
|
|
data: { name?: string; description?: string }
|
|
): Promise<ProjectInfo> {
|
|
const response = await ctx.fetchWithRetry<ProjectInfo>(
|
|
`${ctx.baseUrl}/projects/${projectId}?tenant_id=${encodeURIComponent(ctx.tenantId)}`,
|
|
{
|
|
method: 'PATCH',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': ctx.tenantId,
|
|
},
|
|
body: JSON.stringify({
|
|
...data,
|
|
tenant_id: ctx.tenantId,
|
|
}),
|
|
}
|
|
)
|
|
return response
|
|
}
|
|
|
|
/**
|
|
* Get a single project by ID
|
|
*/
|
|
export async function getProject(
|
|
ctx: FetchContext,
|
|
projectId: string
|
|
): Promise<ProjectInfo> {
|
|
const response = await ctx.fetchWithRetry<ProjectInfo>(
|
|
`${ctx.baseUrl}/projects/${projectId}?tenant_id=${encodeURIComponent(ctx.tenantId)}`,
|
|
{
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': ctx.tenantId,
|
|
},
|
|
}
|
|
)
|
|
return response
|
|
}
|
|
|
|
/**
|
|
* Archive (soft-delete) a project
|
|
*/
|
|
export async function archiveProject(
|
|
ctx: FetchContext,
|
|
projectId: string
|
|
): Promise<void> {
|
|
await ctx.fetchWithRetry<{ success: boolean }>(
|
|
`${ctx.baseUrl}/projects/${projectId}?tenant_id=${encodeURIComponent(ctx.tenantId)}`,
|
|
{
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': ctx.tenantId,
|
|
},
|
|
}
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Restore an archived project
|
|
*/
|
|
export async function restoreProject(
|
|
ctx: FetchContext,
|
|
projectId: string
|
|
): Promise<ProjectInfo> {
|
|
const response = await ctx.fetchWithRetry<ProjectInfo>(
|
|
`${ctx.baseUrl}/projects/${projectId}/restore?tenant_id=${encodeURIComponent(ctx.tenantId)}`,
|
|
{
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': ctx.tenantId,
|
|
},
|
|
}
|
|
)
|
|
return response
|
|
}
|
|
|
|
/**
|
|
* Permanently delete a project and all data
|
|
*/
|
|
export async function permanentlyDeleteProject(
|
|
ctx: FetchContext,
|
|
projectId: string
|
|
): Promise<void> {
|
|
await ctx.fetchWithRetry<{ success: boolean }>(
|
|
`${ctx.baseUrl}/projects/${projectId}/permanent?tenant_id=${encodeURIComponent(ctx.tenantId)}`,
|
|
{
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Tenant-ID': ctx.tenantId,
|
|
},
|
|
}
|
|
)
|
|
}
|