Commit Graph

16 Commits

Author SHA1 Message Date
Hartmut 9bd3781c03 fix(types): flatten tRPC Zod schema types to resolve TS2589 inference depth errors
Cast Zod schemas with .refine()/.superRefine() to z.ZodType<InferredType> at the
procedure level. This short-circuits TypeScript's deep type recursion through
tRPC's middleware chain, eliminating 4 of 5 @ts-expect-error TS2589 suppressions
in web components (VacationModal, ProjectModal, UsersClient, CountriesClient).

Applied same pattern to allocation, timeline, staffing, dashboard, project, and
resource query/mutation procedures to reduce client-side type depth.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 15:28:12 +02:00
Hartmut 41eb722369 feat: user invite flow, deactivate/delete, favicon, dashboard loading fix, admin full-width
- Invite flow: admin can invite users by email with role selection; accept-invite page
  sets password and creates the account; 72-hour token expiry; E2E tests
- User deactivate/reactivate/delete: new tRPC procedures + UI buttons; deactivation
  revokes all active sessions immediately; delete cascades vacation/broadcast records;
  isActive field added via migration 20260402000000_user_isactive
- Auth: block login for inactive users with audit entry
- Favicon: SVG favicon + ICO/PNG fallbacks (16, 32, 180, 192, 512px); manifest updated
- Dashboard: GridLayout dynamic-import loading skeleton prevents blank dark area
  on first login before react-grid-layout chunk is cached
- Admin users: remove max-w-5xl constraint so table uses full page width
- Dev: docker container restart workflow documented in LEARNINGS.md; Prisma generate
  must run inside the container after schema changes (named node_modules volume)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-02 20:19:26 +02:00
Hartmut 9fccd4c29e refactor(api): extract user procedures 2026-03-31 21:40:50 +02:00
Hartmut 99db52929f fix(api): harden user self-service and resource linking 2026-03-31 21:02:36 +02:00
Hartmut 7aa32f8a5c test(api): harden assistant tool error handling 2026-03-30 11:51:59 +02:00
Hartmut 9d43e4b113 feat: ACN Application Security Standard V7.30 compliance (19/23 items)
CRITICAL — Authentication & Access:
- TOTP MFA: otpauth-based, QR setup UI, sign-in flow integration,
  admin disable override, /account/security self-service page
- Session Timeouts: 8h absolute (maxAge), 30min idle (updateAge)
- Failed Auth Logging: Pino warn for invalid password/user/totp,
  info for successful login, audit entries for all auth events
- Concurrent Session Limit: ActiveSession model, oldest-kick strategy,
  max 3 per user (configurable in SystemSettings)

CRITICAL — HTTP Security:
- HSTS: max-age=31536000; includeSubDomains
- CSP: script/style/img/font/connect-src with Gemini/OpenAI whitelist
- X-XSS-Protection: 0 (CSP replaces legacy)
- Auth page cache: no-store, no-cache, must-revalidate
- Rate Limiting: 100/15min general API, 5/15min auth (Map-based)

Data Protection:
- XSS Sanitization: DOMPurify on comment bodies
- autocomplete="new-password" on all password/secret fields
- SameSite=Strict on all cookies (Credentials-only, no OAuth)
- File Upload Magic Bytes validation (PNG/JPEG/WebP/GIF/BMP/TIFF)

Logging & Monitoring:
- Login/Logout audit entries (Auth entityType)
- External API call logging with timing (OpenAI, Gemini)
- Input validation failure logging at warn level
- Concurrent session tracking in ActiveSession table

Documentation:
- docs/security-architecture.md (11 sections)
- docs/sdlc.md (CI pipeline, security gates, incident response)
- .gitea/PULL_REQUEST_TEMPLATE.md (security checklist)

Schema: User.totpSecret/totpEnabled, SystemSettings.sessionMaxAge/
sessionIdleTimeout/maxConcurrentSessions, ActiveSession model

Tests: 310 engine + 37 staffing pass. TypeScript clean.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-27 14:16:39 +01:00
Hartmut cd78f72f33 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>
2026-03-27 13:18:09 +01:00
Hartmut 840f355f4f feat: admin can change user display name
API: new updateName adminProcedure in user router
- Input: userId + name (min 1, max 200 chars)
- Argon2 not involved (name only, not password)
- Audit log: "Changed name from X to Y"

UI: "Display Name" editable section in user edit modal
- Shows current name with "Edit" link
- Click Edit: inline input with Save/Cancel + Enter/Escape
- Auto-focuses input, saves on Enter
- Invalidates user list on success

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-23 09:41:56 +01:00
Hartmut bc6afefeae feat: admin set password for users + fix dashboard cache error
Admin Set Password:
- New setPassword adminProcedure in user router (Argon2 hashing)
- Audit log: "Password reset by admin" (no password value logged)
- UI: per-user "Password" button with key icon in User Management
- Modal: new password + confirm, min 8 chars, mismatch validation
- Success toast + auto-close on completion

Dashboard fix:
- Corrupted .next cache causing "Cannot find module worker.js"
- Fixed by clearing .next cache and restarting dev server

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-23 09:32:38 +01:00
Hartmut 66878f18f4 feat: Activity History system — full audit coverage, UI, AI tools
Infrastructure (Phase 1):
- AuditLog schema: add source, entityName, summary fields + index
- createAuditEntry() helper: auto-diff, auto-summary, fire-and-forget
- auditLog query router: list, getByEntity, getTimeline, getActivitySummary

Audit Coverage (Phase 2 — 14 routers, 50+ mutations):
- vacation: create, approve, reject, cancel, batch ops (8 mutations)
- user: create, updateRole, setPermissions, resetPermissions (5 mutations)
- entitlement: set, bulkSet (3 mutations)
- client: create, update, delete, batchUpdateSortOrder
- org-unit: create, update, deactivate
- country: create, update, createCity, updateCity, deleteCity
- management-level: createGroup, updateGroup, createLevel, updateLevel, deleteLevel
- settings: updateSystemSettings (sensitive fields sanitized), testSmtp
- blueprint: create, update, updateRolePresets, delete, batchDelete, setGlobal
- rate-card: create, update, deactivate, addLine, updateLine, deleteLine, replaceLines
- calculation-rules: create, update, delete
- effort-rule: create, update, delete
- experience-multiplier: create, update, delete
- utilization-category: create, update

Admin UI (Phase 3):
- /admin/activity-log page with global searchable timeline
- Filters: entity type, action, user, date range, text search
- Expandable before/after diff view per entry
- Summary cards showing top entity types by change count
- EntityHistory reusable component for entity detail pages
- Sidebar nav link with clock icon

AI Assistant (Phase 4):
- query_change_history tool: "Who changed project X?"
- get_entity_timeline tool: "What happened to resource Y?"

Regression: 283 engine + 37 staffing tests pass. TypeScript clean.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-22 22:39:30 +01:00
Hartmut ddec3a927a feat: timeline multi-select, demand popover, resource hover card, merged tooltips, dark mode fixes
Major timeline enhancements:
- Right-click drag multi-selection with floating action bar (batch delete/assign)
- DemandPopover for demand strip details (replaces broken "Loading" modal)
- ResourceHoverCard on name hover showing skills, rates, role, chapter
- Merged heatmap+vacation tooltips into unified TimelineTooltip component
- Fixed overbooking blink animation (date normalization, z-index ordering)
- Fixed dark mode sticky column bleed-through in project view
- System roles admin page, notification task management, performance review docs

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-18 23:43:51 +01:00
Hartmut eb283147d1 feat: project colors, timeline filters, sidebar fix, GitLooper agent, and misc improvements
- Fix sidebar double-highlight on /vacations/my (Gitea #6): add isNavItemActive() helper
- Add project color picker (schema + API + modal + timeline rendering)
- Add ProjectCombobox/ResourceCombobox to timeline toolbar
- Show PENDING vacations on timeline with dashed/dimmed style
- Add "show demand projects" preference with localStorage persistence
- Add ProjectAssignmentsTable with total hours/cost columns
- Extend vacation API to accept status arrays
- Add GitLooper formal YAML agent configuration
- Extend user admin with permission overrides UI
- Add delete-assignment use case tests
- Add status-styles.ts shared badge constants
- Centralize formatMoney/formatCents in format.ts

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-17 10:22:52 +01:00
Hartmut b0e55786c3 feat: AI assistant (HartBOT), demand filling, budget-per-role, project favorites, and UX improvements
AI Assistant (HartBOT):
- Chat panel with inline layout, session persistence, message history (up-arrow recall)
- OpenAI function calling with 20+ tools (search, navigate, create/cancel allocations, update status)
- RBAC-aware tool filtering, fuzzy search with word-level matching
- Navigation actions (router.push) and data invalidation after mutations
- Country/metro city/org unit/role filtering on resource search

Demand Filling Enhancements:
- Two-phase fill modal: plan multiple resources, then confirm & assign all at once
- Availability preview per resource (available/partial/conflict days, existing bookings)
- Coverage bar showing demand hours distribution across assigned resources
- Fill demand from project detail page (new Assign button per demand)
- Fixed: filled demands no longer shown on timeline, demand bars no longer overlap

Budget per Role:
- DemandRequirement.budgetCents field (schema + API + UI)
- Project wizard step 3: budget input per role with allocation summary bar
- Project detail: allocated vs booked budget per demand
- Fill demand modal: role budget display with cost estimates
- AllocationModal: budget field for demand editing

Project Favorites:
- User.favoriteProjectIds (JSONB) with toggle API
- Star button on projects list and detail page (optimistic updates)
- "My Projects" dashboard widget (favorites + responsible person projects)

Project Management:
- Edit project from detail page (ProjectModal integration)
- Edit demands from detail page (AllocationModal integration)
- Admin-only project deletion (cascades assignments + demands)
- Create user accounts from admin panel

Timeline Fixes:
- Country multi-select filter with backend support
- URL param sync for same-page navigation (AI assistant integration)
- Demand lane stacking (no more overlapping bars)
- Single-day booking resize handles (always visible, min 6px)
- Single-day resize allowed (start === end)
- "All Clients" toggle (select all / deselect all)

Other Fixes:
- crypto.randomUUID fallback for non-secure contexts
- Chat message limit raised (200 max, client sends last 40)
- Status dropdown portal (no longer clipped by table overflow)
- Cents display restored in budget views (2 decimal places)
- Allocations grouped view with project sub-groups (collapsed by default)
- Server-side resource search for project wizard (no 500 limit)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-16 15:31:48 +01:00
Hartmut a83edb2f9d feat: timeline UI overhaul with project/resource panel redesign, quick filters, and API improvements
Redesigned timeline project and resource panels with expanded detail views,
added quick filter toolbar, improved drag handling, and enhanced vacation/entitlement
router logic. Includes e2e test updates and minor API fixes.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-15 09:28:59 +01:00
Hartmut ad0855902b refactor: complete v2 refactoring plan (Phases 1-5)
Phase 1 — Quick Wins: centralize formatMoney/formatCents, extract
findUniqueOrThrow helper (19 routers), shared Prisma select constants,
useInvalidatePlanningViews hook, status badge consolidation, composite
DB indexes.

Phase 2 — Timeline Split: extract TimelineContext, TimelineResourcePanel,
TimelineProjectPanel; split 28-dep useMemo into 3 focused memos.
TimelineView.tsx reduced from 1,903 to 538 lines.

Phase 3 — Query Performance: server-side filtering for getEntriesView,
remove availability from timeline resource select, SSE event debouncing
(50ms batch window).

Phase 4 — Estimate Workspace: extract 7 tab components and 3 editor
components. EstimateWorkspaceClient 1,298→306 lines,
EstimateWorkspaceDraftEditor 1,205→581 lines.

Phase 5 — Package Cleanup: split commit-dispo-import-batch (1,112→573
lines), extract shared pagination helper with 11 tests.

All tests pass: 209 API, 254 engine, 67 application.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-14 23:03:42 +01:00
Hartmut dd55d0e78b chore(repo): initialize planarchy workspace 2026-03-14 14:31:09 +01:00