## Implementation Plan: Fix Notification Dismissal Marking DMs as Read ### Changes Required 1. **`devplacepy/routers/messages.py` – Remove premature `mark_conversation_read` call (line 156)** Delete the line: ```python mark_conversation_read(user["uid"], with_uid) # ← THE BUG ``` Keep `mark_notifications_read_by_target(user["uid"], other_user["uid"])` on the next line. 2. **No changes to WebSocket handler (`messages.py:312-315`)** – the `"read"` message handler correctly marks conversations read only when the user has an active WebSocket connection. 3. **No changes to client-side `MessagesLayout.js`** – the `markRead()` function (constructor + WebSocket ready + on incoming message) remains the sole mechanism for marking DMs read after the user actually views the conversation. 4. **Add a regression test** that verifies the critical path: clicking a notification → redirect to `/messages?with_uid=...` → **must not** set `messages.read = 1`. Place the test in `tests/unit/` (e.g., `tests/unit/test_notification_dm_read.py`). The test should: - Use an in-memory SQLite database (same pattern as `tests/unit/database.py`). - Insert a user, another user, an unread message, and a notification for that message. - Make a GET request to `/notifications/open/{notification_uid}` (using `TestClient` if available, or directly call the route logic). - After processing the redirect target (`/messages?with_uid=...`), query the database to confirm `messages.read = 0` for that message. - Optionally, simulate a WebSocket `"read"` event and verify the message becomes `read = 1`. ### Definition of Done - [ ] **Line removed**: `mark_conversation_read(user["uid"], with_uid)` no longer exists in `devplacepy/routers/messages.py`. - [ ] **Existing behavior preserved**: - WebSocket handler (`messages.py:312-315`) still calls `mark_conversation_read`. - Client `markRead()` in `MessagesLayout.js` remains unchanged. - `mark_notifications_read_by_target` in `GET /messages` still runs (notification badge state). - `POST /notifications/mark-read/{uid}` (× dismiss) remains clean. - [ ] **New unit test added** at `tests/unit/test_notification_dm_read.py` that: - Passes when `/notifications/open/{uid}` → `/messages?with_uid=...` does **not** set `messages.read = 1`. - Passes when a WebSocket `"read"` event (or simulated equivalent) correctly marks the message read. - [ ] **`pip install -e '.[dev]' -q && make test-unit`** runs without error and all tests pass (including the new one). - [ ] **`pip install -q ruff && ruff check .`** reports no lint errors (exit 0).