**Implementation Plan: Add Vote Value 0 for Retraction** **Objective** Enable the `POST /votes/{target_type}/{target_uid}` endpoint to accept `{"value": 0}` as a valid request, allowing clients to retract a vote in a single call. The core logic (`apply_vote`) already handles `value=0`; only the Pydantic validator blocks it. --- ### Changes Required | File | Change | Rationale | |------|--------|-----------| | `devplacepy/models.py:442` | Expand the validator tuple from `(1, -1)` to `(-1, 0, 1)` (order irrelevant) | This is the single root cause – the form-level Pydantic field validator rejects `0`. | | `devplacepy/services/devii/actions/catalog/engagement.py:25-28` | Update the `value` parameter description to include `0` for retraction (e.g., `"Vote value: 1 to upvote, -1 to downvote, 0 to retract."`) | Keeps the action catalog consistent with the new behaviour. | | `tests/api/votes.py` | Add a new test function `test_explicit_zero_retracts_vote` that:
1. Inserts an upvote (value=1).
2. Sends `{"value": 0}`.
3. Validates the response has `"value": 0` and `"net": 0` (or unchanged from initial).
4. Optionally verifies the row is soft-deleted or updated correctly. | Explicit `value=0` has no test coverage. Adding one ensures the new path is exercised. | **Do not modify any other files.** No database, content logic, template, or documentation changes are required. --- ### Execution Steps (for a competent engineer) 1. **Check out a clean branch** from the current base (e.g. `git checkout -b vote-zero-retraction` off `main` or `develop`). *Do not attempt to rebase onto a branch that has unresolved conflicts.* 2. **Apply the three changes above** using your editor or `sed`. 3. **Run lint**: ```bash pip install -q ruff && ruff check . ``` No new violations should appear. (Existing warnings outside changed files are acceptable.) 4. **Run unit tests**: ```bash pip install -e '.[dev]' -q && make test-unit ``` All tests must pass. The pre-existing `test_owns_instance_true_for_creator` failure observed in earlier attempts is **not caused by these changes** (no file touched affects `content.py`). If that test fails, it indicates a pre-existing issue in the base branch or environment; the engineer should flag it but not consider it a blocker for this change unless it is newly introduced. (Verification of this commit on a clean base should produce a clean run.) 5. **Commit** with a message like `Allow vote value 0 for retraction` and push. --- ### Definition of Done - [ ] The Pydantic validator at `devplacepy/models.py:442` accepts value `0` in addition to `1` and `-1`. - [ ] The Devii action catalog description at `devplacepy/services/devii/actions/catalog/engagement.py:25` mentions `0` as a valid vote value for retraction. - [ ] A new test `test_explicit_zero_retracts_vote` exists in `tests/api/votes.py` and passes. - [ ] `ruff check .` passes with no new violations. - [ ] `make test-unit` passes (all tests green, ignoring any pre-existing failures unrelated to this change). - [ ] No other files are modified.