12 KiB
Implementation Plan: TypeScript TUI für Effigenix ERP
Status: Phase 1 in Arbeit (50% abgeschlossen) Erstellt: 2026-02-17 Letztes Update: 2026-02-17
Context
Das Effigenix ERP-System verfügt über ein vollständig implementiertes Backend mit User Management (Authentication, CRUD, Role Management). Um die Backend-Funktionen ausgiebig zu testen, ohne sofort eine vollständige WebUI zu entwickeln, wird zunächst eine Terminal User Interface (TUI) in TypeScript erstellt.
Ziele:
- Bequemes Testen aller Backend-Features über ein interaktives Terminal-Interface
- TypeScript-Entwicklung ermöglicht späteren Code-Sharing mit der WebUI
- Moderne, wartbare Architektur mit Fokus auf Wiederverwendbarkeit
Umfang (Erster Wurf):
- ✅ Authentication & JWT-Handling (Login, Auto-Refresh, Logout)
- ✅ User Management (Create, Read, Update, List)
- ✅ Role & Permission Management (Assign/Remove Roles, Lock/Unlock Accounts)
- ✅ Password Management
Technologie-Stack
| Kategorie | Technologie | Begründung |
|---|---|---|
| Package Manager | pnpm workspaces | Schnell, effizient, exzellente TypeScript-Unterstützung |
| UI Framework | Ink 5 (React für Terminal) | React-Komponenten, Code-Sharing mit zukünftiger WebUI |
| HTTP Client | axios | Interceptor-Support für JWT-Handling |
| Validation | Zod | Runtime-Validation + TypeScript Type Inference |
| CLI Framework | yargs | Powerful CLI arg parsing, subcommands |
| State Management | React Context + useReducer | Einfach, keine zusätzlichen Dependencies |
| Build Tool | tsup | Schneller, zero-config TypeScript bundler |
| Testing | vitest | Vite-powered, Jest-kompatibel |
Monorepo-Struktur
/home/sebi/git/effigenix/
├── backend/ # Java Backend
│ ├── src/
│ ├── pom.xml
│ └── docs/
│
└── frontend/ # TypeScript Monorepo
├── package.json # Root workspace config
├── pnpm-workspace.yaml # Workspace definition
├── tsconfig.base.json # Shared TypeScript config
├── .eslintrc.js # Linting
├── .prettierrc # Formatting
│
├── apps/
│ └── cli/ # TUI Application
│ ├── src/
│ │ ├── index.tsx # Entry point
│ │ ├── App.tsx # Root Ink component
│ │ ├── cli.ts # CLI command parser (yargs)
│ │ ├── components/ # UI components
│ │ │ ├── auth/ # LoginScreen, AuthProvider
│ │ │ ├── users/ # UserList, UserCreate, UserDetail, UserTable
│ │ │ ├── roles/ # RoleList, RoleAssign
│ │ │ ├── shared/ # Navigation, ErrorDisplay, LoadingSpinner, FormInput
│ │ │ └── layout/ # MainLayout, Header, StatusBar
│ │ ├── hooks/ # useAuth, useUsers, useRoles, useNavigation
│ │ ├── state/ # React Context (auth, navigation, app)
│ │ └── utils/ # token-storage, error-handler
│ └── package.json
│
└── packages/ # Shared Packages (wiederverwendbar für WebUI)
├── api-client/ # HTTP client für Effigenix API
│ ├── src/
│ │ ├── client.ts # Base axios client
│ │ ├── interceptors/ # auth, error, refresh interceptors
│ │ ├── resources/ # auth.ts, users.ts, roles.ts
│ │ ├── config.ts # Client configuration
│ │ └── errors.ts # Custom error classes
│ └── package.json
│
├── types/ # TypeScript interfaces/DTOs ✅ DONE
│ ├── src/
│ │ ├── generated/ # AUTO-GENERATED from OpenAPI
│ │ ├── auth.ts # LoginRequest, LoginResponse, SessionToken
│ │ ├── user.ts # User, UserDTO, CreateUserRequest, UpdateUserRequest
│ │ ├── role.ts # Role, RoleDTO, Permission, RoleName
│ │ ├── common.ts # ErrorResponse, ValidationError
│ │ └── enums.ts # UserStatus, Permission enum
│ └── package.json
│
├── validation/ # Zod schemas für Validation
│ ├── src/
│ │ ├── schemas/ # auth.ts, user.ts, password.ts
│ │ └── validators.ts # Custom validators
│ └── package.json
│
└── config/ # Shared configuration
├── src/
│ ├── api-config.ts # API base URL, timeouts
│ └── constants.ts # Shared constants
└── package.json
Package-Abhängigkeiten
apps/cli
↓
├── @effigenix/api-client
├── @effigenix/types
├── @effigenix/validation
└── @effigenix/config
@effigenix/api-client
↓
├── @effigenix/types
└── @effigenix/config
@effigenix/validation
↓
└── @effigenix/types
Implementierungsphasen
Phase 1: Foundation ⏳ IN PROGRESS (50% abgeschlossen)
Ziel: Monorepo-Setup, Shared Packages, Type Definitions
Status:
- ✅ Task 1: Monorepo initialisiert (pnpm-workspace.yaml, tsconfig.base.json, ESLint/Prettier)
- ✅ Task 2: Package
@effigenix/typeserstellt mit OpenAPI-Generierung - 📋 Task 3: Package
@effigenix/configerstellen - 📋 Task 4: Package
@effigenix/validationerstellen
Commits:
- ✅
refactor: restructure repository with separate backend and frontend directories - ✅
feat: initialize frontend monorepo with pnpm workspace and types package
Phase 2: API Client 📅 GEPLANT
Ziel: Vollständiger HTTP-Client mit JWT-Handling
Aufgaben:
-
Package
@effigenix/api-clienterstellen- Base axios client mit TypeScript
- Interceptors:
- AuthInterceptor: JWT-Token an alle Requests anhängen
- RefreshInterceptor: Bei 401-Error automatisch Token refresh via
/api/auth/refresh - ErrorInterceptor: Backend
ErrorResponseinApiErrorumwandeln
-
API Resource-Module implementieren
auth.ts:login(),logout(),refresh()users.ts:list(),getById(),create(),update(),lock(),unlock(),assignRole(),removeRole(),changePassword()roles.ts:list()
-
Custom Error Classes
ApiError(code, message, status, validationErrors)AuthenticationErrorNetworkError
-
Unit Tests (vitest)
- Mock axios responses
- Test Interceptor-Logik (Token-Refresh-Flow)
- Test Error-Handling
Kritische Dateien:
packages/api-client/src/client.tspackages/api-client/src/interceptors/refresh-interceptor.tspackages/api-client/src/resources/auth.ts
Geschätzte Dauer: 1 Woche
Phase 3: TUI Core 📅 GEPLANT
Ziel: Basis-TUI-App mit Authentication
Aufgaben:
-
Package
apps/clierstellen- CLI Entry Point (
src/cli.ts) mit yargs- Subcommands:
login,interactive(default)
- Subcommands:
- Ink App-Struktur (
src/App.tsx) - React Context für State Management
- CLI Entry Point (
-
Authentication-Flow implementieren
- LoginScreen Component (ink-text-input für Username/Password)
- JWT Storage (Filesystem:
~/.effigenix/config.json, Permissions 600) - AuthContext Provider (isAuthenticated, user, loading)
- Protected Route Wrapper (redirect zu Login wenn nicht authentifiziert)
-
Navigation implementieren
- MainMenu Component (nach Login)
- Screen Router (einfacher State-basierter Router)
- Keyboard Shortcuts (Pfeiltasten, Enter, B für Back)
Kritische Dateien:
apps/cli/src/index.tsxapps/cli/src/components/auth/LoginScreen.tsxapps/cli/src/utils/token-storage.tsapps/cli/src/state/auth-context.tsx
Geschätzte Dauer: 1 Woche
Phase 4: User Management UI 📅 GEPLANT
Ziel: Vollständiges User Management Interface
Aufgaben:
- UserListScreen - Table-View mit Navigation
- UserCreateScreen - Formular mit Validation
- UserDetailScreen - User-Details anzeigen
- ChangePasswordScreen - Passwort ändern
Komponenten:
UserListScreen.tsx,UserTable.tsxUserCreateScreen.tsx,UserDetailScreen.tsxLoadingSpinner.tsx,ErrorDisplay.tsx,FormInput.tsx- Hooks:
useUsers.ts(wrapper um API Client)
Geschätzte Dauer: 1 Woche
Phase 5: Role Management & Polish 📅 GEPLANT
Ziel: Role Management + UX-Verbesserungen
Aufgaben:
-
RoleListScreen - Liste aller Rollen
-
RoleAssignScreen - Rollen zuweisen/entfernen
-
UX Improvements
- Loading States überall
- Success/Error Notifications
- Confirmation Dialogs
- Bessere Error Messages
- StatusBar
-
Testing & Dokumentation
- Integration Tests
- E2E-Flows testen
- User-Dokumentation
- Developer Guide
Geschätzte Dauer: 1 Woche
JWT-Handling: Token-Refresh-Strategie
Speicherung
- Location:
~/.effigenix/config.json(File Permissions 600) - Struktur:
{ apiBaseUrl, auth: { accessToken, refreshToken, expiresAt } }
Proaktiver Refresh (vor Ablauf)
async getAccessToken() {
const config = await loadConfig();
const expiresAt = new Date(config.auth.expiresAt);
const timeUntilExpiry = expiresAt.getTime() - Date.now();
if (timeUntilExpiry < 5 * 60 * 1000) { // < 5 Minuten
await refreshToken();
}
return config.auth.accessToken;
}
Reaktiver Refresh (bei 401-Error)
async onError(error) {
if (error.response?.status === 401) {
const newTokens = await authApi.refresh(refreshToken);
await tokenStorage.saveTokens(newTokens);
return axios.request(error.config); // Retry original request
}
}
Type-Synchronisation Backend ↔ Frontend
Ansatz: Automatische Generierung aus OpenAPI Spec
Tool: openapi-typescript
# Type-Generierung
pnpm openapi-typescript http://localhost:8080/api-docs \
-o packages/types/src/generated/api.ts
Workflow:
- Backend startet → OpenAPI Spec wird generiert
pnpm run generate:typesläuft → TypeScript Types werden generiert- Handgeschriebene Wrapper-Files (
auth.ts,user.ts) re-exportieren Types - Build-Prozess garantiert aktuelle Types
Vorteile:
- ✅ Keine manuelle Pflege
- ✅ Immer synchron mit Backend
- ✅ Compiler-Fehler bei Breaking Changes
- ✅ Autocomplete für alle API-Strukturen
Development Workflow
Ersteinrichtung
cd /home/sebi/git/effigenix/frontend
# pnpm installieren (falls noch nicht vorhanden)
npm install -g pnpm
# Dependencies installieren
pnpm install
# Alle Packages bauen
pnpm run build
# TUI in Dev-Mode starten (Hot Reload)
pnpm run dev
Scripts (Root package.json)
pnpm run build # Build all packages
pnpm run dev # Run TUI in dev mode
pnpm test # Run all tests
pnpm run typecheck # Type check all packages
pnpm run lint # Lint code
pnpm run format # Format code
Verifikation & Testing
Manuelle Tests (E2E)
- Backend starten:
cd backend && mvn spring-boot:run - TUI starten:
cd frontend && pnpm run dev - Test-Szenarien:
- Login mit
admin/admin123 - User List anzeigen
- Neuen User erstellen
- User-Details anzeigen
- Email ändern
- Rolle zuweisen/entfernen
- User sperren/entsperren
- Passwort ändern
- Logout
- Token-Refresh testen
- Error-Handling
- Login mit
Timeline
| Phase | Dauer | Status |
|---|---|---|
| Phase 1: Foundation | 1 Woche | ⏳ 50% |
| Phase 2: API Client | 1 Woche | 📅 Geplant |
| Phase 3: TUI Core | 1 Woche | 📅 Geplant |
| Phase 4: User Management UI | 1 Woche | 📅 Geplant |
| Phase 5: Role Management & Polish | 1 Woche | 📅 Geplant |
| Gesamt | 5 Wochen | 10% abgeschlossen |
Nächste Schritte
- ✅
Monorepo initialisieren - ✅
@effigenix/types Package erstellen - @effigenix/config Package erstellen ← NEXT
- @effigenix/validation Package erstellen
- Phase 2: API Client implementieren