docs: reorder & testing

This commit is contained in:
Ilia Denisov
2026-05-07 00:58:53 +03:00
committed by GitHub
parent f446c6a2ac
commit 604fe40bcf
148 changed files with 9150 additions and 2757 deletions
+23 -9
View File
@@ -3,7 +3,7 @@
`backend` is the consolidated business service of the Galaxy platform. It
owns identity, sessions, lobby, game runtime, mail, notifications, geo
signals, and administration. It is reachable only from `gateway` over
the trusted network. See `../ARCHITECTURE.md` for the platform-level
the trusted network. See `../docs/ARCHITECTURE.md` for the platform-level
context, security model, and decision rationale.
## 1. Purpose
@@ -205,12 +205,21 @@ message PushEvent {
- `ClientEvent` carries an opaque payload addressed to a `(user_id [,
device_session_id])`. Gateway signs and forwards it to active client
subscriptions. The frame also carries `event_id`, `request_id`, and
`trace_id` correlation strings populated by backend producers
(notification dispatcher fills `event_id` from `route_id`,
`request_id` from the originating intent's `idempotency_key`, and
`trace_id` from the active span); gateway re-emits the values inside
the signed client envelope without re-interpreting them.
subscriptions. Producers do not pass raw bytes to `push.Service`;
instead they pass a typed `push.Event` (`Kind() string`,
`Marshal() ([]byte, error)`) and `push.Service` invokes Marshal at
publish time. Every notification catalog kind (§10) has a 1:1
FlatBuffers schema in `pkg/schema/fbs/notification.fbs`; the
notification dispatcher routes `(kind, payload)` to a typed event
through `notification.buildClientPushEvent`, so client decoders can
rely on a stable wire shape per kind. `push.JSONEvent` remains as a
safety net for kinds that arrive without a catalog schema. The frame
also carries `event_id`, `request_id`, and `trace_id` correlation
strings populated by backend producers (notification dispatcher
fills `event_id` from `route_id`, `request_id` from the originating
intent's `idempotency_key`, and `trace_id` from the active span);
gateway re-emits the values inside the signed client envelope
without re-interpreting them.
- `SessionInvalidation` instructs gateway to close active subscriptions
and reject in-flight requests for the affected sessions.
- `cursor` is a monotonically increasing string. Gateway stores the last
@@ -275,7 +284,12 @@ Lifecycle:
and either marks `sent` or schedules `next_attempt_at` with
exponential backoff and jitter.
3. After `BACKEND_MAIL_MAX_ATTEMPTS` the delivery moves to
`mail_dead_letters`. An admin notification intent is emitted.
`mail_dead_letters` and the worker writes an operator log line.
The `mail.dead_lettered` notification kind is reserved in the
catalog (see §10) but has no producer wired up yet, so no admin
email or push event is emitted today; admin observability for
dead letters relies on the log line and the
`/api/v1/admin/mail/dead-letters` listing.
4. Operators can resend a `pending`, `retrying`, or `dead_lettered`
delivery via `POST /api/v1/admin/mail/{delivery_id}/resend`. Resend
on a `sent` delivery returns `409 Conflict` so operators cannot
@@ -469,4 +483,4 @@ Primary references:
- [`PLAN.md`](PLAN.md) — historical staged build-up of the service.
- [`openapi.yaml`](openapi.yaml) — REST contract.
- [`../ARCHITECTURE.md`](../ARCHITECTURE.md) — workspace-level architecture.
- [`../docs/ARCHITECTURE.md`](../docs/ARCHITECTURE.md) — workspace-level architecture.