diff --git a/frontend/apps/cli/src/__tests__/hooks/useRoles.test.ts b/frontend/apps/cli/src/__tests__/hooks/useRoles.test.ts
index 510d21d..53142e6 100644
--- a/frontend/apps/cli/src/__tests__/hooks/useRoles.test.ts
+++ b/frontend/apps/cli/src/__tests__/hooks/useRoles.test.ts
@@ -12,8 +12,8 @@ vi.mock('../../utils/api-client.js', () => ({
const { client } = await import('../../utils/api-client.js');
const mockRoles: RoleDTO[] = [
- { id: '1', name: 'ADMIN', permissions: [] },
- { id: '2', name: 'USER', permissions: [] },
+ { id: '1', name: 'ADMIN', permissions: [], description: 'Administrator' },
+ { id: '2', name: 'SALES_MANAGER', permissions: [], description: 'Sales Manager' },
];
describe('useRoles – api-client integration', () => {
diff --git a/frontend/apps/cli/src/components/masterdata/articles/ArticleDetailScreen.tsx b/frontend/apps/cli/src/components/masterdata/articles/ArticleDetailScreen.tsx
index 87876a1..b82149f 100644
--- a/frontend/apps/cli/src/components/masterdata/articles/ArticleDetailScreen.tsx
+++ b/frontend/apps/cli/src/components/masterdata/articles/ArticleDetailScreen.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import { Box, Text, useInput } from 'ink';
-import type { ArticleDTO, SalesUnitDTO } from '@effigenix/api-client';
+import type { ArticleDTO, SalesUnitDTO, Unit, PriceModel } from '@effigenix/api-client';
import { UNIT_LABELS, PRICE_MODEL_LABELS } from '@effigenix/api-client';
import { useNavigation } from '../../../state/navigation-context.js';
import { useArticles } from '../../../hooks/useArticles.js';
@@ -114,7 +114,7 @@ export function ArticleDetailScreen() {
setActionLoading(false);
if (updated) {
setArticle(updated);
- setSuccessMessage(`Verkaufseinheit "${UNIT_LABELS[su.unit]}" entfernt.`);
+ setSuccessMessage(`Verkaufseinheit "${UNIT_LABELS[su.unit as Unit]}" entfernt.`);
}
}, [article, removeSalesUnit]);
@@ -150,8 +150,8 @@ export function ArticleDetailScreen() {
{article.salesUnits.map((su) => (
•
- {UNIT_LABELS[su.unit]}
- ({PRICE_MODEL_LABELS[su.priceModel]})
+ {UNIT_LABELS[su.unit as Unit]}
+ ({PRICE_MODEL_LABELS[su.priceModel as PriceModel]})
{su.price.toFixed(2)} €
))}
@@ -181,7 +181,7 @@ export function ArticleDetailScreen() {
{i === selectedSuIndex ? '▶ ' : ' '}
- {UNIT_LABELS[su.unit]} – {su.price.toFixed(2)} €
+ {UNIT_LABELS[su.unit as Unit]} – {su.price.toFixed(2)} €
))}
diff --git a/frontend/apps/cli/src/components/masterdata/customers/CustomerDetailScreen.tsx b/frontend/apps/cli/src/components/masterdata/customers/CustomerDetailScreen.tsx
index 8e35838..ad26fe1 100644
--- a/frontend/apps/cli/src/components/masterdata/customers/CustomerDetailScreen.tsx
+++ b/frontend/apps/cli/src/components/masterdata/customers/CustomerDetailScreen.tsx
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import { Box, Text, useInput } from 'ink';
-import type { CustomerDTO } from '@effigenix/api-client';
+import type { CustomerDTO, CustomerPreference } from '@effigenix/api-client';
import { CUSTOMER_PREFERENCE_LABELS } from '@effigenix/api-client';
import { useNavigation } from '../../../state/navigation-context.js';
import { useCustomers } from '../../../hooks/useCustomers.js';
@@ -137,6 +137,8 @@ export function CustomerDetailScreen() {
if (!customer) return Kunde nicht gefunden.;
const statusColor = customer.status === 'ACTIVE' ? 'green' : 'red';
+ const ba = customer.billingAddress;
+ const billingText = ba ? `${ba.street} ${ba.houseNumber}, ${ba.postalCode} ${ba.city}, ${ba.country}` : '–';
return (
@@ -164,7 +166,7 @@ export function CustomerDetailScreen() {
)}
Rechnungsadresse:
- {`${customer.billingAddress.street} ${customer.billingAddress.houseNumber}, ${customer.billingAddress.postalCode} ${customer.billingAddress.city}, ${customer.billingAddress.country}`}
+ {billingText}
{customer.paymentTerms && (
@@ -175,7 +177,7 @@ export function CustomerDetailScreen() {
{customer.preferences.length > 0 && (
Präferenzen:
- {customer.preferences.map((p) => CUSTOMER_PREFERENCE_LABELS[p]).join(', ')}
+ {customer.preferences.map((p) => CUSTOMER_PREFERENCE_LABELS[p as CustomerPreference]).join(', ')}
)}
{customer.deliveryAddresses.length > 0 && (
@@ -185,7 +187,7 @@ export function CustomerDetailScreen() {
•
{addr.label}:
- {`${addr.address.street} ${addr.address.houseNumber}, ${addr.address.city}, ${addr.address.country}`}
+ {addr.address ? `${addr.address.street} ${addr.address.houseNumber}, ${addr.address.city}, ${addr.address.country}` : '–'}
))}
@@ -217,7 +219,7 @@ export function CustomerDetailScreen() {
{customer.deliveryAddresses.map((addr, i) => (
- {i === selectedAddrIndex ? '▶ ' : ' '}{addr.label}: {addr.address.city}
+ {i === selectedAddrIndex ? '▶ ' : ' '}{addr.label}: {addr.address?.city ?? '–'}
))}
diff --git a/frontend/apps/cli/src/components/masterdata/customers/SetPreferencesScreen.tsx b/frontend/apps/cli/src/components/masterdata/customers/SetPreferencesScreen.tsx
index aa40293..17ad70f 100644
--- a/frontend/apps/cli/src/components/masterdata/customers/SetPreferencesScreen.tsx
+++ b/frontend/apps/cli/src/components/masterdata/customers/SetPreferencesScreen.tsx
@@ -28,7 +28,7 @@ export function SetPreferencesScreen() {
useEffect(() => {
client.customers.getById(customerId)
- .then((c) => { setChecked(new Set(c.preferences)); setInitLoading(false); })
+ .then((c) => { setChecked(new Set(c.preferences as CustomerPreference[])); setInitLoading(false); })
.catch((err: unknown) => { setInitError(errorMessage(err)); setInitLoading(false); });
}, [customerId]);
diff --git a/frontend/apps/cli/src/components/masterdata/suppliers/SupplierListScreen.tsx b/frontend/apps/cli/src/components/masterdata/suppliers/SupplierListScreen.tsx
index a2d202b..383a5ce 100644
--- a/frontend/apps/cli/src/components/masterdata/suppliers/SupplierListScreen.tsx
+++ b/frontend/apps/cli/src/components/masterdata/suppliers/SupplierListScreen.tsx
@@ -8,7 +8,7 @@ import type { SupplierStatus } from '@effigenix/api-client';
type Filter = 'ALL' | SupplierStatus;
-function avgRating(rating: { qualityScore: number; deliveryScore: number; priceScore: number } | null): string {
+function avgRating(rating: { qualityScore: number; deliveryScore: number; priceScore: number } | null | undefined): string {
if (!rating) return '–';
const avg = (rating.qualityScore + rating.deliveryScore + rating.priceScore) / 3;
return avg.toFixed(1);
diff --git a/frontend/apps/cli/src/components/production/ProductionOrderCreateScreen.tsx b/frontend/apps/cli/src/components/production/ProductionOrderCreateScreen.tsx
index 69a9786..8e01caf 100644
--- a/frontend/apps/cli/src/components/production/ProductionOrderCreateScreen.tsx
+++ b/frontend/apps/cli/src/components/production/ProductionOrderCreateScreen.tsx
@@ -82,8 +82,9 @@ export function ProductionOrderCreateScreen() {
if (success) {
if (_input.toLowerCase() === 'f' && productionOrder?.id) {
+ const orderId = productionOrder.id;
void (async () => {
- const result = await releaseProductionOrder(productionOrder.id);
+ const result = await releaseProductionOrder(orderId);
if (result) setReleased(true);
})();
return;
diff --git a/frontend/apps/cli/src/hooks/useCategories.ts b/frontend/apps/cli/src/hooks/useCategories.ts
index 970e645..fc6e759 100644
--- a/frontend/apps/cli/src/hooks/useCategories.ts
+++ b/frontend/apps/cli/src/hooks/useCategories.ts
@@ -32,8 +32,9 @@ export function useCategories() {
const createCategory = useCallback(async (name: string, description?: string) => {
setState((s) => ({ ...s, loading: true, error: null }));
try {
- const req = description ? { name, description } : { name };
- const cat = await client.categories.create(req);
+ const req: Record = { name };
+ if (description) req.description = description;
+ const cat = await client.categories.create(req as { name: string; description?: string });
setState((s) => ({ categories: [...s.categories, cat], loading: false, error: null }));
return cat;
} catch (err) {
@@ -45,7 +46,9 @@ export function useCategories() {
const updateCategory = useCallback(
async (id: string, name: string, description: string | null) => {
try {
- const updated = await client.categories.update(id, { name, description });
+ const req: Record = { name };
+ if (description !== null) req.description = description;
+ const updated = await client.categories.update(id, req as { name: string; description?: string });
setState((s) => ({
...s,
categories: s.categories.map((c) => (c.id === id ? updated : c)),
diff --git a/frontend/apps/cli/src/hooks/useUsers.ts b/frontend/apps/cli/src/hooks/useUsers.ts
index 3abc3d9..69403e0 100644
--- a/frontend/apps/cli/src/hooks/useUsers.ts
+++ b/frontend/apps/cli/src/hooks/useUsers.ts
@@ -1,7 +1,9 @@
import { useState, useCallback } from 'react';
-import type { UserDTO } from '@effigenix/api-client';
+import type { UserDTO, CreateUserRequest } from '@effigenix/api-client';
import { client } from '../utils/api-client.js';
+type RoleName = CreateUserRequest['roleNames'][number];
+
interface UsersState {
users: UserDTO[];
loading: boolean;
@@ -37,7 +39,7 @@ export function useUsers() {
username,
email,
password,
- roleNames: roleName ? [roleName] : [],
+ roleNames: roleName ? [roleName as RoleName] : [],
});
setState((s) => ({ users: [...s.users, user], loading: false, error: null }));
return user;
@@ -79,7 +81,7 @@ export function useUsers() {
const assignRole = useCallback(async (id: string, roleName: string) => {
try {
- const user = await client.users.assignRole(id, { roleName });
+ const user = await client.users.assignRole(id, { roleName: roleName as RoleName });
setState((s) => ({
...s,
users: s.users.map((u) => (u.id === id ? user : u)),
diff --git a/frontend/packages/api-client/src/resources/roles.ts b/frontend/packages/api-client/src/resources/roles.ts
index 99045a9..4ce7112 100644
--- a/frontend/packages/api-client/src/resources/roles.ts
+++ b/frontend/packages/api-client/src/resources/roles.ts
@@ -3,13 +3,10 @@
*/
import type { AxiosInstance } from 'axios';
+import type { RoleDTO } from '@effigenix/types';
import { API_PATHS } from '@effigenix/config';
-export interface RoleDTO {
- id: string;
- name: string;
- permissions: string[];
-}
+export type { RoleDTO };
export function createRolesResource(client: AxiosInstance) {
return {