Skip to content

Commit 791ee7b

Browse files
authored
docs: merge the upsert ADRs, drop replaced and non-ADR records, renumber (#62)
ADRs that a later decision replaces are now deleted once their reasoning moves into the new record.
1 parent 9626b43 commit 791ee7b

16 files changed

Lines changed: 56 additions & 115 deletions

‎AGENTS.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ env vars (see `docker-compose.yml`). `api_bootstrapper_config` builds the
187187
`ForeignKey`, a `return` from inside a transaction block, discarded work that
188188
is not dead code (`AuthenticateUserUseCase`'s hash-anyway). Alembic's own
189189
`# ###` autogenerate markers stay — they are regenerated on every migration.
190+
- **Coverage.** The suite runs at `--cov-fail-under=100` and no `# pragma: no cover`
191+
appears anywhere. The only exemptions are structural: `[tool.coverage.run] omit`
192+
for files the default run never imports, and `exclude_also` for
193+
`if typing.TYPE_CHECKING:`. A branch that looks untestable gets a test that
194+
produces its condition for real, such as the concurrent create tests'
195+
second connection holding an uncommitted insert.
190196
- `ruff` is configured with `select = ["ALL"]` and a line length of 120 —
191197
expect strict lint. Type-check with `ty`.
192198

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Idempotency is scoped per chat
2+
3+
`messages` carries `UniqueConstraint("chat_id", "idempotency_key")`, and the
4+
send's `ON CONFLICT` names that constraint. Idempotency belongs to the operation
5+
"send this message to this chat", so a key reused in another chat is a different
6+
operation, not a retry. A global constraint on `idempotency_key` shipped first.
7+
A client that reused a key across chats got the other chat's message back, and
8+
the message it meant to send was never written.

‎docs/adr/0005-upsert-via-duplicate-key-recovery.md‎

Lines changed: 0 additions & 21 deletions
This file was deleted.

‎docs/adr/0006-idempotency-scoped-per-chat.md‎

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Read-marker integrity
2+
3+
`MarkReadUseCase` rejects a `last_read_message_id` that does not name a message
4+
in that chat with a `400`, and moving the marker to a lower id is a silent
5+
no-op. Accepting any id would let a client set its marker arbitrarily high and
6+
permanently zero its own unread counts, and storing self-inflicted corruption is
7+
worse than refusing the request. A lower id usually comes from a replayed or
8+
reordered request, which is not a client mistake worth reporting, so it gets the
9+
current marker back instead of an error.

‎docs/adr/0007-read-marker-integrity.md‎

Lines changed: 0 additions & 16 deletions
This file was deleted.
File renamed without changes.

‎docs/adr/0009-coverage-exclusions-structural-only.md‎

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ that user, and short-lived tokens with refresh because they replace the whole
88
auth model. The cost is one primary-key lookup per authenticated request, on a
99
session the middleware closes before the handler opens its own, so a request
1010
still holds one pooled connection at a time. That lookup is the read
11-
[ADR-0010](0010-auth-carries-an-actor-id.md) kept out of authentication; the
11+
[ADR-0008](0008-auth-carries-an-actor-id.md) kept out of authentication; the
1212
user row is still never loaded. A token without a `jti`, which includes every
1313
token issued before this change, gets a 401. Each logout prunes expired rows,
1414
so the table holds at most a token lifetime of logouts.

0 commit comments

Comments
 (0)