/** * Tenant API Methods * * HTTP client methods for tenant CRUD operations. * All methods accept/return domain objects - schemas are handled internally by mappers. * * @layer Infrastructure - API Client */ import { TENANTS_CREATE, TENANTS_LIST, TENANTS_GET, } from "@archer/api-interface/endpoints/customer-api"; import type { ListTenantsRequest } from '@archer/api-interface'; import { ApiClient } from '../../ApiClient'; import { Tenant } from '@/domain/entities/Tenant'; import type { PaginationMeta } from '../shared/types'; import { TenantRequestMapper } from './mappers/TenantRequestMapper'; import { TenantResponseMapper } from './mappers/TenantResponseMapper'; /** * Tenant API * * Provides tenant CRUD operations with domain-driven interface. * UI layer works with Tenant domain objects, API client handles schema mapping internally. */ export class TenantsApi { constructor(private client: ApiClient) {} /** * Creates a new tenant * * @param companyId - Company ID to create tenant under * @param tenant - Tenant domain object * @returns Created Tenant domain entity * @throws ApiError on failure */ async createTenant(companyId: string, tenant: Tenant): Promise<{ tenant: Tenant; rawResponse: any }> { // Map domain → request schema (internal) const requestDto = TenantRequestMapper.toCreateRequest(tenant); // Replace :companyId in path const path = TENANTS_CREATE.path.replace(':companyId', companyId); // HTTP call const responseData = await this.client.post(path, requestDto); // Map response schema → domain (internal) return { tenant: TenantResponseMapper.toTenant(responseData), rawResponse: responseData }; } /** * Lists tenants for a company with pagination * * @param companyId - Company ID to list tenants for * @param params - Optional pagination and filter params * @returns Object with tenants array and pagination metadata * @throws ApiError on failure */ async listTenants( companyId: string, params?: Partial ): Promise<{ tenants: Tenant[]; pagination: PaginationMeta }> { // Replace :companyId in path const path = TENANTS_LIST.path.replace(':companyId', companyId); // HTTP call with query params const responseData = await this.client.get(path, { params }); // Map response schema → domain (internal) return TenantResponseMapper.toTenantList(responseData); } /** * Gets a single tenant by ID * * @param id - Tenant ID * @returns Tenant domain entity * @throws ApiError on failure (404 if not found) */ async getTenant(id: string): Promise { // Replace :id in path const path = TENANTS_GET.path.replace(':id', id); // HTTP call const responseData = await this.client.get(path); // Map response schema → domain (internal) return TenantResponseMapper.toTenant(responseData); } } /** * Factory function to create TenantsApi instance * * @param client - ApiClient instance * @returns TenantsApi instance */ export function createTenantsApi(client: ApiClient): TenantsApi { return new TenantsApi(client); } // Import the default API client for the singleton import { apiClient } from '../../ApiClient'; /** * Default TenantsApi singleton instance * * Uses the shared apiClient with auth token management. */ export const tenantsApi = new TenantsApi(apiClient);