1
0
Fork 0
mirror of https://github.com/s-frick/effigenix.git synced 2026-03-28 21:19:58 +01:00
effigenix/frontend/packages/api-client/src/resources/customers.ts
Sebastian Frick c26d72fbe7 feat: TUI-Screens für Inventar und Produktion + API-Client Typ-Migration
Neue TUI-Features:
- Inventar: Lageorte auflisten, anlegen, bearbeiten, (de-)aktivieren
- Produktion: Rezepte auflisten, anlegen, Detail-Ansicht
- Navigation erweitert (Hauptmenü, Routing)

API-Client auf generierte OpenAPI-Typen umgestellt:
- 6 neue Alias-Dateien in @effigenix/types (supplier, category, article,
  customer, inventory, production)
- api-client Re-Exports direkt von @effigenix/types statt via Resources
- Backend: @Schema(requiredProperties) auf 16 Response-Records
- Backend: OpenApiCustomizer für application-layer DTOs (UserDTO, RoleDTO)

Hinweis: Backend-Endpoints für GET /api/recipes und
GET /api/inventory/storage-locations/{id} fehlen noch (separate Issues).
2026-02-19 13:54:29 +01:00

140 lines
4.4 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.

/**
* Customers resource Real HTTP implementation.
* Endpoints: GET/POST /api/customers, GET/PUT /api/customers/{id},
* POST /api/customers/{id}/activate|deactivate,
* POST /api/customers/{id}/delivery-addresses,
* DELETE /api/customers/{id}/delivery-addresses/{label},
* PUT /api/customers/{id}/frame-contract,
* DELETE /api/customers/{id}/frame-contract,
* PUT /api/customers/{id}/preferences
*
* DELETE delivery-addresses/{label} and DELETE frame-contract return 204 → re-fetch.
*/
import type { AxiosInstance } from 'axios';
import type {
CustomerDTO,
DeliveryAddressDTO,
FrameContractDTO,
ContractLineItemDTO,
CreateCustomerRequest,
UpdateCustomerRequest,
AddDeliveryAddressRequest,
SetFrameContractRequest,
} from '@effigenix/types';
export type CustomerType = 'B2B' | 'B2C';
export type CustomerStatus = 'ACTIVE' | 'INACTIVE';
export type CustomerPreference =
| 'BIO'
| 'REGIONAL'
| 'TIERWOHL'
| 'HALAL'
| 'KOSHER'
| 'GLUTENFREI'
| 'LAKTOSEFREI';
export type DeliveryRhythm = 'DAILY' | 'WEEKLY' | 'BIWEEKLY' | 'MONTHLY' | 'ON_DEMAND';
export const CUSTOMER_PREFERENCE_LABELS: Record<CustomerPreference, string> = {
BIO: 'Bio',
REGIONAL: 'Regional',
TIERWOHL: 'Tierwohl',
HALAL: 'Halal',
KOSHER: 'Koscher',
GLUTENFREI: 'Glutenfrei',
LAKTOSEFREI: 'Laktosefrei',
};
export const DELIVERY_RHYTHM_LABELS: Record<DeliveryRhythm, string> = {
DAILY: 'Täglich',
WEEKLY: 'Wöchentlich',
BIWEEKLY: 'Zweiwöchentlich',
MONTHLY: 'Monatlich',
ON_DEMAND: 'Nach Bedarf',
};
export type {
CustomerDTO,
DeliveryAddressDTO,
FrameContractDTO,
ContractLineItemDTO,
CreateCustomerRequest,
UpdateCustomerRequest,
AddDeliveryAddressRequest,
SetFrameContractRequest,
};
// ── Resource factory ─────────────────────────────────────────────────────────
export function createCustomersResource(client: AxiosInstance) {
return {
async list(): Promise<CustomerDTO[]> {
const res = await client.get<CustomerDTO[]>('/api/customers');
return res.data;
},
async getById(id: string): Promise<CustomerDTO> {
const res = await client.get<CustomerDTO>(`/api/customers/${id}`);
return res.data;
},
async create(request: CreateCustomerRequest): Promise<CustomerDTO> {
const res = await client.post<CustomerDTO>('/api/customers', request);
return res.data;
},
async update(id: string, request: UpdateCustomerRequest): Promise<CustomerDTO> {
const res = await client.put<CustomerDTO>(`/api/customers/${id}`, request);
return res.data;
},
async activate(id: string): Promise<CustomerDTO> {
const res = await client.post<CustomerDTO>(`/api/customers/${id}/activate`);
return res.data;
},
async deactivate(id: string): Promise<CustomerDTO> {
const res = await client.post<CustomerDTO>(`/api/customers/${id}/deactivate`);
return res.data;
},
async addDeliveryAddress(id: string, request: AddDeliveryAddressRequest): Promise<CustomerDTO> {
const res = await client.post<CustomerDTO>(
`/api/customers/${id}/delivery-addresses`,
request,
);
return res.data;
},
// Returns 204 No Content → re-fetch customer
async removeDeliveryAddress(id: string, label: string): Promise<CustomerDTO> {
await client.delete(`/api/customers/${id}/delivery-addresses/${encodeURIComponent(label)}`);
const res = await client.get<CustomerDTO>(`/api/customers/${id}`);
return res.data;
},
async setFrameContract(id: string, request: SetFrameContractRequest): Promise<CustomerDTO> {
const res = await client.put<CustomerDTO>(
`/api/customers/${id}/frame-contract`,
request,
);
return res.data;
},
// Returns 204 No Content → re-fetch customer
async removeFrameContract(id: string): Promise<CustomerDTO> {
await client.delete(`/api/customers/${id}/frame-contract`);
const res = await client.get<CustomerDTO>(`/api/customers/${id}`);
return res.data;
},
async setPreferences(id: string, preferences: CustomerPreference[]): Promise<CustomerDTO> {
const res = await client.put<CustomerDTO>(`/api/customers/${id}/preferences`, {
preferences,
});
return res.data;
},
};
}
export type CustomersResource = ReturnType<typeof createCustomersResource>;