Files
babymonitor/plan_5_prompt.md
T
2026-06-24 15:30:47 +02:00

164 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.