mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 13:59:36 +01:00
docs: add TUI implementation plan documentation
This commit is contained in:
parent
3ab2c1a57e
commit
22c007a768
1 changed files with 386 additions and 0 deletions
386
frontend/IMPLEMENTATION_PLAN.md
Normal file
386
frontend/IMPLEMENTATION_PLAN.md
Normal file
|
|
@ -0,0 +1,386 @@
|
||||||
|
# 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/types` erstellt mit OpenAPI-Generierung
|
||||||
|
- 📋 Task 3: Package `@effigenix/config` erstellen
|
||||||
|
- 📋 Task 4: Package `@effigenix/validation` erstellen
|
||||||
|
|
||||||
|
**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:**
|
||||||
|
1. Package `@effigenix/api-client` erstellen
|
||||||
|
- 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 `ErrorResponse` in `ApiError` umwandeln
|
||||||
|
|
||||||
|
2. API Resource-Module implementieren
|
||||||
|
- `auth.ts`: `login()`, `logout()`, `refresh()`
|
||||||
|
- `users.ts`: `list()`, `getById()`, `create()`, `update()`, `lock()`, `unlock()`, `assignRole()`, `removeRole()`, `changePassword()`
|
||||||
|
- `roles.ts`: `list()`
|
||||||
|
|
||||||
|
3. Custom Error Classes
|
||||||
|
- `ApiError` (code, message, status, validationErrors)
|
||||||
|
- `AuthenticationError`
|
||||||
|
- `NetworkError`
|
||||||
|
|
||||||
|
4. Unit Tests (vitest)
|
||||||
|
- Mock axios responses
|
||||||
|
- Test Interceptor-Logik (Token-Refresh-Flow)
|
||||||
|
- Test Error-Handling
|
||||||
|
|
||||||
|
**Kritische Dateien:**
|
||||||
|
- `packages/api-client/src/client.ts`
|
||||||
|
- `packages/api-client/src/interceptors/refresh-interceptor.ts`
|
||||||
|
- `packages/api-client/src/resources/auth.ts`
|
||||||
|
|
||||||
|
**Geschätzte Dauer:** 1 Woche
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 3: TUI Core 📅 GEPLANT
|
||||||
|
|
||||||
|
**Ziel:** Basis-TUI-App mit Authentication
|
||||||
|
|
||||||
|
**Aufgaben:**
|
||||||
|
1. Package `apps/cli` erstellen
|
||||||
|
- CLI Entry Point (`src/cli.ts`) mit yargs
|
||||||
|
- Subcommands: `login`, `interactive` (default)
|
||||||
|
- Ink App-Struktur (`src/App.tsx`)
|
||||||
|
- React Context für State Management
|
||||||
|
|
||||||
|
2. 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)
|
||||||
|
|
||||||
|
3. 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.tsx`
|
||||||
|
- `apps/cli/src/components/auth/LoginScreen.tsx`
|
||||||
|
- `apps/cli/src/utils/token-storage.ts`
|
||||||
|
- `apps/cli/src/state/auth-context.tsx`
|
||||||
|
|
||||||
|
**Geschätzte Dauer:** 1 Woche
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 4: User Management UI 📅 GEPLANT
|
||||||
|
|
||||||
|
**Ziel:** Vollständiges User Management Interface
|
||||||
|
|
||||||
|
**Aufgaben:**
|
||||||
|
1. **UserListScreen** - Table-View mit Navigation
|
||||||
|
2. **UserCreateScreen** - Formular mit Validation
|
||||||
|
3. **UserDetailScreen** - User-Details anzeigen
|
||||||
|
4. **ChangePasswordScreen** - Passwort ändern
|
||||||
|
|
||||||
|
**Komponenten:**
|
||||||
|
- `UserListScreen.tsx`, `UserTable.tsx`
|
||||||
|
- `UserCreateScreen.tsx`, `UserDetailScreen.tsx`
|
||||||
|
- `LoadingSpinner.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:**
|
||||||
|
1. **RoleListScreen** - Liste aller Rollen
|
||||||
|
2. **RoleAssignScreen** - Rollen zuweisen/entfernen
|
||||||
|
3. **UX Improvements**
|
||||||
|
- Loading States überall
|
||||||
|
- Success/Error Notifications
|
||||||
|
- Confirmation Dialogs
|
||||||
|
- Bessere Error Messages
|
||||||
|
- StatusBar
|
||||||
|
|
||||||
|
4. **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)
|
||||||
|
```typescript
|
||||||
|
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)
|
||||||
|
```typescript
|
||||||
|
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`**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Type-Generierung
|
||||||
|
pnpm openapi-typescript http://localhost:8080/api-docs \
|
||||||
|
-o packages/types/src/generated/api.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
**Workflow:**
|
||||||
|
1. Backend startet → OpenAPI Spec wird generiert
|
||||||
|
2. `pnpm run generate:types` läuft → TypeScript Types werden generiert
|
||||||
|
3. Handgeschriebene Wrapper-Files (`auth.ts`, `user.ts`) re-exportieren Types
|
||||||
|
4. 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
|
||||||
|
```bash
|
||||||
|
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)
|
||||||
|
```bash
|
||||||
|
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)
|
||||||
|
1. Backend starten: `cd backend && mvn spring-boot:run`
|
||||||
|
2. TUI starten: `cd frontend && pnpm run dev`
|
||||||
|
3. 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
1. ✅ ~~Monorepo initialisieren~~
|
||||||
|
2. ✅ ~~@effigenix/types Package erstellen~~
|
||||||
|
3. **@effigenix/config Package erstellen** ← NEXT
|
||||||
|
4. **@effigenix/validation Package erstellen**
|
||||||
|
5. Phase 2: API Client implementieren
|
||||||
Loading…
Add table
Add a link
Reference in a new issue