Hartmut
732538857b
test(api): cover remaining timeline and broadcast fallback races
2026-03-30 12:23:46 +02:00
Hartmut
a9a01e8df0
test(resource): cover chapter and skill import access
2026-03-30 12:23:35 +02:00
Hartmut
d3ad350821
test(assistant): document self-service approval access
2026-03-30 12:20:55 +02:00
Hartmut
c9a35452dc
fix(blueprint): require planning access for global field defs
2026-03-30 12:18:59 +02:00
Hartmut
649c8feb22
fix(api): harden broadcast transactions and estimate fallbacks
2026-03-30 12:18:10 +02:00
Hartmut
016f862405
fix(holiday-calendar): scope resource holiday reads
2026-03-30 12:10:52 +02:00
Hartmut
c7434c968e
fix(vacation): scope preview requests to owned resources
2026-03-30 12:07:26 +02:00
Hartmut
6a6e98b5f7
fix(api): harden broadcast and assistant fallback errors
2026-03-30 12:03:27 +02:00
Hartmut
22cff9648e
test(entitlement): cover self-service and role boundaries
2026-03-30 12:01:34 +02:00
Hartmut
3a29ce4332
fix(blueprint): require planning access for detailed reads
2026-03-30 11:55:43 +02:00
Hartmut
7aa32f8a5c
test(api): harden assistant tool error handling
2026-03-30 11:51:59 +02:00
Hartmut
4ce8577824
test(api): cover notification and user edge cases
2026-03-30 11:51:26 +02:00
Hartmut
4c542d0015
fix(assistant): dedupe missing approval storage warnings
2026-03-30 11:49:05 +02:00
Hartmut
978cd9184d
test(assistant): align admin tool descriptions
2026-03-30 11:45:29 +02:00
Hartmut
b254ab70ba
test(auth): cover notification and user router audiences
2026-03-30 11:08:14 +02:00
Hartmut
c8e82ac221
feat(settings): restrict AI readiness checks to admins
2026-03-30 11:00:42 +02:00
Hartmut
81a46c81bd
feat(blueprint): scope summary reads to planning audience
2026-03-30 10:55:28 +02:00
Hartmut
9b764008c3
feat(management-level): scope reads to planning audience
2026-03-30 10:45:44 +02:00
Hartmut
c2ca6a6d0d
feat(holiday-calendar): restrict catalog reads to admins
2026-03-30 10:36:05 +02:00
Hartmut
54769ca0f5
feat(utilization-category): scope reads to planning audience
2026-03-30 10:29:40 +02:00
Hartmut
ae74700f7c
feat(client): scope planning reads to explicit audience
2026-03-30 10:24:52 +02:00
Hartmut
2b514ea962
feat(org-unit): scope structural reads to resource overview
2026-03-30 10:17:57 +02:00
Hartmut
65fe7ce04f
feat(assistant): align resource tool visibility with read audiences
2026-03-30 10:11:55 +02:00
Hartmut
bd654251f7
feat(master-data): scope detail reads to resource overview
2026-03-30 10:08:44 +02:00
Hartmut
3a30fecc13
feat(role): scope planning-linked role reads to planning audience
2026-03-30 09:58:39 +02:00
Hartmut
16cf1bcb50
feat(assistant): align system role config visibility with admin reads
2026-03-30 09:56:45 +02:00
Hartmut
a25635ee66
feat(auth): restrict system role config reads to admins
2026-03-30 09:46:32 +02:00
Hartmut
98502e6cf8
feat(estimate): scope estimate search to controller audience
2026-03-30 09:44:50 +02:00
Hartmut
806c028974
feat(scenario): scope baseline reads to planning and cost audiences
2026-03-30 09:40:07 +02:00
Hartmut
3aac946443
feat(staffing): enforce planning and cost audiences
2026-03-30 09:36:38 +02:00
Hartmut
a960d43ed1
feat(assistant): align tool visibility with route audiences
2026-03-30 09:22:26 +02:00
Hartmut
93c4374973
feat(auth): introduce explicit planning read permission
2026-03-30 09:15:07 +02:00
Hartmut
a50ca09333
feat(auth): tighten allocation read audiences
2026-03-30 09:03:44 +02:00
Hartmut
db45829eca
feat(auth): classify planning and resource read audiences
2026-03-30 08:51: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
00b936fa1f
feat(assistant): extend audit and import parity
2026-03-29 12:56:29 +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
2a005794e7
feat: additive security improvements — prompt guard, content filter, data classification
...
Prompt Injection Detection (EGAI 4.6.3.2):
- 12-pattern regex scanner on user messages before AI processing
- Logs warning + creates SecurityAlert audit entry on detection
- Reinforces system prompt instead of blocking (non-breaking)
AI Output Content Filter (EGAI 4.3.2.1):
- Scans AI responses for leaked credentials/secrets
- Auto-redacts passwords, API keys, bearer tokens, private keys
- Logs warning + SecurityAlert audit when redaction occurs
AI Tool Execution Audit Trail (IAAI 3.6.35):
- Every AI tool call creates AiToolExecution audit entry
- Logs tool name, parameters, userId, source: "ai"
Data Classification Labels (EGAI 4.2):
- DATA_CLASSIFICATION constant mapping all fields to HC/C/IR/U
- Exported from @capakraken/shared
All changes strictly additive — no existing logic modified.
Co-Authored-By: claude-flow <ruv@ruv.net >
2026-03-27 16:23:33 +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
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
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
e5d7ca1293
refactor: rename Planarchy to CapaKraken (branding only)
...
User-facing rename across 20 files:
- Layout title/meta: "CapaKraken — Resource & Capacity Planning"
- Sidebar logo: "CapaKraken" with "RESOURCE & CAPACITY PLANNING"
- Sign-in page: "CapaKraken Control Center", "Sign in to CapaKraken"
- PWA manifest: name + short_name
- PDF reports: footer text
- Install prompt: "Install CapaKraken"
- AI assistant system prompt
- Webhooks test payload
- Email subject lines
- Tooltips, descriptions, empty states
NOT changed (technical identifiers):
- Package names (@planarchy/*)
- Import paths
- Database names
- Docker container names
- localStorage keys
- Domain URLs
- CLAUDE.md
Co-Authored-By: claude-flow <ruv@ruv.net >
2026-03-25 21:46:15 +01:00
Hartmut
cb46bfbd85
fix: cap AI tool result size to prevent JSON parse errors
...
When generating multiple cover images in one conversation, the
accumulated tool results (each ~400KB base64) caused the OpenAI
conversation payload to exceed JSON parsing limits in the browser.
Fix:
- Strip coverImageUrl from invalidate action results (not needed by AI)
- Cap invalidate results to 4KB
- Cap all tool results to 8KB
- Prevents "JSON.parse: unexpected character" errors during batch ops
Co-Authored-By: claude-flow <ruv@ruv.net >
2026-03-23 18:35:57 +01:00
Hartmut
e766309c6c
fix: AI assistant generate_project_cover now uses configured provider
...
The tool was hardcoded to only check isDalleConfigured(), ignoring
Gemini even when it was the configured image provider. This caused
"DALL-E is not configured" errors for all 13 projects.
Fix: reads imageProvider from SystemSettings and routes to Gemini
or DALL-E accordingly (same logic as the generateCover mutation).
Co-Authored-By: claude-flow <ruv@ruv.net >
2026-03-23 18:01:16 +01:00