**Implementation Plan: Expose Level Progress in Profile API** **Objective** Add derived fields `xp_progress_pct` (integer percentage toward next level) and `xp_next_level` (total XP required for next level) to `GET /profile` and `GET /profile/{username}` responses. **1. Schema Change** *File*: `devplacepy/schemas/profile.py` - In class `ProfileOut` (line 29–82), add two optional integer fields: `xp_progress_pct: Optional[int] = None` `xp_next_level: Optional[int] = None` These fields are optional to avoid breaking existing consumers and because the value is computed at request time. **2. Route Handler Computation** *File*: `devplacepy/routers/profile/index.py` `profile_page()` function (starting line 128). Locate the `respond()` call at line 383–445. Before that call, compute: ```python LEVEL_XP = 100 # constant from devplacepy/utils/rewards.py xp = user.xp or 0 xp_progress_pct = xp % LEVEL_XP xp_next_level = ((xp // LEVEL_XP) + 1) * LEVEL_XP ``` Include these values in the context dict passed to `respond()`. For example: ```python context["xp_progress_pct"] = xp_progress_pct context["xp_next_level"] = xp_next_level ``` If `user.xp` is `None`, default to `0` for the computation. **3. Test Addition** *File*: `tests/api/profile/index.py` (add a new test function, e.g., `test_profile_contains_xp_progress`) - Create a test user with known XP (e.g., 250). - Perform `GET /profile` and `GET /profile/{username}`. - Assert that the JSON response contains `xp_progress_pct` and `xp_next_level`. - Assert that the values match the formula: - `xp_progress_pct` = 250 % 100 = 50 - `xp_next_level` = ((250 // 100) + 1) * 100 = 300 Use the existing test infrastructure (e.g., `test_client` fixture and `auth_headers`). **4. Verification** - Run the profile-specific test file: ```bash pip install -e '.[dev]' -q && python -m pytest tests/api/profile/index.py -v ``` - Confirm all tests pass (0 failures, 0 errors). - Optional: run a broader subset (e.g., `tests/api/`) to ensure no regressions, but the primary verification is the command above. **Definition of Done** - [ ] `ProfileOut` schema includes `xp_progress_pct` and `xp_next_level` fields. - [ ] `/profile` and `/profile/{username}` responses contain `xp_progress_pct` (0–99 integer) and `xp_next_level` (total XP for next level). - [ ] The new test `test_profile_contains_xp_progress` (or equivalent) exists and verifies the fields for at least one known XP value. - [ ] The command `pip install -e '.[dev]' -q && python -m pytest tests/api/profile/index.py` exits with code 0 and shows all tests passing. (Pre-existing Playwright-related failures in other test directories are unrelated and ignored for this change’s validation.)