Commit Graph

5 Commits

Author SHA1 Message Date
Hartmut 9051ff73d0 fix(types): replace structural DB types with Pick<PrismaClient> and remove Prisma boundary as any casts
Replace ~440 lines of hand-written structural DB client types across 7 lib files
with `Pick<PrismaClient, ...>` from @capakraken/db. This eliminates all `as any`
casts at Prisma boundaries (cron routes, allocation effects, vacation procedures)
and surfaces two pre-existing bugs:
- weekly-digest.ts: `db.allocation.count()` called non-existent model (fixed → demandRequirement)
- estimate-reminders.ts: `submittedAt` field doesn't exist on EstimateVersion (fixed → updatedAt)

Also adds root eslint.config.mjs so lint-staged can lint package files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 15:09:16 +02:00
Hartmut 82acc56b8d chore: add pre-commit hooks, tighten ESLint, activate Sentry DSN, publish CI coverage (Phase 1)
- Install husky v9 + lint-staged: pre-commit runs eslint --fix and prettier on staged files
- Tighten ESLint base config: no-console→error, ban-ts-comment (ts-ignore banned, ts-expect-error with description allowed), reportUnusedDisableDirectives→error
- Migrate web app from deprecated `next lint` to `eslint src/` with flat config and react-hooks plugin
- Convert all 5 @ts-ignore to @ts-expect-error with descriptions, remove stale disable comments
- Add NEXT_PUBLIC_SENTRY_DSN to docker-compose.prod.yml and .env.example
- Add coverage artifact upload step to CI test job
- Pre-existing violations (102 warnings) downgraded to warn in web config for Phase 2 cleanup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 14:49:29 +02:00
Hartmut f8550110eb security: fix 4 OWASP quick-wins from audit round 2
A04-1 (High): docker-compose E2E_TEST_MODE now defaults to "false"
  via ${E2E_TEST_MODE:-false} — prevents accidental security bypass in
  non-test deployments. runtime-env.ts throws at startup if
  E2E_TEST_MODE=true in production.

A05-3 (Medium): all 4 cron routes now fail-closed when CRON_SECRET
  is unset. Extracted shared verifyCronSecret() helper to
  apps/web/src/lib/cron-auth.ts.

A02-1 (Low): verifyCronSecret uses crypto.timingSafeEqual for
  constant-time Bearer token comparison.

A10-1 (Medium): Slack webhook routing uses strict hostname check
  (parsedUrl.hostname === "hooks.slack.com") instead of .includes()
  to prevent bypass via subdomain confusion.

Tickets created for remaining findings: #28 (TOTP rate limit),
#29 (allocations role check), #30 (API keys in DB), #31 (pgAdmin
creds), #32 (MFA enforcement), #33 (auth anomaly alerting),
#34 (comment server-side sanitization).

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-04-01 22:57:51 +02:00
Hartmut 8c5be51251 feat(platform): checkpoint current implementation state 2026-04-01 07:42:03 +02: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