readme, claude mds update info

This commit is contained in:
2026-09-15 23:20:30 +03:00
parent 7505f26c98
commit 962f250a8d
2 changed files with 89 additions and 8 deletions
+26 -5
View File
@@ -89,11 +89,17 @@ workers. Python >=3.13,<4.0, Poetry for dependency management.
`src/service/email/templates/`), inline CSS (email clients don't support
`<style>` reliably), `EmailMessage` with `set_content()` (plain-text
fallback) + `add_alternative(html, subtype="html")`.
- **Known gap**: the reset-password flow is a stub. `ResetEmailConsumer.process_message`
only prints and acks — it never calls a sender — and
`src/service/email/email_reset.py` is empty. `templates/reset.html` still
has a hardcoded placeholder password. Don't assume reset emails actually
send until this is wired up like `WelcomeEmailConsumer`/`DaemonEmailSender`.
- Reset-password flow mirrors welcome: `ResetEmailSender`
(`src/service/email/email_reset.py`) renders `templates/reset.html`
(`{{ temp_password }}`, no longer hardcoded) the same way
`DaemonEmailSender` does `welcome.html`. `ResetEmailConsumer.process_message`
reads both `email` and `temp_password` from the message body and uses the
same transient/permanent classification as `WelcomeEmailConsumer`.
`EmailProducer.send_reset_email(email, temp_password)` takes the password
as a second argument now. **Still missing**: nothing in the app actually
calls `send_reset_email` yet — there's no password-reset route that
generates a `temp_password` and publishes it. Don't assume the
reset-password feature is reachable end-to-end until that route exists.
## Logging (`src/logging/`)
@@ -204,3 +210,18 @@ workers. Python >=3.13,<4.0, Poetry for dependency management.
which broke refresh-token-cookie-dependent tests like logout).
- `test_user_fixture` is `indirect=True` parametrized with
`(direct_permissions, group)` tuples.
- `tests/unit/test_consumers.py` covers `RabbitMQClient`/`WelcomeEmailConsumer`/
`ResetEmailConsumer` entirely with mocks — no real broker involved.
Pattern: `monkeypatch.setattr(rabbitmq_client_module.aio_pika, "connect_robust", ...)`
patches the module attribute that `connect()` looks up at call time (not
the `rabbitmq_client` singleton's method — that's a bound method, it has
no attribute of its own to patch). `aio_pika.connect_robust`/`asyncio.sleep`
must both be mocked when testing the retry loop, or the test really
sleeps `2**attempt` seconds between attempts. `message.process(...)` is an
async context manager, not a plain awaitable — mocking it needs a
`MagicMock` with `__aenter__`/`__aexit__` set to `AsyncMock`s (see
`make_fake_message()` in that file), not just `AsyncMock()`. When
asserting on what a mocked async method returned, compare against
`mock.return_value` (or a variable captured before assigning it), never
against the mock itself — `some_mock is some_mock.return_value` is never
true, they're two different objects.