diff --git a/.planning/phases/06-performance-production-hardening/06-03-SUMMARY.md b/.planning/phases/06-performance-production-hardening/06-03-SUMMARY.md new file mode 100644 index 0000000..967c488 --- /dev/null +++ b/.planning/phases/06-performance-production-hardening/06-03-SUMMARY.md @@ -0,0 +1,61 @@ +--- +plan: 06-03 +phase: 06-performance-production-hardening +status: complete +completed_at: 2026-06-03 +commits: + - fb35f0e + - 5a93257 +self_check: PASSED +--- + +# Plan 06-03: Locust Load Test Implementation + +## What was built + +Full Locust load test for Phase 6 SLA verification (D-04, D-05, D-06). + +### Files created + +| File | Purpose | +|------|---------| +| `backend/requirements-dev.txt` | Dev-only deps with `locust>=2.34.0`; includes `-r requirements.txt` | +| `backend/load_tests/locustfile.py` | Full DocuVaultUser implementation (121 lines) | +| `backend/load_tests/README.md` | Operator guide: install, run command, env vars, SLA semantics, cleanup | + +### Key decisions + +**Credential strategy: Option A (self-bootstrapping)** +`on_start()` calls `POST /api/auth/register` (409 silently ignored), then `POST /api/auth/login`. Zero out-of-band setup; works against a clean DB. + +**Upload endpoint: direct `/api/documents/upload`** +Confirmed against `backend/api/documents.py`: accepts `UploadFile file` + `Form target_backend="minio"`. Used over the presigned-URL flow (upload-url → MinIO PUT → confirm) because it is a single HTTP call from the Locust process perspective, simpler to implement correctly, and exercises the same code path for performance measurement. + +**Task weights (D-05 realistic session)** +| Task | Weight | Endpoint | +|------|--------|----------| +| list_documents | 5 | GET /api/documents/ | +| get_document | 3 | GET /api/documents/{id} | +| upload_document | 2 | POST /api/documents/upload | +| refresh_token | 1 | POST /api/auth/refresh | + +**SLA listener (D-06)** +`@events.quitting.add_listener check_sla` reads `stats.total.get_response_time_percentile(0.95/0.99)` and `fail_ratio`. Sets `environment.process_exit_code = 1` if: fail_ratio > 1%, p95 > 200ms, or p99 > 500ms. + +## Acceptance criteria verification + +- `locust` in requirements-dev.txt only (not requirements.txt): ✓ +- Syntax valid (`ast.parse`): ✓ +- `class DocuVaultUser`: 1 ✓ +- No `raise NotImplementedError` stubs: 0 ✓ +- `events.quitting.add_listener`: 1 ✓ +- `@task` decorators: 4 ✓ +- p95 and p99 references: present ✓ +- No application code imports: 0 ✓ +- README.md with LOAD_TEST_EMAIL documentation: ✓ + +## Notes for downstream plans + +- Plan 06-06 should reference this file in the RUNBOOK.md under the "Load Testing" section +- The load test user (`loadtest@example.com`) will persist in the DB after a run — operator cleanup documented in README.md +- Locust is intentionally excluded from the production Dockerfile; the production requirements.txt is unchanged