Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
945 commits
Select commit Hold shift + click to select a range
36a4bf5
Initial plan
Copilot May 15, 2026
33c4e57
Initial plan
Copilot May 15, 2026
6c14e84
Initial plan
Copilot May 15, 2026
7f76742
Initial plan
Copilot May 15, 2026
dae49bd
Initial plan
Copilot May 15, 2026
bda97c7
Initial plan
Copilot May 15, 2026
f79503f
Initial plan
Copilot May 15, 2026
047a17a
security: harden Docker runtime file ownership (docker:S6504)
Copilot May 15, 2026
cc598ad
chore: document non-security-sensitive Math.random() uses in load tests
Copilot May 15, 2026
c2a4b49
security: tighten Docker build contexts and .dockerignore rules
Copilot May 15, 2026
f6951f5
security: minimise pgbackrest container root usage (S6471)
Copilot May 15, 2026
2e69117
security: harden regex usage against ReDoS across five files
Copilot May 15, 2026
3226451
feat(security): enforce HTTPS for public/browser-facing URLs in produ…
Copilot May 15, 2026
7611903
test: address code review — fix parentheses, add delete-files variant…
Copilot May 15, 2026
67f220a
refactor(security): use requireHttpsInProduction in next.config.ts; d…
Copilot May 15, 2026
fa2cc41
security: enforce HTTPS-only redirects in staging deploy script curl …
Copilot May 15, 2026
87ec457
security: classify S5332 HTTP hotspots and add NOSONAR annotations
Copilot May 15, 2026
e0ff5fd
refactor: address code review - fix NOSONAR placement precision
Copilot May 15, 2026
60030b6
refactor: fix remaining NOSONAR placement issues per code review
Copilot May 15, 2026
a548cd2
Merge pull request #284 from NickLetts2/copilot/classify-docker-http-…
NickLetts2 May 15, 2026
205cd96
Merge pull request #285 from NickLetts2/copilot/harden-staging-deploy…
NickLetts2 May 15, 2026
fb3a52e
Merge pull request #283 from NickLetts2/copilot/fix-http-to-https-config
NickLetts2 May 15, 2026
3e9b8c3
Merge pull request #282 from NickLetts2/copilot/review-math-random-usage
NickLetts2 May 15, 2026
e2174e2
Merge pull request #281 from NickLetts2/copilot/harden-regex-against-…
NickLetts2 May 15, 2026
0224eed
Merge pull request #279 from NickLetts2/copilot/review-minimise-pgbac…
NickLetts2 May 15, 2026
aa5b6e3
Merge pull request #280 from NickLetts2/copilot/tighten-docker-build-…
NickLetts2 May 15, 2026
fa80d58
Merge pull request #278 from NickLetts2/copilot/harden-docker-runtime…
NickLetts2 May 15, 2026
75a88a5
Add target architecture action plan
NickLetts2 May 16, 2026
d80ed9b
Update target architecture action plan with issue map
NickLetts2 May 16, 2026
4574b22
Update target architecture for backup target VM
NickLetts2 May 16, 2026
d4d9236
Add local staging backup target bootstrap script
NickLetts2 May 16, 2026
373abcf
Add files via upload
NickLetts2 May 16, 2026
b24304e
Add files via upload
NickLetts2 May 16, 2026
bfba163
Add scripts for Curvit local staging setup and backup restoration
NickLetts2 May 18, 2026
4216960
Merge branch 'main' of https://github.com/NickLetts2/Curvit
NickLetts2 May 18, 2026
6144bb1
chore: apply Sonar remediations and trigger new analysis run
NickLetts2 May 18, 2026
cec405e
ci: accept hash-continued exact pins in requirements validator
NickLetts2 May 18, 2026
83c7552
ci: avoid DAST SARIF missing-file annotations
NickLetts2 May 18, 2026
303a598
fix: resolve new Sonar reliability findings
NickLetts2 May 18, 2026
57743e8
fix: clear remaining frontend sonar reliability issues
NickLetts2 May 18, 2026
b869a76
revert: narrow frontend sonar-only edits
NickLetts2 May 18, 2026
1f0bfd7
test: add comprehensive test coverage for admin error page and login …
NickLetts2 May 18, 2026
5688c92
test: add comprehensive email service tests for messaging-service
NickLetts2 May 18, 2026
7a216b5
test: add CurvitWordmark component tests
NickLetts2 May 18, 2026
7ae2851
docs: add 80% coverage roadmap with test strategy
NickLetts2 May 18, 2026
f3cabfc
fix: resolve all SonarQube maintainability issues and pre-existing te…
NickLetts2 May 18, 2026
770545b
fix(ci): suppress Debian OS CVEs pending apt security updates
NickLetts2 May 18, 2026
ba37a15
fix(sonar): replace hardcoded test credentials with fixture constant …
NickLetts2 May 18, 2026
903ad63
fix(sonar): exclude url-validation.ts from coverage measurement
NickLetts2 May 18, 2026
72de7af
test: add Stripe gateway adapter tests
NickLetts2 May 18, 2026
d4093a2
test: add Stripe service integration tests + fix exception handling
NickLetts2 May 18, 2026
e36cd63
docs: add comprehensive test coverage progress report
NickLetts2 May 18, 2026
c4953f2
feat: add Phase 3 comprehensive test coverage (55 new tests)
NickLetts2 May 18, 2026
624a350
feat: add billing orchestration tests (11 tests, 85% service coverage)
NickLetts2 May 18, 2026
41c4efe
Align staging backup monitoring with local VM setup
NickLetts2 May 18, 2026
85e919f
Fix local staging DR restore rehearsal
NickLetts2 May 18, 2026
337b5af
Optimize CI/CD workflow execution
NickLetts2 May 18, 2026
00faef3
Stabilize CMS blog visibility boundary tests
NickLetts2 May 18, 2026
61df6aa
Cancel superseded staging deploys
NickLetts2 May 18, 2026
8f15eff
Run staging deploy directly on local runner
NickLetts2 May 18, 2026
c1964fc
Trust staging checkout during local deploy
NickLetts2 May 18, 2026
008b0b6
Allow insecure TLS for local staging health check
NickLetts2 May 18, 2026
b0a41bb
Pass ZAP daemon options correctly
NickLetts2 May 18, 2026
d83c248
Prevent staging health check stalls
NickLetts2 May 18, 2026
87f55f2
ci(staging): fail fast when staging host is unreachable
NickLetts2 May 19, 2026
d76ead2
Add .gitattributes for cross-platform line ending consistency
NickLetts2 May 19, 2026
a29cd44
Normalize line endings across all files per .gitattributes
NickLetts2 May 19, 2026
d1048f4
Enhance CI/CD workflows with security scan gating and deployment flow…
NickLetts2 May 19, 2026
91d71aa
fix(security): remediate critical deps and harden validator/workflow
NickLetts2 May 19, 2026
5788f5e
chore(dependabot): ignore nodemailer major updates for next-auth comp…
NickLetts2 May 19, 2026
62eff11
fix(security): remove user-controlled schema path construction
NickLetts2 May 19, 2026
508a676
fix(security): avoid logging or returning raw exception details
NickLetts2 May 19, 2026
25aa9f7
fix(security): harden startup logging and remove regex backtracking path
NickLetts2 May 19, 2026
a0ebf83
fix(ci): retry GHCR imagetools retag on transient registry failures
NickLetts2 May 19, 2026
642916d
fix(ci): harden image publish retries and patch core-api base runtime…
NickLetts2 May 19, 2026
af20470
fix(core-api): restore valid dotnet alpine base image references
NickLetts2 May 19, 2026
47498f7
Fix high-priority code scanning alerts
NickLetts2 May 19, 2026
b6a2e93
Harden test-only auth helpers
NickLetts2 May 19, 2026
1ffad23
Avoid exposing harness exception details
NickLetts2 May 19, 2026
838a439
Batch security scan remediations
NickLetts2 May 19, 2026
79ad447
Allow patched Nodemailer peer install
NickLetts2 May 19, 2026
a4ab85e
Refresh Python service base digests
NickLetts2 May 19, 2026
d1a4338
chore(infra): harden production bootstrap and introduce least-privile…
NickLetts2 May 19, 2026
937e4d2
Batch remaining dependency updates
NickLetts2 May 19, 2026
dd528df
Keep marketing Vite on compatible major
NickLetts2 May 19, 2026
90780be
Refactor bootstrap scripts: Remove SSH public key parameter, add Clou…
NickLetts2 May 19, 2026
b2a6593
docs: reconcile runbooks with Auth.js authentication system
NickLetts2 May 19, 2026
a04f64b
Refactor Traefik environment handling and enhance deployment scripts
NickLetts2 May 19, 2026
cd3c549
Fix: Update default email from_address from noreply@curvit.dev to nor…
NickLetts2 May 19, 2026
0d0eded
Marketing site production tuning and curvit.co.uk domain update
NickLetts2 May 19, 2026
e133557
Fix: Allow public messaging endpoints to bypass authentication middle…
NickLetts2 May 19, 2026
9111fa5
CD production: allow security gate workflow dispatch
NickLetts2 May 19, 2026
8402360
CD production: wait for newly dispatched security scan run
NickLetts2 May 19, 2026
e805311
Enhance accessibility: Add skip navigation functionality for keyboard…
NickLetts2 May 19, 2026
1a31470
CD production: suspend scan gate by default
NickLetts2 May 19, 2026
255da23
CD production: use existing SERVER_SSH_KEY secret
NickLetts2 May 19, 2026
8f247dc
CD production: use configurable SSH username defaulting to curvitadmin
NickLetts2 May 19, 2026
3a17961
CD production: default SSH user back to deploy
NickLetts2 May 19, 2026
b1987b9
Enhance deployment scripts: enforce permissions for deploy user and i…
NickLetts2 May 19, 2026
97d0fb4
Enhance Hetzner bootstrap scripts: add safety switches for production…
NickLetts2 May 19, 2026
b7ef3b4
fix: add pool_pre_ping to async DB engine to prevent stale connection…
NickLetts2 May 19, 2026
3731065
chore: rotate Resend API key in prod and staging secrets
NickLetts2 May 19, 2026
f9060bb
fix: set messaging-service from address to mail.curvit.co.uk for Rese…
NickLetts2 May 19, 2026
f12fc2e
chore(prod): route contact notifications to Nick inbox
NickLetts2 May 19, 2026
fd656f5
chore(staging): align resend sender/admin email config
NickLetts2 May 19, 2026
0727764
chore(staging): differentiate app and alert email identities
NickLetts2 May 19, 2026
4dd0949
chore(monitoring): switch grafana smtp examples to resend
NickLetts2 May 19, 2026
50caf57
chore(secrets): update encrypted smtp resend settings
NickLetts2 May 19, 2026
d929c38
chore(network): allow grafana smtp egress in prod and staging
NickLetts2 May 19, 2026
5a3daaf
fix(staging): add prod host age recipient for staging decrypt
NickLetts2 May 19, 2026
7544954
Initial plan
Copilot May 20, 2026
5a2ec45
test: stabilize messaging-service admin email assertions
Copilot May 20, 2026
69b575e
Merge pull request #322 from NickLetts2/copilot/fix-admin-email-test-…
NickLetts2 May 20, 2026
3a1b673
feat(tunnel): add SSH tunnel scripts for Grafana access in staging an…
NickLetts2 May 21, 2026
1982c96
chore: update Python 3.14-slim-bookworm base image digest to latest
NickLetts2 May 21, 2026
72f11e9
Merge branch 'main' of https://github.com/NickLetts2/Curvit
NickLetts2 May 21, 2026
5784596
fix(security): address SonarQube security hotspots
NickLetts2 May 21, 2026
3eddd3c
fix(c#): batch rename CancellationToken ct → cancellationToken (Sonar…
NickLetts2 May 21, 2026
5e4ab8d
fix(c#): remove unused private setters and dead test classes (SonarQu…
NickLetts2 May 21, 2026
abdd0e4
fix(python): add logging to silent exception handlers (SonarQube S110…
NickLetts2 May 21, 2026
826b13c
fix(python): remove unused imports (SonarQube F401)
NickLetts2 May 21, 2026
6c74f56
fix(python): restore uuid import in billing-service db_models (Batch …
NickLetts2 May 21, 2026
abee60c
fix(c#): consolidate magic strings to constants (SonarQube S3254)
NickLetts2 May 21, 2026
2609bab
fix(python): wrap long lines in content-sanitiser and billing test (E…
NickLetts2 May 21, 2026
acb53d8
fix(python): extract setup_api_key_scheme to shared module (S4144)
NickLetts2 May 21, 2026
1545f2f
feat(frontend): complete TypeScript/Frontend fixes (Batch 8)
NickLetts2 May 21, 2026
15267cc
feat(python): add return type annotations to FastAPI route handlers (…
NickLetts2 May 21, 2026
2f36cab
refactor(python): deduplicate setup_api_key_scheme across 9 services …
NickLetts2 May 21, 2026
0686a0e
feat(python): add return type annotations to messaging-service router…
NickLetts2 May 21, 2026
a4217c1
fix: resolve remaining SonarQube issues - batches 6-9 complete
NickLetts2 May 21, 2026
bfbbb74
fix: resolve system test failures and enforce UTF-8 encoding standards
NickLetts2 May 21, 2026
26d92c5
fix(sonar): remove incompatible sonar-project.properties for Scanner v8+
NickLetts2 May 21, 2026
945ae58
chore: remove transitory Phase 1 planning documents
NickLetts2 May 21, 2026
c8b0cfb
chore: remove obsolete auth documentation (Authentik-era)
NickLetts2 May 21, 2026
538dc44
fix: remove obsolete permissions from DAST workflow
NickLetts2 May 21, 2026
1c51bae
fix: update SonarCloud exclusions to include SQL and PL/SQL files
NickLetts2 May 21, 2026
1149830
feat: add Stripe staging payment test support
NickLetts2 May 22, 2026
301fd53
Improve payment sandbox and billing admin safety
NickLetts2 May 22, 2026
ffcd4c2
Fix staging Stripe webhook path
NickLetts2 May 22, 2026
d2b92ae
Document payment environments and testing
NickLetts2 May 22, 2026
3b3ab71
Implement feature X to enhance user experience and optimize performance
NickLetts2 May 22, 2026
a70f814
Update terms of use and improve styling
NickLetts2 May 22, 2026
2b2714c
Refactor Stripe payment E2E tests for improved readability and functi…
NickLetts2 May 22, 2026
897f5f0
chore(deps): bump the docker-all group across 4 directories with 2 up…
dependabot[bot] May 23, 2026
5ea19aa
chore(deps): bump the pip-all group across 5 directories with 2 updates
dependabot[bot] May 23, 2026
e53ec12
Fix pre-commit by scoping payment E2E to payment config
NickLetts2 May 26, 2026
e136fdb
Skip payment E2E outside payment Playwright project
NickLetts2 May 26, 2026
97f64af
Fix SonarCloud issues: type C# catch blocks, suppress intentional pat…
NickLetts2 May 26, 2026
4768c36
Fix TypeScript and C# type errors in SonarCloud remediation
NickLetts2 May 26, 2026
26d690f
Shift monitoring to SSH tunnel access and enable anonymous Grafana mode
NickLetts2 May 26, 2026
97d288f
Retrigger GitHub Actions
NickLetts2 May 26, 2026
8c02fc4
Merge pull request #323 from NickLetts2/dependabot/docker/apps/app-fr…
NickLetts2 May 26, 2026
612b15e
Prevent automatic database migrations on startup - require explicit a…
NickLetts2 May 26, 2026
443b0c5
Add bootstrap migrations endpoint for auth-blocking schema changes
NickLetts2 May 26, 2026
3959678
Revert "Add bootstrap migrations endpoint for auth-blocking schema ch…
NickLetts2 May 26, 2026
ee39445
Revert "Prevent automatic database migrations on startup - require ex…
NickLetts2 May 26, 2026
1a91f1c
Restore auto-migrations and add initial seed data
NickLetts2 May 26, 2026
ae46a22
Infrastructure improvements: monitoring, scripts, and alerting
NickLetts2 May 26, 2026
1f6da9b
Merge branch 'main' of https://github.com/NickLetts2/Curvit
NickLetts2 May 26, 2026
eba4cf3
Suppress new Trivy CVEs in postgres:18-alpine base image
NickLetts2 May 26, 2026
2a0994c
fix: Complete HyperV staging backup migration and monitoring hardening
NickLetts2 May 26, 2026
d581a73
fix: Mark component props as readonly to improve type safety
NickLetts2 May 26, 2026
d1494db
fix: Remove redundant FastAPI response_model parameters
NickLetts2 May 26, 2026
4bb83f0
chore(deps): bump the npm-all group across 2 directories with 15 updates
dependabot[bot] May 26, 2026
421f5fa
fix: Resolve syntax errors from response_model removal
NickLetts2 May 26, 2026
b13c3a3
fix: Resolve Trivy scanning issue in build-push workflow
NickLetts2 May 26, 2026
6792f0e
fix: Resolve Trivy image scanning with local Docker references
NickLetts2 May 26, 2026
d523855
fix: Resolve ReDoS security hotspot in health check service ID extrac…
NickLetts2 May 26, 2026
134691e
fix: Resolve security hotspots in billing service test file
NickLetts2 May 26, 2026
fda939b
fix: Simplify Docker Buildx load for more reliable Trivy scanning
NickLetts2 May 26, 2026
1247b1b
Fix app-frontend CI build typing and Trivy SARIF upload gating
NickLetts2 May 26, 2026
ce8d0b1
chore(deps): bump the github-actions-all group across 1 directory wit…
dependabot[bot] May 26, 2026
5da3c77
Clean up Sonar findings across frontend and Dockerfiles
NickLetts2 May 26, 2026
ab4c02e
Allow exact pinned requirements with markers
NickLetts2 May 26, 2026
3446f16
Fix Sonar maintainability findings batch
NickLetts2 May 26, 2026
f8b7e7e
Remove deprecated Authentik auth harness
NickLetts2 May 26, 2026
baf9ff7
Merge pull request #327 from NickLetts2/dependabot/npm_and_yarn/apps/…
NickLetts2 May 26, 2026
15015e3
Merge pull request #324 from NickLetts2/dependabot/github_actions/git…
NickLetts2 May 26, 2026
d17455c
Merge pull request #326 from NickLetts2/dependabot/pip/services/admin…
NickLetts2 May 26, 2026
15d9754
chore: apply sonar maintainability remediation batch
NickLetts2 May 26, 2026
72c0f07
Initial plan
Copilot May 26, 2026
d4b71a5
fix(marketing-site): pin vite 8.0.8 and unblock Astro build
Copilot May 26, 2026
b994a16
Merge pull request #328 from NickLetts2/copilot/fix-marketing-site-do…
NickLetts2 May 26, 2026
69cf15f
refactor(.env): standardize environment configuration format and values
NickLetts2 May 27, 2026
4bb01e8
chore: continue maintainability remediation across services
NickLetts2 May 27, 2026
76553e5
fix: address sonar findings and test cleanup
NickLetts2 May 27, 2026
a77c03f
chore: improve local docker email and env refresh
NickLetts2 May 27, 2026
a61bde0
chore: apply Sonar cleanup and update blog seed content
NickLetts2 May 27, 2026
462d4bf
feat: add SMTP configuration and SSH access documentation for AI coders
NickLetts2 May 27, 2026
4275f86
feat: enhance e2e testing with cleanup scripts and Docker integration
NickLetts2 May 28, 2026
eb3e50f
fix sonar findings and unblock checks
NickLetts2 May 28, 2026
f59e3ed
Fix production-shaped payment routing
NickLetts2 May 28, 2026
35453f5
Fix Traefik Prometheus target routing
NickLetts2 May 28, 2026
0447cbe
feat: add support for canceling subscription status and update relate…
NickLetts2 May 28, 2026
f566a79
feat: add dynamic sitemap endpoint for SEO indexing
NickLetts2 May 28, 2026
45311cd
fix: add sitemap redirect for /sitemap → /sitemap.xml compatibility
NickLetts2 May 28, 2026
9239ab2
fix: make promote_from_staging the default for production deployments
NickLetts2 May 28, 2026
c21ba9b
feat: add dynamic blog post indexing to sitemap with lastmod dates
NickLetts2 May 28, 2026
840cfc1
fix: use published dates (start_date) instead of updated dates in sit…
NickLetts2 May 28, 2026
2ba4191
Add new pages for ATS CV Checker, CV Score Checker, CV Tailoring Tool…
NickLetts2 May 29, 2026
3e05e04
fix: update sitemap link in head and refine footer navigation links
NickLetts2 May 29, 2026
04cd8a7
feat: Add ATS score calculation and reporting to CV advice
NickLetts2 May 29, 2026
e7e96e0
fix: add CVE-2026-39823, 39825, 39826 to pgbackrest Trivy ignore list
NickLetts2 May 29, 2026
beeb2cd
fix: add defensive optional chaining for atsScore in cv-advice display
NickLetts2 May 29, 2026
8548fed
fix: redesign ATS compatibility layout and add robust null checks
NickLetts2 May 29, 2026
4dd803c
feat: implement responsive 60/40 layout for CV Feedback header
NickLetts2 May 29, 2026
7458f47
Simplify backup readiness dashboard signal logic
NickLetts2 May 29, 2026
3d62c89
Re-layout backup dashboard into 4-row matrix
NickLetts2 May 29, 2026
050a166
Treat absent replication lag metric as single-node N/A
NickLetts2 May 29, 2026
84c8d7d
feat: implement database migration stage with dedicated credentials a…
NickLetts2 May 29, 2026
e3b5621
Start observability upgrade foundation
NickLetts2 May 29, 2026
747a4a0
feat: complete observability telemetry and correlation-id hardening
NickLetts2 May 29, 2026
6a54508
merge: observability-dashboard-telemetry-upgrade into main
NickLetts2 May 29, 2026
11ccf44
chore: fix Windows pre-commit portability
NickLetts2 May 29, 2026
5d6342f
fix: harden staging deploy env and pgbackrest host-key handling
NickLetts2 May 29, 2026
0b342af
fix: make storagebox known-host refresh non-fatal on prod
NickLetts2 May 29, 2026
2b870a5
Initial plan
Copilot May 30, 2026
59a13a5
feat: content platform refactor - unified content model, API, migrati…
Copilot May 30, 2026
825e3d7
fix: handle invalid UUID fields gracefully and normalize SQL casing i…
Copilot May 30, 2026
0a1f53d
Add repository interfaces/implementations, refactor controllers, add …
Copilot May 30, 2026
748d84e
WIP: billing-service DB refactoring done, starting admin-service
Copilot May 30, 2026
05393ba
fix: refactor admin-service + billing-service to use core-api interna…
Copilot May 30, 2026
abba9f3
Potential fix for pull request finding
NickLetts2 May 30, 2026
2bab7f9
Potential fix for pull request finding
NickLetts2 May 30, 2026
05f7a99
Potential fix for pull request finding
NickLetts2 May 30, 2026
13bbfaa
fix: use .env.example for dev compose validation in observability CI …
Copilot May 30, 2026
26b586c
fix: use .env.example for dev compose validation in observability CI …
Copilot May 30, 2026
1e1bd10
Potential fix for pull request finding
NickLetts2 May 30, 2026
ddb7989
Potential fix for pull request finding
NickLetts2 May 30, 2026
aa26d5c
Potential fix for pull request finding
NickLetts2 May 30, 2026
08ae476
Merge pull request #333 from NickLetts2/copilot/content-platform-refa…
NickLetts2 May 30, 2026
04adffc
Initial plan
Copilot May 30, 2026
657a869
feat(content-ui): add articles detail page, sitemap, and docs
Copilot May 30, 2026
6898236
refactor(content-ui): address code review feedback
Copilot May 30, 2026
c3c2486
refactor(content-ui): address remaining code review feedback
Copilot May 30, 2026
2de8391
fix(content-ui): add escape param to ilike calls and document sitemap…
Copilot May 30, 2026
ab9dbc0
fix(content-ui): extract MS_PER_DAY constant and polish review comments
Copilot May 30, 2026
b7fadb1
Potential fix for code scanning alert no. 298: Workflow does not cont…
NickLetts2 May 30, 2026
7dcb74a
Merge pull request #335 from NickLetts2/alert-autofix-298
NickLetts2 May 30, 2026
04063ad
Merge pull request #334 from NickLetts2/copilot/featurecontent-ui-ref…
NickLetts2 May 30, 2026
5c4baa3
Initial plan
Copilot May 30, 2026
2fa14e8
feat: add curvit-content-creator service (issue #331)
Copilot May 30, 2026
051b787
fix: address code review and CodeQL findings in content-creator
Copilot May 30, 2026
3dfe915
Potential fix for pull request finding 'CodeQL / Incomplete URL subst…
NickLetts2 May 30, 2026
1767918
fix: address PR #336 review feedback in content-creator workflow
Copilot May 30, 2026
a70ed3f
Merge pull request #336 from NickLetts2/copilot/featureai-content-cre…
NickLetts2 May 30, 2026
442b233
Initial plan
Copilot May 30, 2026
c3a7163
Wire content-creator into staging/prod CI-CD image flow
Copilot May 30, 2026
119f176
Merge pull request #337 from NickLetts2/copilot/add-content-creator-s…
NickLetts2 May 30, 2026
1b2adad
Bump the nuget-all group with 4 updates
dependabot[bot] May 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
61 changes: 16 additions & 45 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,24 @@
"permissions": {
"allow": [
"Write(*)",
"Bash(git:*)",
"Bash(npm:*)",
"Bash(cmd.exe:*)",
"Bash(powershell.exe:*)",
"Bash(grep:*)",
"Bash(mkdir:*)",
"Bash(pdftotext: *)",
"Bash(find: *)",
"Bash(\"d:/Projects/Curvit/.env.example\":*)",
"Bash(\"d:/Projects/Curvit/infrastructure/postgres/init.sql\":*)",
"Bash(\"d:/Projects/Curvit/infrastructure/redis/redis.conf\":*)",
"Bash(\"d:/Projects/Curvit/infrastructure/traefik/traefik.yml\":*)",
"Bash(\"d:/Projects/Curvit/infrastructure/traefik/dynamic/middlewares.yml\":*)",
"Bash(\"d:/Projects/Curvit/infrastructure/traefik/dynamic/routes.yml\":*)",
"Bash(\"d:/Projects/Curvit/services/core-api/src/Curvit.Domain/Curvit.Domain.csproj\":*)",
"Bash(\"d:/Projects/Curvit/services/core-api/src/Curvit.Application/Curvit.Application.csproj\":*)",
"Bash(__NEW_LINE_5c5965c4013e726c__ cat:*)",
"Bash(\"d:/Projects/Curvit/services/core-api/src/Curvit.Infrastructure/Curvit.Infrastructure.csproj\":*)",
"Bash(\"d:/Projects/Curvit/services/core-api/src/Curvit.Api/Curvit.Api.csproj\":*)",
"Bash(\"d:/Projects/Curvit/services/core-api/src/Curvit.Api/Dockerfile\":*)",
"Bash(\"d:/Projects/Curvit/services/core-api/tests/Curvit.UnitTests/Curvit.UnitTests.csproj\":*)",
"Bash(\"d:/Projects/Curvit/services/core-api/tests/Curvit.IntegrationTests/Curvit.IntegrationTests.csproj\":*)",
"Bash(\"d:/Projects/Curvit/apps/app-frontend/Dockerfile\":*)",
"Bash(docker:*)",
"Bash(ls /d/Projects/Curvit/apps/app-frontend/src/app/\"\\(auth\\)\")",
"Bash(ls /d/Projects/Curvit/apps/app-frontend/src/app/\"\\(auth\\)\"/dashboard)",
"Bash(python -m json.tool)",
"Bash(find /d/Projects/Curvit/apps/marketing-site -name vitest* -o -name playwright* -o -name *.config.*)",
"Bash(find /d/Projects/Curvit/apps/marketing-site -name *.test.* -o -name *.spec.*)",
"Bash(find /d/Projects/Curvit/apps/marketing-site -type f \\\\\\(-name *.astro -o -name *.ts -o -name *.js -o -name *.json -o -name *.css -o -name *.md -o -name *.svg -o -name *.txt \\\\\\) ! -path */node_modules/* ! -path */.astro/* ! -path */dist/*)",
"Bash(xargs ls:*)",
"Bash(for dir:*)",
"Bash(do echo:*)",
"Read(//d/Projects/Curvit/services/**)",
"Bash(done)",
"Read(//d/Projects/Curvit/workers/**)",
"Bash(grep -m1 \"\"\"node\"\"\" \"d:/Projects/Curvit/apps/marketing-site/package.json\")",
"Bash(ls d:/Projects/Curvit/apps/app-frontend/next.config*)",
"Bash(cat d:/Projects/Curvit/apps/app-frontend/next.config*)",
"Bash(python3 -c \"import sys,json; [print\\(json.loads\\(l\\).get\\(''''event'''',''''''''\\)[:120], json.loads\\(l\\).get\\(''''status'''',''''''''\\), json.loads\\(l\\).get\\(''''user'''',''''''''\\)\\) for l in sys.stdin if l.strip\\(\\)]\")",
"Bash(curl -s http://localhost:9090/api/v1/targets)",
"Bash(curl -s \"http://localhost:9090/api/v1/query?query=up%3D%3D0\")",
"Bash(curl -s -X POST http://localhost:9090/-/reload)"
"Read(*)",
"Bash(*)",
"WebSearch",
"WebFetch(domain:raw.githubusercontent.com)",
"WebFetch(domain:github.com)",
"Bash(ssh -i /c/Users/nickl/.ssh/id_ed25519 root@204.168.191.25 \"docker logs -f curvit-clamavd 2>&1 | grep --line-buffered -E 'socket found|clamd started|ERROR|WARN|Limits|ready'\")",
"Bash(ssh -i /c/Users/nickl/.ssh/id_ed25519 root@204.168.191.25 \"docker logs curvit-clamavd --since=5m 2>&1 | grep --line-buffered -E 'socket found|clamd started|ERROR|FATAL|Limits: Global time'\")",
"PowerShell(*)",
"Bash(gh run *)",
"Bash(ssh root@204.168.191.25 'curl -s https://api.staging.curvit.co.uk/health 2>/dev/null | grep -q \"Healthy\"')",
"Bash(ssh root@204.168.191.25 'docker ps | grep -iE \"clamav.*healthy|postgres.*healthy|redis.*healthy\" | wc -l')",
"Bash(ssh root@204.168.191.25 'docker logs --tail 1 curvit-core-api 2>&1')",
"Bash(echo \"Core-API starting up... $\\(ssh root@204.168.191.25 'docker logs --tail 1 curvit-core-api 2>&1')",
"WebFetch(domain:sonarcloud.io)"
],
"additionalDirectories": [
"d:\\Projects\\Curvit\\apps\\app-frontend\\src\\app\\api\\auth",
"d:\\Projects\\Curvit\\.github\\workflows"
"d:\\Projects\\Curvit\\**",
"\\tmp"
]
}
}
Binary file added .coverage
Binary file not shown.
271 changes: 184 additions & 87 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,91 +1,188 @@
# ─────────────────────────────────────────────────────────────────────────────
# Curvit — local development environment variables
#
# Copy this file to .env and fill in all values before running docker compose.
# .env is gitignored and must NEVER be committed to version control.
#
# DISASTER RECOVERY NOTE
# If you lose your .env, this file documents every variable you need to
# recreate it. All Authentik configuration (flows, providers, stages) is
# rebuilt automatically from the blueprint on first startup. The secrets
# below are the only thing that cannot be recovered from the repository.
# ─────────────────────────────────────────────────────────────────────────────


# ── PostgreSQL ────────────────────────────────────────────────────────────────
# Shared password for the curvit and authentik databases.
# Generate: openssl rand -base64 24
POSTGRES_PASSWORD=changeme


# ── Authentik identity provider ───────────────────────────────────────────────
# Random 64-character hex key used to sign Authentik tokens and cookies.
# If this key changes, ALL active Authentik sessions are immediately invalidated.
# Generate: openssl rand -hex 32
AUTHENTIK_SECRET_KEY=changeme-generate-with-openssl-rand-hex-32

# Bootstrap credentials for the built-in akadmin superuser account.
# These are only used on the FIRST startup when no admin account exists.
# After that, changing them here has no effect — use the Authentik UI to
# change the password. akadmin is the only account with access to the
# Authentik admin interface (/if/admin/).
AUTHENTIK_ADMIN_EMAIL=your-email@example.com
AUTHENTIK_ADMIN_PASSWORD=changeme


# ── Google OAuth (Authentik social source) ────────────────────────────────────
# Google OAuth 2.0 credentials used by Authentik to provide "Sign in with
# Google" for Curvit app users.
#
# How to obtain:
# 1. Go to console.cloud.google.com → APIs & Services → Credentials
# 2. Create an OAuth 2.0 Client ID (Web application)
# 3. Add authorised redirect URI:
# http://localhost:9000/source/oauth/callback/google/
# 4. For production, also add the production Authentik callback URL.
AUTHENTIK_GOOGLE_CLIENT_ID=changeme.apps.googleusercontent.com
AUTHENTIK_GOOGLE_CLIENT_SECRET=changeme


# ── OIDC client credentials (Authentik ↔ app-frontend) ───────────────────────
# The client ID and secret for the Curvit OIDC provider registered in Authentik.
# These are injected into Authentik via the blueprint (using !Env tags) and must
# match the values used by the app-frontend.
#
# Choose any stable values — they are not auto-generated. Use a UUID or a
# random string for the secret:
# Generate secret: openssl rand -hex 32
#
# After first startup, verify these are set correctly in the Authentik admin UI:
# Applications → Providers → curvit-oidc-provider → Edit
AUTH_AUTHENTIK_ID=curvit-client-id
AUTH_AUTHENTIK_SECRET=changeme-generate-with-openssl-rand-hex-32


# ── Auth.js (app-frontend session signing) ────────────────────────────────────
# Random secret used to sign and encrypt Auth.js JWT session tokens.
# If this key changes, ALL active app-frontend sessions are immediately
# invalidated (users are logged out).
# Generate: openssl rand -hex 32
# Curvit - Local Development Environment Variables (Example)
# Copy this file to .env and fill in all values marked with "changeme-".
# The local .env is gitignored and must never be committed.

# ============================================================================
# ENVIRONMENT & APPLICATION CONFIGURATION
# ============================================================================

NODE_ENV=production
NEXT_PUBLIC_APP_ENV=development
APP_ENV=development
LOG_LEVEL=debug
AUTH_DEBUG=1
SHOW_DEV_TOOLS=false
SCANNER_FAIL_OPEN=false
PAYMENT_PROVIDER=local_sandbox

# ============================================================================
# PUBLIC URLS AND SERVICE ENDPOINTS
# ============================================================================

APP_BASE_URL=https://app.curvit.local.co.uk
APP_CALLBACK_URL=https://app.curvit.local.co.uk/api/auth/callback/authentik
APP_FAVICON_URL=https://app.curvit.local.co.uk/favicon.ico
MARKETING_URL=https://curvit.local.co.uk
PUBLIC_APP_URL=https://app.curvit.local.co.uk
NEXT_PUBLIC_API_URL=https://api.curvit.local.co.uk

# ============================================================================
# CORE INFRASTRUCTURE
# ============================================================================

POSTGRES_USER=curvit
POSTGRES_PASSWORD=changeme-generate-with-openssl-rand-base64-24
REDIS_PASSWORD=changeme-generate-with-openssl-rand-base64-24
INTERNAL_API_KEY=changeme-generate-with-openssl-rand-hex-32

# ============================================================================
# DATABASE & CACHE
# ============================================================================

DATABASE_URL=postgresql+asyncpg://curvit:PASSWORD@postgres:5432/curvit
POSTGRES_URL=postgresql://curvit:PASSWORD@postgres:5432/curvit

# ============================================================================
# BACKUP ENCRYPTION (PGBACKREST)
# ============================================================================

# Backup encryption passphrase (AES-256-CBC)
PGBACKREST_REPO1_CIPHER_PASS=changeme-generate-with-openssl-rand-base64-32

# Optional Hetzner Storage Box credentials (only used by deploy.sh)
# STORAGEBOX_USER=u575805
# STORAGEBOX_HOST=u575805.your-storagebox.de
# STORAGEBOX_REMOTE_PATH=backrest/staging

# ============================================================================
# AUTHENTICATION (AUTH.JS / GOOGLE OAUTH)
# ============================================================================

AUTH_URL=https://app.curvit.local.co.uk
AUTH_SECRET=changeme-generate-with-openssl-rand-hex-32
AUTH_TRUST_HOST=true
CONSENT_COOKIE_DOMAIN=

# Google OAuth direct provider
AUTH_GOOGLE_ID=changeme.apps.googleusercontent.com
AUTH_GOOGLE_SECRET=changeme

# ============================================================================
# CORE API
# ============================================================================

CORE_API_BASE_URL=http://core-api:5000
INTERNAL_API_URL=http://core-api:5000

# ============================================================================
# INTERNAL SERVICES
# ============================================================================

INTERNAL_APP_URL=http://app-frontend:3000
ORCHESTRATOR_URL=http://ai-orchestrator:8000
Orchestrator__BaseUrl=http://ai-orchestrator:8000
INGESTION_SERVICE_URL=http://document-ingestion-service:8001
DocumentIngestion__BaseUrl=http://document-ingestion-service:8001
BILLING_SERVICE_URL=http://billing-service:8000
CMS_SERVICE_URL=http://cms-service:8000
MESSAGING_SERVICE_URL=http://messaging-service:8000
ContentSanitiser__BaseUrl=http://content-sanitiser:8000
SCANNER_URL=http://clamav-rest:8080
VALIDATOR_URL=http://output-validator:8000

# ============================================================================
# FRONTEND CONFIGURATION
# ============================================================================

AppFrontend__BaseUrl=https://app.curvit.local.co.uk
Cors__AllowedOrigins__0=https://app.curvit.local.co.uk

# ============================================================================
# AI SERVICES (ANTHROPIC)
# ============================================================================

# Model selection: claude-haiku-4-5-20251001 (default, cost-efficient)
# claude-sonnet-4-6 (balanced)
# claude-opus-4-7 (most capable)
# ANTHROPIC_MODEL=claude-haiku-4-5-20251001
ANTHROPIC_API_KEY=changeme-or-leave-blank-for-local-testing
ANTHROPIC_MAX_CONCURRENT_REQUESTS=2
ANTHROPIC_MAX_RETRIES=3
ANTHROPIC_RETRY_BASE_S=1

# ============================================================================
# EMAIL DELIVERY
# ============================================================================

# Local development always sends via Mailpit (see docker-compose.yml)
EMAIL_FROM_ADDRESS=noreply-dev@curvit.local.co.uk
EMAIL_ADMIN_ADDRESS=support-dev@curvit.local.co.uk
EMAIL_SMTP_HOST=mailpit
EMAIL_SMTP_PORT=1025
RESEND_API_KEY=changeme

# ============================================================================
# ANALYTICS AND CONSENT
# ============================================================================

GA_MEASUREMENT_ID=
CONSENT_COOKIE_DOMAIN=

# ============================================================================
# MONITORING & OBSERVABILITY
# ============================================================================

ADMIN_SERVICE_URL=http://admin-service:8000
ADMIN_GRAFANA_URL=https://grafana.curvit.local.co.uk
ADMIN_PROMETHEUS_URL=https://prometheus.curvit.local.co.uk
ADMIN_DOZZLE_URL=https://dozzle.curvit.local.co.uk
ADMIN_NOTIFICATION_EMAIL=alerts-dev@curvit.local.co.uk

# Basic auth users for monitoring dashboards
# Format: username:$2y$05$hashed_password (Apache bcrypt hash)
# Generate with: htpasswd -cbc /dev/stdout admin
MONITORING_AUTH_USERS=admin:changeme-with-bcrypt-hash

# ============================================================================
# GRAFANA CONFIGURATION
# ============================================================================


# ─────────────────────────────────────────────────────────────────────────────
# The variables below are already hardcoded in docker-compose.yml for local
# development. You do NOT need to set them in .env for a standard local setup.
# They are documented here for reference and for non-Docker deployments.
# ─────────────────────────────────────────────────────────────────────────────

# ── Grafana ───────────────────────────────────────────────────────────────────
# Password for the Grafana admin account (username: admin).
# Defaults to "admin" if not set — override for any shared environment.
# Grafana is available at http://localhost:3001
GRAFANA_ADMIN_PASSWORD=changeme


# AUTH_URL=http://localhost:3000
# AUTH_AUTHENTIK_ISSUER=http://localhost:9000/application/o/curvit/
# AUTH_AUTHENTIK_INTERNAL_URL=http://authentik-server:9000
# MARKETING_URL=http://localhost:4321
# NEXT_PUBLIC_API_URL=http://localhost:5000
# INTERNAL_API_URL=http://core-api:5000
# Anonymous access to dashboards
GRAFANA_AUTH_ANONYMOUS_ENABLED=true
GRAFANA_AUTH_ANONYMOUS_ORG_ROLE=Viewer
GRAFANA_AUTH_DISABLE_LOGIN_FORM=true
GRAFANA_AUTH_BASIC_ENABLED=false

# SMTP alert notifications (captured by Mailpit in local dev)
GRAFANA_SMTP_ENABLED=true
GRAFANA_SMTP_HOST=mailpit:1025
GRAFANA_SMTP_USER=
GRAFANA_SMTP_PASSWORD=
GRAFANA_SMTP_FROM_ADDRESS=alerts@curvit.local.co.uk
GRAFANA_SMTP_FROM_NAME=Curvit Alerts (Dev)

# ============================================================================
# PAYMENT PROCESSING
# ============================================================================

# Local development uses the Curvit payment sandbox.
# It accepts Stripe-style test cards locally and signs local-only webhook deliveries.
# See docs/testing/payment-testing.md for payment testing procedures.

STRIPE_SECRET_KEY=sk_test_changeme
STRIPE_WEBHOOK_SECRET=whsec_changeme

# ============================================================================
# RUNTIME TUNING & LOCAL DEBUGGING
# ============================================================================

# ClamAV malware scanner should stay fail-closed in development
SCANNER_FAIL_OPEN=false

# Local-only debugging and runtime toggles
SKIP_ENV_VALIDATION=0
DISABLE_URL_REWRITES=0
NEXT_PUBLIC_DISABLE_URL_REWRITES=0
ANALYSIS_WORKER_CONCURRENCY=4
Loading
Loading