mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 21:19:58 +01:00
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).
140 lines
4.4 KiB
TypeScript
140 lines
4.4 KiB
TypeScript
/**
|
||
* 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>;
|