chore: full technical rename planarchy → capakraken
Complete rename of all technical identifiers across the codebase: Package names (11 packages): - @planarchy/* → @capakraken/* in all package.json, tsconfig, imports Import statements: 277 files, 548 occurrences replaced Database & Docker: - PostgreSQL user/db: planarchy → capakraken - Docker volumes: planarchy_pgdata → capakraken_pgdata - Connection strings updated in docker-compose, .env, CI CI/CD: - GitHub Actions workflow: all filter commands updated - Test database credentials updated Infrastructure: - Redis channel: planarchy:sse → capakraken:sse - Logger service name: planarchy-api → capakraken-api - Anonymization seed updated - Start/stop/restart scripts updated Test data: - Seed emails: @planarchy.dev → @capakraken.dev - E2E test credentials: all 11 spec files updated - Email defaults: @planarchy.app → @capakraken.app - localStorage keys: planarchy_* → capakraken_* Documentation: 30+ .md files updated Verification: - pnpm install: workspace resolution works - TypeScript: only pre-existing TS2589 (no new errors) - Engine: 310/310 tests pass - Staffing: 37/37 tests pass Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -1,177 +1,237 @@
|
||||
# Nearshore-Ratio Indikator — Plan
|
||||
# Technischer Rename: planarchy → capakraken — Migrationsplan
|
||||
|
||||
## Anforderungsanalyse
|
||||
## Uebersicht
|
||||
|
||||
**Was:** Ein Nearshore/Offshore-Ratio Indikator pro Projekt, der zeigt wieviel % der gebuchten Ressourcen Standort Deutschland vs. andere Standorte haben.
|
||||
|
||||
**Kernkonzept:**
|
||||
- **Onshore** = Resource hat `countryId` → Country mit Code "DE" (Deutschland)
|
||||
- **Offshore/Nearshore** = Resource hat `countryId` → Country mit Code != "DE" (oder kein Country gesetzt)
|
||||
- **Shoring-Ratio** = (Offshore-Stunden / Gesamt-Stunden) * 100
|
||||
- **Threshold** = Default 55%, pro Projekt aenderbar
|
||||
- **Anzeige** = Farbiger Indikator (gruen < Threshold, rot >= Threshold)
|
||||
|
||||
**Datenquelle:** Assignments eines Projekts → Resource.countryId → Country.code
|
||||
| Kategorie | Dateien | Vorkommen | Aufwand | Risiko |
|
||||
|-----------|---------|-----------|---------|--------|
|
||||
| **A: Package-Namen & Imports** | 277 | 548 | 3 Std | KRITISCH |
|
||||
| **B: Datenbank & Docker** | 26 | 32 | 30 Min | KRITISCH |
|
||||
| **C: CI/CD & Scripts** | 13 | 45 | 15 Min | HOCH |
|
||||
| **D: Dokumentation** | 30 | 200+ | 1 Std | MITTEL |
|
||||
| **E: Test-Daten & Emails** | 35 | 85 | 30 Min | HOCH |
|
||||
| **Gesamt** | **372** | **910+** | **~5 Std** | |
|
||||
|
||||
---
|
||||
|
||||
## Betroffene Pakete & Dateien
|
||||
## Phase 1: Package-Namen & Imports (KRITISCH)
|
||||
|
||||
| Paket | Dateien | Art der Aenderung |
|
||||
|-------|---------|------------------|
|
||||
| `packages/db` | `prisma/schema.prisma` | **edit** — `shoringThreshold Int?` auf Project |
|
||||
| `packages/engine` | `src/allocation/shoring-ratio.ts` | **create** — Pure Berechnung |
|
||||
| `packages/engine` | `src/__tests__/shoring-ratio.test.ts` | **create** — Unit Tests |
|
||||
| `packages/api` | `src/router/project.ts` | **edit** — `getShoringRatio` Query + Threshold im Update |
|
||||
| `packages/api` | `src/router/assistant-tools.ts` | **edit** — `get_shoring_ratio` AI Tool |
|
||||
| `apps/web` | `src/components/projects/ShoringIndicator.tsx` | **create** — Visueller Indikator |
|
||||
| `apps/web` | `src/app/(app)/projects/[id]/page.tsx` | **edit** — Indikator auf Detail-Seite |
|
||||
| `apps/web` | `src/app/(app)/projects/ProjectsClient.tsx` | **edit** — Indikator-Spalte in Projektliste |
|
||||
| `apps/web` | `src/components/projects/ProjectModal.tsx` | **edit** — Threshold-Feld im Edit |
|
||||
| `apps/web` | `src/components/dashboard/widgets/ProjectHealthWidget.tsx` | **edit** — Optional: Shoring in Health-Score |
|
||||
### 1.1 Package-Namen umbenennen (12 package.json)
|
||||
|
||||
---
|
||||
| Alt | Neu |
|
||||
|-----|-----|
|
||||
| `@capakraken/api` | `@capakraken/api` |
|
||||
| `@capakraken/application` | `@capakraken/application` |
|
||||
| `@capakraken/db` | `@capakraken/db` |
|
||||
| `@capakraken/engine` | `@capakraken/engine` |
|
||||
| `@capakraken/shared` | `@capakraken/shared` |
|
||||
| `@capakraken/staffing` | `@capakraken/staffing` |
|
||||
| `@capakraken/ui` | `@capakraken/ui` |
|
||||
| `@capakraken/web` | `@capakraken/web` |
|
||||
| `@capakraken/eslint-config` | `@capakraken/eslint-config` |
|
||||
| `@capakraken/prettier-config` | `@capakraken/prettier-config` |
|
||||
| `@capakraken/tsconfig` | `@capakraken/tsconfig` |
|
||||
|
||||
## Task-Liste
|
||||
|
||||
### Phase 1: Schema + Engine (sequenziell)
|
||||
|
||||
- [ ] **Task 1:** Schema erweitern → `packages/db/prisma/schema.prisma`
|
||||
- `shoringThreshold Int? @default(55)` auf dem Project Model
|
||||
- Repraesntiert den kritischen Shoring-Prozentsatz (Default 55%)
|
||||
- `prisma db push`
|
||||
|
||||
- [ ] **Task 2:** Pure Shoring-Ratio Berechnung → `packages/engine/src/allocation/shoring-ratio.ts`
|
||||
```typescript
|
||||
interface ShoringInput {
|
||||
resourceId: string;
|
||||
countryCode: string | null; // "DE", "ES", "IN", etc.
|
||||
hoursPerDay: number;
|
||||
workingDays: number; // oder totalHours direkt
|
||||
}
|
||||
|
||||
interface ShoringResult {
|
||||
totalHours: number;
|
||||
onshoreHours: number; // countryCode === "DE"
|
||||
offshoreHours: number; // countryCode !== "DE"
|
||||
offshoreRatio: number; // 0-100 (%)
|
||||
onshoreRatio: number; // 0-100 (%)
|
||||
threshold: number; // Default 55
|
||||
isAboveThreshold: boolean;
|
||||
byCountry: Record<string, { hours: number; pct: number; resourceCount: number }>;
|
||||
}
|
||||
|
||||
export function calculateShoringRatio(
|
||||
assignments: ShoringInput[],
|
||||
threshold?: number, // Default 55
|
||||
onshoreCountryCode?: string, // Default "DE"
|
||||
): ShoringResult
|
||||
```
|
||||
|
||||
- [ ] **Task 3:** Unit Tests → `packages/engine/src/__tests__/shoring-ratio.test.ts`
|
||||
- 100% Deutsche Ressourcen → offshoreRatio = 0, isAboveThreshold = false
|
||||
- 100% Offshore → offshoreRatio = 100, isAboveThreshold = true
|
||||
- 50/50 Mix → offshoreRatio = 50, isAboveThreshold = false (< 55)
|
||||
- 60/40 Mix → offshoreRatio = 60, isAboveThreshold = true (> 55)
|
||||
- Custom Threshold (30%) → 40% Offshore = above threshold
|
||||
- Leere Assignments → offshoreRatio = 0
|
||||
- Resource ohne Country → zaehlt als Offshore
|
||||
|
||||
- [ ] **Task 4:** Export → `packages/engine/src/allocation/index.ts`
|
||||
|
||||
### Phase 2: API + UI (parallel)
|
||||
|
||||
- [ ] **Task 5:** API Query → `packages/api/src/router/project.ts`
|
||||
- `getShoringRatio` Query (protectedProcedure):
|
||||
- Input: `{ projectId: string }`
|
||||
- Laedt Assignments mit Resource.country
|
||||
- Ruft `calculateShoringRatio()` auf
|
||||
- Returns: `ShoringResult`
|
||||
- `update` Mutation erweitern: `shoringThreshold` im Input akzeptieren
|
||||
- `getById` erweitern: `shoringThreshold` im Response zurueckgeben
|
||||
|
||||
- [ ] **Task 6:** Visueller Indikator → `ShoringIndicator.tsx`
|
||||
- Kompakte Anzeige:
|
||||
```
|
||||
[====DE 45%====|==ES 30%==|IN 25%] ⚠ 55% offshore (Limit: 55%)
|
||||
```
|
||||
- Stacked horizontal bar: Laender-Segmente farbig
|
||||
- Gruen/Gelb/Rot Badge je nach Threshold
|
||||
- Gruen: < Threshold - 10pp
|
||||
- Gelb: Threshold - 10pp bis Threshold
|
||||
- Rot: >= Threshold
|
||||
- Tooltip: Aufschluesselung nach Land
|
||||
- Props: `projectId: string` (laedt Daten selbst via tRPC)
|
||||
|
||||
- [ ] **Task 7:** Threshold im ProjectModal → `ProjectModal.tsx`
|
||||
- Neues Feld: "Max Offshore %" (Number Input, 0-100, Default 55)
|
||||
- Unter "Budget" oder als eigene Section "Shoring"
|
||||
- Label: "Maximum Offshore/Nearshore Ratio (%)"
|
||||
- Hinweis: "Alert when offshore staffing exceeds this percentage"
|
||||
|
||||
- [ ] **Task 8:** Indikator auf Projekt-Detail-Seite → `projects/[id]/page.tsx`
|
||||
- `<ShoringIndicator projectId={id} />` neben dem Budget-Status
|
||||
- Oder als eigene Karte unter den Budget-Karten
|
||||
|
||||
- [ ] **Task 9:** Indikator-Spalte in Projektliste → `ProjectsClient.tsx`
|
||||
- Neue Spalte "Shoring" mit Mini-Indikator (nur Badge gruen/gelb/rot + %)
|
||||
- InfoTooltip: "Offshore staffing ratio vs project threshold"
|
||||
|
||||
### Phase 3: AI + Dashboard (parallel)
|
||||
|
||||
- [ ] **Task 10:** AI Assistant Tool → `assistant-tools.ts`
|
||||
- `get_shoring_ratio` Tool:
|
||||
- Input: `{ projectId: string }`
|
||||
- Returns: menschenlesbare Aufschluesselung
|
||||
- "Project X: 45% onshore (DE), 55% offshore (ES 30%, IN 25%). ⚠ Above 55% threshold."
|
||||
|
||||
- [ ] **Task 11:** Optional: Dashboard Widget oder ProjectHealth Integration
|
||||
- Shoring-Warnung in ProjectHealthWidget einbauen
|
||||
- Oder neues Mini-Widget "Shoring Alerts" (Projekte ueber Threshold)
|
||||
|
||||
---
|
||||
|
||||
## Abhaengigkeiten
|
||||
|
||||
```
|
||||
Task 1 (Schema) → Task 2 (Engine) → Task 3 (Tests) → Task 4 (Export)
|
||||
Task 4 → Task 5 (API)
|
||||
Task 5 → Task 6 + Task 7 + Task 8 + Task 9 (alle parallel)
|
||||
Task 5 → Task 10 (AI Tool)
|
||||
Task 5 → Task 11 (Dashboard)
|
||||
### 1.2 Import-Statements (277 Dateien, 548 Vorkommen)
|
||||
```bash
|
||||
# Globaler Find+Replace
|
||||
find . -type f \( -name "*.ts" -o -name "*.tsx" \) \
|
||||
-not -path "*/node_modules/*" -not -path "*/.next/*" \
|
||||
-exec sed -i 's/@planarchy\//@capakraken\//g' {} +
|
||||
```
|
||||
|
||||
- Tasks 6-9 **vollstaendig parallel** (verschiedene Dateien)
|
||||
- Tasks 10-11 parallel zu Tasks 6-9
|
||||
### 1.3 tsconfig.json Path-Mappings (8 Dateien)
|
||||
```
|
||||
"@capakraken/*" → "@capakraken/*"
|
||||
```
|
||||
|
||||
### 1.4 next.config.ts transpilePackages
|
||||
```
|
||||
"@capakraken/api" → "@capakraken/api" (6 Eintraege)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Akzeptanzkriterien
|
||||
## Phase 2: Datenbank & Docker (KRITISCH)
|
||||
|
||||
- [ ] `pnpm test:unit` laeuft gruen (inkl. neue shoring-ratio Tests)
|
||||
- [ ] `pnpm --filter @planarchy/web exec tsc --noEmit` — keine neuen Errors
|
||||
- [ ] **Projekt-Detail:** Shoring-Indikator sichtbar mit Laender-Aufschluesselung
|
||||
- [ ] **Projektliste:** Shoring-Badge-Spalte (gruen/gelb/rot)
|
||||
- [ ] **Projekt-Edit:** Threshold aenderbar (Default 55%)
|
||||
- [ ] **AI Assistant:** "Wie ist der Shoring-Mix bei Projekt X?" liefert Antwort
|
||||
- [ ] **Farben:** Gruen < 45%, Gelb 45-55%, Rot >= 55% (bei Default-Threshold)
|
||||
- [ ] **Resource ohne Country:** Zaehlt als Offshore
|
||||
- [ ] **Projekt ohne Assignments:** Zeigt "No data" statt Fehler
|
||||
### 2.1 Docker Compose (2 Dateien, 32 Vorkommen)
|
||||
|
||||
| Alt | Neu |
|
||||
|-----|-----|
|
||||
| `POSTGRES_DB: planarchy` | `POSTGRES_DB: capakraken` |
|
||||
| `POSTGRES_USER: planarchy` | `POSTGRES_USER: capakraken` |
|
||||
| `POSTGRES_PASSWORD: capakraken_dev` | `POSTGRES_PASSWORD: capakraken_dev` |
|
||||
| `planarchy_pgdata` (Volume) | `capakraken_pgdata` |
|
||||
| `planarchy_prod_pgdata` | `capakraken_prod_pgdata` |
|
||||
| `planarchy_prod_redis` | `capakraken_prod_redis` |
|
||||
| `admin@capakraken.dev` (pgAdmin) | `admin@capakraken.dev` |
|
||||
|
||||
### 2.2 Datenbank migrieren
|
||||
|
||||
```bash
|
||||
# 1. Backup erstellen
|
||||
docker exec capakraken-postgres-1 pg_dump -U planarchy planarchy > backup.sql
|
||||
|
||||
# 2. Neue DB + User erstellen
|
||||
docker exec capakraken-postgres-1 psql -U postgres -c "
|
||||
CREATE USER capakraken WITH PASSWORD 'capakraken_dev';
|
||||
CREATE DATABASE capakraken OWNER capakraken;
|
||||
GRANT ALL PRIVILEGES ON DATABASE capakraken TO capakraken;
|
||||
"
|
||||
|
||||
# 3. Daten importieren
|
||||
docker exec -i capakraken-postgres-1 psql -U capakraken capakraken < backup.sql
|
||||
|
||||
# 4. .env.local aktualisieren
|
||||
DATABASE_URL=postgresql://capakraken:capakraken_dev@localhost:5433/capakraken
|
||||
```
|
||||
|
||||
### 2.3 Environment-Dateien (3 Dateien)
|
||||
```
|
||||
DATABASE_URL=postgresql://planarchy:capakraken_dev@localhost:5433/planarchy
|
||||
→ DATABASE_URL=postgresql://capakraken:capakraken_dev@localhost:5433/capakraken
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Risiken & offene Fragen
|
||||
## Phase 3: CI/CD & Scripts (HOCH)
|
||||
|
||||
### Risiken
|
||||
- **Country-Daten unvollstaendig:** Viele Resources haben moeglicherweise kein `countryId` gesetzt
|
||||
→ Mitigation: Zaehlt als Offshore + Warning "X resources have no country assigned"
|
||||
- **Stunden vs Headcount:** Soll nach Stunden oder Koepfen gemessen werden?
|
||||
→ Vorschlag: Stunden (gewichtet), da ein 50%-FTE weniger zaehlt als ein 100%-FTE
|
||||
### 3.1 GitHub Actions (.github/workflows/ci.yml, 25 Vorkommen)
|
||||
```bash
|
||||
sed -i 's/@planarchy\//@capakraken\//g' .github/workflows/ci.yml
|
||||
sed -i 's/capakraken_test/capakraken_test/g' .github/workflows/ci.yml
|
||||
sed -i 's/POSTGRES_USER: planarchy/POSTGRES_USER: capakraken/g' .github/workflows/ci.yml
|
||||
sed -i 's/pg_isready -U planarchy/pg_isready -U capakraken/g' .github/workflows/ci.yml
|
||||
```
|
||||
|
||||
### Offene Fragen
|
||||
1. **Nur "DE" als Onshore?** Oder soll der Onshore-Laendercode konfigurierbar sein?
|
||||
→ Vorschlag: Default "DE", aber konfigurierbar pro Projekt
|
||||
2. **Welche Assignment-Status zaehlen?** Nur CONFIRMED? Auch PROPOSED?
|
||||
→ Vorschlag: CONFIRMED + PROPOSED (beide relevant fuer Planung)
|
||||
3. **Soll der Indikator auch in der Timeline sichtbar sein?**
|
||||
→ Vorschlag: Erst mal nur Projektliste + Detail-Seite
|
||||
### 3.2 Root package.json Scripts (9 Vorkommen)
|
||||
```bash
|
||||
sed -i 's/@planarchy\//@capakraken\//g' package.json
|
||||
```
|
||||
|
||||
### 3.3 Start/Stop/Restart Scripts
|
||||
```bash
|
||||
sed -i 's/planarchy/capakraken/g' scripts/start.sh scripts/stop.sh scripts/restart.sh
|
||||
```
|
||||
|
||||
### 3.4 Dependabot
|
||||
```bash
|
||||
sed -i 's/planarchy/capakraken/g' .github/dependabot.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Test-Daten & Emails (HOCH)
|
||||
|
||||
### 4.1 Seed-Dateien (2 Dateien)
|
||||
```
|
||||
admin@capakraken.dev → admin@capakraken.dev
|
||||
manager@capakraken.dev → manager@capakraken.dev
|
||||
viewer@capakraken.dev → viewer@capakraken.dev
|
||||
```
|
||||
|
||||
### 4.2 E2E-Tests (11 Spec-Dateien)
|
||||
```bash
|
||||
find apps/web/e2e -name "*.spec.ts" \
|
||||
-exec sed -i 's/@planarchy\.dev/@capakraken.dev/g' {} +
|
||||
```
|
||||
|
||||
### 4.3 LocalStorage-Keys
|
||||
```
|
||||
planarchy_theme → capakraken_theme
|
||||
planarchy_sidebar_collapsed → capakraken_sidebar_collapsed
|
||||
planarchy_prefs → capakraken_prefs
|
||||
planarchy_dashboard_v1 → capakraken_dashboard_v1
|
||||
planarchy_pwa_dismiss → capakraken_pwa_dismiss
|
||||
planarchy-chat-messages → capakraken-chat-messages
|
||||
```
|
||||
|
||||
### 4.4 Email-Defaults (3 Dateien)
|
||||
```
|
||||
noreply@capakraken.app → noreply@capakraken.app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Dokumentation (MITTEL)
|
||||
|
||||
### 5.1 Kern-Dokumente
|
||||
```bash
|
||||
# Globaler Replace in allen .md Dateien
|
||||
find . -name "*.md" -not -path "*/node_modules/*" \
|
||||
-exec sed -i 's/planarchy/capakraken/g; s/Planarchy/CapaKraken/g; s/plANARCHY/CapaKraken/g' {} +
|
||||
```
|
||||
|
||||
### 5.2 CLAUDE.md aktualisieren
|
||||
- Projektname, Monorepo-Struktur, Package-Referenzen
|
||||
|
||||
### 5.3 Code-Kommentare
|
||||
```bash
|
||||
grep -rn "planarchy" --include="*.ts" --include="*.tsx" . \
|
||||
| grep -v node_modules | grep -v .next | grep "\/\/"
|
||||
# Manuell pruefen und aendern
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Verzeichnis-Umbenennung (OPTIONAL)
|
||||
|
||||
### Nicht umbenennen (zu riskant):
|
||||
- `packages/` Verzeichnisnamen bleiben (`packages/api/`, nicht `packages/capakraken-api/`)
|
||||
- Git-Remote URL aendern ist ein separater Schritt beim Hoster
|
||||
|
||||
### Umbenennen (sicher):
|
||||
- Docker-Container-Namen aendern sich automatisch durch docker-compose Aenderungen
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Verifikation
|
||||
|
||||
```bash
|
||||
# 1. Node Modules neu installieren
|
||||
rm -rf node_modules apps/web/node_modules packages/*/node_modules
|
||||
pnpm install
|
||||
|
||||
# 2. Prisma regenerieren
|
||||
pnpm --filter @capakraken/db exec prisma generate
|
||||
|
||||
# 3. TypeScript pruefen
|
||||
pnpm --filter @capakraken/web exec tsc --noEmit
|
||||
|
||||
# 4. Unit Tests
|
||||
pnpm test:unit
|
||||
|
||||
# 5. Build
|
||||
pnpm --filter @capakraken/web exec next build
|
||||
|
||||
# 6. E2E (nach Seed mit neuen Emails)
|
||||
pnpm --filter @capakraken/db db:seed
|
||||
pnpm test:e2e
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Risiken
|
||||
|
||||
| Risiko | Mitigation |
|
||||
|--------|-----------|
|
||||
| **pnpm Workspace-Aufloesung bricht** | Nach Rename sofort `pnpm install` ausfuehren |
|
||||
| **Import-Pfade nicht komplett ersetzt** | `grep -rn "@planarchy" --include="*.ts"` als Kontrolle |
|
||||
| **Docker Volumes mit alten Namen** | Alte Volumes manuell loeschen: `docker volume rm planarchy_pgdata` |
|
||||
| **Bestehende User-Sessions invalide** | Alle User muessen sich neu einloggen (NEXTAUTH_SECRET bleibt gleich) |
|
||||
| **LocalStorage-Keys veraltet** | Alte Keys werden ignoriert, neue Defaults greifen |
|
||||
| **Git-History referenziert alten Namen** | Kein Problem — History bleibt unveraendert |
|
||||
|
||||
---
|
||||
|
||||
## Empfohlene Reihenfolge
|
||||
|
||||
1. **Backup erstellen** (DB + Git Tag)
|
||||
2. **Phase 1** durchfuehren (Package-Namen + Imports)
|
||||
3. `pnpm install` → pruefen ob Workspace funktioniert
|
||||
4. **Phase 2** (Docker + DB Migration)
|
||||
5. **Phase 3** (CI/CD + Scripts)
|
||||
6. **Phase 4** (Tests + Emails)
|
||||
7. `pnpm test:unit` → alle Tests gruen?
|
||||
8. **Phase 5** (Dokumentation)
|
||||
9. **Phase 7** (Vollstaendige Verifikation)
|
||||
10. **Commit + PR** als einzelner "chore: rename planarchy → capakraken" Commit
|
||||
|
||||
Reference in New Issue
Block a user