refactor(admin): split api-client.ts (885 LOC) and endpoints.ts (1262 LOC) into focused modules
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>
This commit is contained in:
160
admin-compliance/lib/sdk/api-client-projects.ts
Normal file
160
admin-compliance/lib/sdk/api-client-projects.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* 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,
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user