feat: security headers, coverage gates, and web vitals #115

Merged
chihlasm merged 7 commits from feat/security-headers-coverage-performance into main 2026-03-18 03:34:04 +00:00
chihlasm commented 2026-03-18 02:51:08 +00:00 (Migrated from github.com)

Summary

  • Security headers middleware — HSTS (prod only), X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, and Content-Security-Policy in report-only mode. Configurable via settings to promote CSP to enforcing without code changes.
  • Coverage gates — Backend CI now fails if coverage drops below 80%. Frontend CI now generates coverage reports via @vitest/coverage-v8 (report-only, no gate yet).
  • Core Web Vitals → PostHog — LCP, INP, CLS, FCP, TTFB reported as web_vitals events with metric name, value, rating, and page path.

Test plan

  • Backend: pytest tests/test_security_headers.py -v — 3 tests for header presence, CSP report-only, HSTS prod-only
  • Backend: full suite passes with --cov-fail-under=80
  • Frontend: npm run test:coverage generates coverage report
  • Frontend: npm run build succeeds with web-vitals wired in
  • Deploy to PR env and verify security headers appear in browser DevTools (Network → Response Headers)
  • Verify web_vitals events appear in PostHog after page load

Note: npm install needed to pick up @vitest/coverage-v8 and web-vitals (added to package.json, lockfile update pending).

🤖 Generated with Claude Code

## Summary - **Security headers middleware** — HSTS (prod only), X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, and Content-Security-Policy in report-only mode. Configurable via settings to promote CSP to enforcing without code changes. - **Coverage gates** — Backend CI now fails if coverage drops below 80%. Frontend CI now generates coverage reports via `@vitest/coverage-v8` (report-only, no gate yet). - **Core Web Vitals → PostHog** — LCP, INP, CLS, FCP, TTFB reported as `web_vitals` events with metric name, value, rating, and page path. ## Test plan - [ ] Backend: `pytest tests/test_security_headers.py -v` — 3 tests for header presence, CSP report-only, HSTS prod-only - [ ] Backend: full suite passes with `--cov-fail-under=80` - [ ] Frontend: `npm run test:coverage` generates coverage report - [ ] Frontend: `npm run build` succeeds with web-vitals wired in - [ ] Deploy to PR env and verify security headers appear in browser DevTools (Network → Response Headers) - [ ] Verify `web_vitals` events appear in PostHog after page load **Note:** `npm install` needed to pick up `@vitest/coverage-v8` and `web-vitals` (added to package.json, lockfile update pending). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
railway-app[bot] commented 2026-03-18 02:51:23 +00:00 (Migrated from github.com)

🚅 Deployed to the patherly-pr-115 environment in selfless-grace

Service Status Web Updated (UTC)
hopeful-liberation Success (View Logs) Web Mar 18, 2026 at 3:15 am
patherly Success (View Logs) Web Mar 18, 2026 at 3:13 am
<!-- railway-bot-comment-version=2 --> <!-- railway-project-id="22b9b58c-271b-42e5-a10e-6fdec8d00134" railway-project-name="selfless-grace" --> 🚅 Deployed to the [patherly-pr-115](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134?environmentId=5e4976aa-f825-49d9-9c2c-13ccc9c08c60) environment in **[selfless-grace](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134)** | **Service** | **Status** | **Web** | **Updated** (UTC) | | :--- | :--- | :--- | :--- | | hopeful-liberation | ✅ Success ([View Logs](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134/service/e1db2ee3-d241-4f45-abe4-c9c5fdf483d5?id=16f5cc41-4704-4dc7-8b8e-d4e92377c950&environmentId=5e4976aa-f825-49d9-9c2c-13ccc9c08c60)) | [Web](https://hopeful-liberation-patherly-pr-115.up.railway.app) | Mar 18, 2026 at 3:15 am | | patherly | ✅ Success ([View Logs](https://railway.com/project/22b9b58c-271b-42e5-a10e-6fdec8d00134/service/95f556ff-5264-4116-a0c2-618a2fc53ba4?id=9fed56d7-15c6-4722-a807-043b6302a747&environmentId=5e4976aa-f825-49d9-9c2c-13ccc9c08c60)) | [Web](https://patherly-patherly-pr-115.up.railway.app) | Mar 18, 2026 at 3:13 am |
Sign in to join this conversation.