Add 5 plans

This commit is contained in:
2026-06-24 15:30:47 +02:00
parent 5348bedb86
commit d97d8c6cf4
5 changed files with 644 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
# Plan 5 — Observability & Test Coverage
**Items covered:** #10 (no logging), #12 (missing test coverage)
---
## Context
You are working on a FastAPI backend for a baby monitor / sleep tracker app. The codebase lives under `app/`. This is the final plan. Plans 1–4 must already be complete — this plan assumes auth returns 401, malformed parameters return 422, and `updated_at` is updated on PATCH/PUT.
Do the logging setup first (it is quick), then work through the missing tests methodically. Add tests one group at a time and run `pytest` after each group.
---
## Tasks
### 1. Add structured logging (`app/main.py` and other files)
#### Step 1 — Read `app/config.py` and `app/main.py` first
Confirm that `LOG_LEVEL` already exists in `Settings` (it does — it is currently defined but never consumed). Note its default value.
#### Step 2 — Configure logging in `main.py`
At the top of `app/main.py`, before the app is created, add:
```python
import logging
logging.basicConfig(
level=settings.LOG_LEVEL,
format="%(asctime)s %(levelname)s %(name)s %(message)s",
)
logger = logging.getLogger(__name__)
```
#### Step 3 — Add request logging middleware
Add a simple middleware to log every request and response status:
```python
import time
from fastapi import Request
@app.middleware("http")
async def log_requests(request: Request, call_next):
start = time.time()
response = await call_next(request)
duration_ms = (time.time() - start) * 1000
logger.info(
"%s %s → %s (%.1fms)",
request.method,
request.url.path,
response.status_code,
duration_ms,
)
return response
```
#### Step 4 — Add business event logging
In the relevant router files, add a `logger = logging.getLogger(__name__)` at the module level and log the key business events:
- Session started: `logger.info("Session started id=%s", session.id)`
- Session ended: `logger.info("Session ended id=%s duration_min=%.1f", session.id, ...)`
- Session deleted: `logger.info("Session deleted id=%s", session_id)`
Keep log messages concise. Do not log sensitive user data.
#### Step 5 — Verify
Run the tests:
```bash
pytest
```
Logging must not break any existing tests.
---
### 2. Add missing test coverage (`tests/`)
Read the existing test files before adding anything so you understand the test client setup, fixtures, and conventions already in use. Add all new tests to appropriate existing files (or a new file if clearly warranted — e.g. `tests/test_stats.py` if one does not exist).
Work through each group below. After adding each group, run `pytest` and fix any failures before continuing.
---
#### Group A — Stats endpoints: empty date ranges
For each stats endpoint (`/api/stats/daily-summary`, `/api/stats/timetable`, `/api/stats/wake-sleep-times`), add a test that:
- Calls the endpoint with a valid date range that has no sessions
- Asserts a 200 response
- Asserts the response body represents an empty result (no days, empty list, etc.)
---
#### Group B — Stats endpoints: session spanning midnight
Add a test that:
- Creates a session with `start_time` on day N at 23:00 and `end_time` on day N+1 at 07:00
- Calls `/api/stats/timetable` for a range covering both days
- Asserts that the session appears in both days' slot data
---
#### Group C — Stats endpoints: session partially overlapping the query range
Add a test that:
- Creates a session that starts before the query range and ends inside it
- Calls each stats endpoint with the range
- Asserts the session is counted/included correctly (it should be, since it overlaps the range)
---
#### Group D — Stats endpoints: multiple sessions on the same day
Add a test that:
- Creates two or more sessions on the same day
- Calls `/api/stats/daily-summary` for that day
- Asserts that the totals correctly aggregate across both sessions
---
#### Group E — Invalid query parameters return 422
These tests depend on Plan 2 (silent suppression replaced with 422). Add a parametrised test (or individual tests) for:
- `/api/stats/daily-summary` with `day_start=not-a-time` → expect 422
- `/api/stats/timetable` with `day_start=not-a-time` → expect 422
- Any other endpoint that previously silently suppressed a `ValueError`
---
#### Group F — Bounded `limit` parameter
This test depends on Plan 4 (Query bound added). Add tests for:
- `GET /api/sessions?limit=0` → expect 422
- `GET /api/sessions?limit=1000001` → expect 422
- `GET /api/sessions?limit=1` → expect 200
- `GET /api/sessions?limit=1000` → expect 200
---
#### Group G — `updated_at` regression
This test depends on Plan 1 (updated_at bug fixed). Add a test that:
- Creates a session
- Records the `updated_at` value
- Sends a PUT/PATCH request to update it
- Asserts that `updated_at` in the response is strictly greater than the original value
---
## Final verification
Run the complete test suite one last time:
```bash
pytest --tb=short
```
All tests must pass. Review the output for any warnings. This completes all 15 improvements from the backend improvement report.