frontend_nyla/src/api/mandateApi.ts

186 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ApiRequestOptions } from '../hooks/useApi';
// ============================================================================
// TYPES & INTERFACES
// ============================================================================
/**
* Mandate (Mandant) — represents one tenant in PowerOn PORTA.
*
* Field semantics (must stay in sync with the backend `Mandate` Pydantic model):
* - `id` — UUID, immutable.
* - `name` — Kurzzeichen / slug. Globally unique, lowercase [a-z0-9] with
* hyphen-separated segments (length 232). Used for audit/tracking
* and stable references. Only PlatformAdmin can change it after
* creation.
* - `label` — Voller Name. Mandatory, human-readable display name shown in the
* UI. Freely changeable by a Mandate-Admin.
*/
export interface Mandate {
id: string;
name: string;
label: string;
enabled?: boolean;
isSystem?: boolean;
deletedAt?: number | null;
[key: string]: any; // Allow additional properties from backend
}
/** Payload for creating a mandate. `label` is required, `name` is optional. */
export interface MandateCreateData {
label: string;
name?: string;
enabled?: boolean;
[key: string]: any;
}
/**
* Payload for updating a mandate. Only PlatformAdmin may change `name`;
* Mandate-Admin can update `label` and other UI fields.
*/
export type MandateUpdateData = Partial<Omit<Mandate, 'id'>>;
export interface PaginationParams {
page?: number;
pageSize?: number;
sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
filters?: Record<string, any>;
search?: string;
viewKey?: string;
}
export interface PaginatedResponse<T> {
items: T[];
pagination?: {
currentPage: number;
pageSize: number;
totalItems: number;
totalPages: number;
};
}
// Type for the request function passed to API functions
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;
// ============================================================================
// API REQUEST FUNCTIONS
// ============================================================================
/**
* Fetch list of mandates with optional pagination
* Endpoint: GET /api/mandates/
*/
export async function fetchMandates(
request: ApiRequestFunction,
params?: PaginationParams
): Promise<PaginatedResponse<Mandate> | Mandate[]> {
const requestParams: any = {};
// Build pagination object if provided
if (params) {
const paginationObj: any = {};
if (params.page !== undefined) paginationObj.page = params.page;
if (params.pageSize !== undefined) paginationObj.pageSize = params.pageSize;
if (params.sort) paginationObj.sort = params.sort;
if (params.filters) paginationObj.filters = params.filters;
if (params.search) paginationObj.search = params.search;
if (params.viewKey) paginationObj.viewKey = params.viewKey;
if (Object.keys(paginationObj).length > 0) {
requestParams.pagination = JSON.stringify(paginationObj);
}
}
const data = await request({
url: '/api/mandates/',
method: 'get',
params: requestParams
});
return data;
}
/**
* Fetch a single mandate by ID
* Endpoint: GET /api/mandates/{mandateId}
*/
export async function fetchMandateById(
request: ApiRequestFunction,
mandateId: string
): Promise<Mandate | null> {
try {
const data = await request({
url: `/api/mandates/${mandateId}`,
method: 'get'
});
return data || null;
} catch (error: any) {
console.error('Error fetching mandate by ID:', error);
return null;
}
}
/**
* Update a mandate
* Endpoint: PUT /api/mandates/{mandateId}
*/
export async function updateMandate(
request: ApiRequestFunction,
mandateId: string,
updateData: MandateUpdateData
): Promise<Mandate> {
return await request({
url: `/api/mandates/${mandateId}`,
method: 'put',
data: updateData
});
}
/**
* Create a new mandate
* Endpoint: POST /api/mandates/
*/
export async function createMandate(
request: ApiRequestFunction,
mandateData: MandateCreateData | Partial<Mandate>
): Promise<Mandate> {
return await request({
url: '/api/mandates/',
method: 'post',
data: mandateData
});
}
/**
* Soft-delete a mandate (sets enabled=false, 30-day retention)
* Endpoint: DELETE /api/mandates/{mandateId}
*/
export async function deleteMandate(
request: ApiRequestFunction,
mandateId: string
): Promise<void> {
await request({
url: `/api/mandates/${mandateId}`,
method: 'delete'
});
}
/**
* Hard-delete a mandate with full cascade (irreversible)
* Endpoint: DELETE /api/mandates/{mandateId}?force=true
*/
export async function hardDeleteMandate(
request: ApiRequestFunction,
mandateId: string,
confirmName: string
): Promise<void> {
await request({
url: `/api/mandates/${mandateId}`,
method: 'delete',
params: { force: true },
additionalConfig: {
headers: { 'X-Confirm-Name': confirmName }
}
});
}