Commit Graph

111 Commits

Author SHA1 Message Date
Hartmut 5e8babd1e6 test(web): cover timeline live preview render edges 2026-04-01 09:41:43 +02:00
Hartmut 5011d071b8 refactor(web): extract timeline live preview helpers 2026-04-01 09:40:07 +02:00
Hartmut 2855567456 test(web): cover timeline project row layout 2026-04-01 09:29:43 +02:00
Hartmut 85744d1879 test(web): cover timeline render helper edges 2026-04-01 09:26:44 +02:00
Hartmut 1f71b345ee test(web): cover allocation visual state helpers 2026-04-01 09:24:38 +02:00
Hartmut f70ce9480d test(web): cover timeline drag math guards 2026-04-01 09:23:45 +02:00
Hartmut 403d59ad73 fix(web): stabilize timeline hover date matching 2026-04-01 09:15:24 +02:00
Hartmut 71c4e61735 test(web): cover timeline sse edge paths 2026-04-01 09:10:45 +02:00
Hartmut e75f69bcf5 refactor(web): extract timeline sse invalidation policy 2026-04-01 08:59:25 +02:00
Hartmut 4edf3a32ac fix(web): keep segmented timeline allocations actionable 2026-04-01 08:54:15 +02:00
Hartmut 8c5be51251 feat(platform): checkpoint current implementation state 2026-04-01 07:42:03 +02:00
Hartmut 7908ab6d05 feat(web): strengthen report builder explainability 2026-03-31 23:07:36 +02:00
Hartmut 8cb34a1c9b feat(web): expand chargeability export explainability 2026-03-31 23:06:39 +02:00
Hartmut dfa289213c refactor(web): share allocation workbook export helper 2026-03-31 23:06:21 +02:00
Hartmut c3b3dffb6e fix(web): harden timeline sse reconnect lifecycle 2026-03-31 23:06:07 +02:00
Hartmut 73ef3b2bba test(web): align workbook export buffer typing 2026-03-31 23:06:00 +02:00
Hartmut 160ba99b5c refactor(insights): share workbook export and ai defaults 2026-03-31 22:53:53 +02:00
Hartmut 05eeaab3f7 chore(settings): align default ai model handling 2026-03-31 22:52:29 +02:00
Hartmut 7ace137d16 feat(dashboard): tighten explainability detail views 2026-03-31 22:50:47 +02:00
Hartmut db50e2e555 feat(import): harden workbook parser boundaries 2026-03-31 22:48:30 +02:00
Hartmut a7362f17bd refactor(config): enforce runtime auth secret policy 2026-03-30 23:40:00 +02:00
Hartmut ef5e8016a4 refactor(api): add redis-backed rate limiting fallback 2026-03-30 23:23:56 +02:00
Hartmut a36bca7ca7 refactor(admin): split system settings into section modules 2026-03-30 20:04:06 +02:00
Hartmut a19d2cbae0 refactor(settings): adopt environment-only runtime secret flow 2026-03-30 19:55:06 +02:00
Hartmut dd71e8f80b fix(comment): align mention audience with entity visibility 2026-03-30 18:50:36 +02:00
Hartmut 82466a4e34 fix(api): derive secure sse subscriptions 2026-03-30 14:20:18 +02:00
Hartmut 27b0e38b93 fix(web): portal remaining overlay menus 2026-03-30 14:20:05 +02:00
Hartmut ea2efabd7f fix(web): portal autocomplete overlays 2026-03-30 14:14:15 +02:00
Hartmut f0bea6235d fix(web): reuse project combobox in timeline popovers 2026-03-30 13:34:59 +02:00
Hartmut 9268a38df4 fix(web): restore comment typing and portal combobox menus 2026-03-30 13:32:51 +02:00
Hartmut 5b60cf5553 fix(web): portal skill tag suggestions 2026-03-30 13:29:28 +02:00
Hartmut fcfe09ac1d fix(web): open project demand strips in demand popover 2026-03-30 13:26:54 +02:00
Hartmut 5a345cd2e4 fix(web): portal timeline hover tooltips 2026-03-30 13:19:43 +02:00
Hartmut e20bf64eef fix(web): portal timeline overlays above stacked panels 2026-03-30 13:18:08 +02:00
Hartmut 93c4374973 feat(auth): introduce explicit planning read permission 2026-03-30 09:15:07 +02:00
Hartmut f6daf21983 feat(import): harden untrusted spreadsheet boundaries 2026-03-30 08:02:52 +02:00
Hartmut fac8c1c3a5 feat(sse): scope timeline events to affected audiences 2026-03-30 00:40:24 +02:00
Hartmut 819345acfa feat(platform): harden access scoping and delivery baseline 2026-03-30 00:27:31 +02:00
Hartmut 47e4d701ff chore(repo): checkpoint current capakraken implementation state 2026-03-29 12:47:12 +02:00
Hartmut beae1a5d6e feat(assistant): add approval inbox and e2e hardening 2026-03-29 10:10:59 +02:00
Hartmut 4f48afe7b4 feat(planning): ship holiday-aware planning and assistant upgrades 2026-03-28 22:49:28 +01:00
Hartmut 1fc1e9f24c feat: AI security controls + PostgreSQL hardening (Week 1 Quick Wins)
AI Security (EGAI 4.3.1.3, 4.3.1.4, 4.1.3.1, IAAI 3.6.26):
- AI Disclaimer banner in ChatPanel: "AI responses may be inaccurate"
- "AI Generated" violet badge on: chat messages, AI summaries,
  project narratives, AI-generated cover images
- HITL: system prompt now requires explicit user confirmation
  before any data mutation (strongly worded instruction)
- Mutation tool audit logging: all 31 write tools logged with
  tool name, params, userId, userRole via Pino

PostgreSQL Hardening (PG Standard V1.6):
- Audit logging: log_connections, log_disconnections, log_statement=ddl,
  log_min_duration_statement=1000 in docker-compose
- SUPERUSER removal script: scripts/harden-postgres.sh
  (NOSUPERUSER + minimal GRANT for app user)
- Health check: pg_isready -U capakraken -d capakraken
- Documentation: security-architecture.md Section 12 updated

Controls closed: EGAI 4.1.3.1, 4.3.1.3, 4.3.1.4, PG 3.3, 3.5

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-27 16:18:35 +01:00
Hartmut cd0c2fe3e2 feat: close 4 more security compliance gaps (46/63 OK, 73%)
Error-Page Headers (3.3.1.3.03 → OK):
- Cache-Control no-store on ALL routes (API, auth, catch-all)

Proactive Monitoring (3.2.1.04 → OK):
- /api/cron/health-check: DB + Redis check with latency, ADMIN alerts on failure

Security Scanning (3.2.2.7 → improved):
- /api/cron/security-audit: package version check against minimum safe versions

Server Hardening (3.3.1.4 → OK):
- docs/nginx-hardening.conf: complete template (rate limits, SSL, headers)

Database Security (3.3.3 → OK):
- docs/security-architecture.md Section 12: DB auth, isolation, SSL/audit recommendations

Compliance: 46 OK / 5 PARTIAL / 8 TODO / 4 N/A (was 42/9/8/4)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-27 15:43:44 +01: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 bf3751f667 fix: invert shoring ratio logic — higher offshore = better
The shoring indicator logic was backwards. In the business context,
higher offshore = more cost-efficient = GOOD.

Inverted logic:
- Green: offshore >= threshold (target met, e.g. >= 55%)
- Yellow: offshore close to threshold (threshold-10 to threshold)
- Red: offshore below threshold (too little offshore, too expensive)

Updated:
- ShoringIndicator: getSeverity() inverted, badge text updated
- ProjectModal: "Max Offshore" renamed to "Min Offshore" with new tooltip
- AI Tool: status text reflects "target met" vs "below target"
- Tool description: "higher offshore is better, threshold is minimum"

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-26 13:07:36 +01:00
Hartmut d58f121c12 feat: clickable project names in ProjectHealth widget
Project names in the health widget now link to /projects/[id] detail page.
Hover: brand color transition for visual feedback.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-26 13:01:42 +01:00
Hartmut be2d2c0d56 feat: Shoring column in ProjectHealth widget + populate country data
Widget: added "Shoring" column with ShoringBadge per project showing
offshore % with color indicator (green/yellow/red).

Backend: added id field to ProjectHealthRow for badge queries.

Database: assigned diverse countries to 11 resources for realistic
shoring data (25 DE, 5 ES, 4 IN, 2 US instead of all-DE).

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-26 11:49:28 +01:00
Hartmut 92a982b151 feat: Nearshore-Ratio indicator per project
Engine (packages/engine):
- calculateShoringRatio() pure function: onshore/offshore hours,
  country breakdown, threshold check, weighted by hours not headcount
- 12 unit tests: empty, 100% onshore/offshore, mixed ratios,
  custom threshold, case-insensitive, unknown country, FTE weighting

Schema:
- Project.shoringThreshold (default 55%) — per-project configurable
- Project.onshoreCountryCode (default "DE") — configurable onshore country

API (project router):
- getShoringRatio query: loads assignments with resource.country,
  computes ratio, returns full breakdown
- update mutation: accepts shoringThreshold + onshoreCountryCode

UI:
- ShoringIndicator: stacked horizontal bar with country segments,
  severity badge (green/yellow/red), hover tooltip, dark theme
- ShoringBadge: mini colored dot + % for project list column
- ProjectModal: "Max Offshore %" number input
- Project detail: indicator after budget status card
- Project list: "Shoring" column (default hidden, toggleable)

AI Assistant:
- get_shoring_ratio tool: human-readable breakdown with threshold alert

Colors: green (<threshold-10), yellow (threshold-10 to threshold), red (>=threshold)
Default: 55% offshore threshold, "DE" as onshore country

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-26 11:45:50 +01:00
Hartmut a9107add7b feat: unique icons for all admin navigation items
Replaced generic AdminIcon (gear) with distinct icons:
- Blueprints: document with lines
- Clients: building/office
- Countries: globe
- Org Units: layout/grid
- Util. Categories: tag
- Mgmt Levels: horizontal lines (hierarchy)
- Data Import: upload arrow
- Calc. Rules: calculator
- Users: people group
- System Roles: shield with checkmark
- Settings: detailed gear (distinct from AdminIcon)
- Webhooks: chain link

Existing unique icons kept: Broadcasts (megaphone), Activity Log (clock)

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-26 08:44:25 +01:00