feat: notification service
This commit is contained in:
+64
-21
@@ -218,7 +218,7 @@ Important architectural rules:
|
||||
|
||||
* public auth stays synchronous;
|
||||
* `confirm-email-code` returns a ready `device_session_id`;
|
||||
* no async “pending session provisioning” stage exists;
|
||||
* no async “pending session provisioning” step exists;
|
||||
* session source of truth and gateway-facing projection remain separate;
|
||||
* active-session limits are configuration-driven;
|
||||
* `send-email-code` stays success-shaped for existing, new, blocked, and throttled email flows.
|
||||
@@ -291,7 +291,12 @@ Transport rules:
|
||||
* `Auth / Session Service -> Mail Service` uses the dedicated synchronous
|
||||
trusted internal REST contract `POST /api/v1/internal/login-code-deliveries`;
|
||||
* `Notification Service -> Mail Service` is an asynchronous internal command
|
||||
flow carried through the event bus or an equivalent queue-backed handoff.
|
||||
flow carried through dedicated queue-backed handoff after durable route
|
||||
acceptance inside `Notification Service`.
|
||||
|
||||
This split is covered by integration tests: auth-code delivery bypasses
|
||||
`Notification Service`, while notification-generated mail uses template-mode
|
||||
commands whose `template_id` equals `notification_type`.
|
||||
|
||||
`Mail Service` may internally queue both flows.
|
||||
Its trusted operator read and resend APIs are part of the v1 service surface,
|
||||
@@ -353,7 +358,7 @@ It is the source of truth for:
|
||||
* game records before and after runtime existence;
|
||||
* public/private game type;
|
||||
* owner of a private game;
|
||||
* invitations and invite code lifecycle;
|
||||
* user-bound invitations and invite lifecycle;
|
||||
* applications and approvals;
|
||||
* membership and roster;
|
||||
* blocked/removed participants at platform level;
|
||||
@@ -410,8 +415,9 @@ Public games:
|
||||
Private games:
|
||||
|
||||
* can be created only by eligible paid users;
|
||||
* visible only to their owner and to invited users who used an invite code and were accepted;
|
||||
* joining uses invite code plus owner approval;
|
||||
* visible only to their owner and to invited users whose invitation is bound
|
||||
to a concrete `user_id` and later accepted;
|
||||
* joining uses a user-bound invite plus owner approval;
|
||||
* invite lifecycle belongs entirely to `Game Lobby`.
|
||||
|
||||
Private-party owners get a limited owner-admin capability set, not full system admin power.
|
||||
@@ -527,20 +533,42 @@ It executes runtime jobs for `Game Lobby` and `Game Master`.
|
||||
|
||||
This is a hard invariant.
|
||||
|
||||
## 10. Notification Service
|
||||
## 10. [Notification Service](notification/README.md)
|
||||
|
||||
`Notification Service` is the async delivery/orchestration layer for platform notifications.
|
||||
|
||||
It has a deliberately minimal role:
|
||||
|
||||
* consume domain/integration events from services;
|
||||
* decide whether a given event should result in push, email, or both;
|
||||
* render and route notification payloads;
|
||||
* send push-targeted events toward gateway;
|
||||
* send email-targeted asynchronous commands toward `Mail Service`.
|
||||
* consume normalized notification intents from services through dedicated
|
||||
Redis Stream `notification:intents`;
|
||||
* validate idempotency and persist durable notification route state;
|
||||
* enrich user-targeted routes with `email` and `preferred_language` from
|
||||
`User Service`;
|
||||
* decide whether a given notification type results in `push`, `email`, or
|
||||
both;
|
||||
* send user-targeted `push` events toward gateway by `user_id`;
|
||||
* send non-auth email asynchronous commands toward `Mail Service`.
|
||||
|
||||
It is not a source of truth for user preferences in v1 unless a later feature requires it.
|
||||
|
||||
For user-targeted intents, upstream producers publish the concrete recipient
|
||||
`user_id` values. `Notification Service` resolves user email and locale from
|
||||
`User Service`, uses configured administrator email lists per
|
||||
`notification_type` for admin-only notifications, keeps
|
||||
`template_id == notification_type` for notification-generated email, and
|
||||
treats private-game invite flows in v1 as user-bound by internal `user_id`.
|
||||
Go producers use the shared `galaxy/notificationintent` module to build and
|
||||
append compatible intents into `notification:intents`; a failed append is a
|
||||
notification degradation signal and must not roll back already committed source
|
||||
business state.
|
||||
Acceptance of a user-targeted notification intent is complete only after every
|
||||
published recipient `user_id` resolves through `User Service`; unresolved user
|
||||
ids are treated as producer input defects and are recorded as malformed
|
||||
notification intents rather than deferred publication failures.
|
||||
|
||||
User-facing notifications use `push+email` unless a type explicitly opts out of
|
||||
one channel. Administrator-facing notifications are `email`-only in v1.
|
||||
|
||||
All platform notifications except auth-code delivery flow through this service, including:
|
||||
|
||||
* game lifecycle notifications;
|
||||
@@ -548,6 +576,13 @@ All platform notifications except auth-code delivery flow through this service,
|
||||
* new turn notifications;
|
||||
* operational/admin notifications where appropriate.
|
||||
|
||||
The current process surface exposes only one private probe HTTP listener with
|
||||
`GET /healthz` and `GET /readyz`; that probe surface is documented in
|
||||
[`notification/openapi.yaml`](notification/openapi.yaml). The canonical
|
||||
notification-intent stream contract remains
|
||||
[`notification/api/intents-asyncapi.yaml`](notification/api/intents-asyncapi.yaml).
|
||||
It does not expose an operator REST API.
|
||||
|
||||
## 11. Billing Service (future)
|
||||
|
||||
`Billing Service` is not part of the first implementation wave.
|
||||
@@ -611,6 +646,12 @@ The platform uses one simple rule:
|
||||
* `Lobby -> Runtime Manager` runtime jobs;
|
||||
* `Game Master -> Runtime Manager` runtime jobs;
|
||||
* all event-bus propagation;
|
||||
* `Game Master -> Notification Service` notification intents through
|
||||
`notification:intents`;
|
||||
* `Game Lobby -> Notification Service` notification intents through
|
||||
`notification:intents`;
|
||||
* `Geo Profile Service -> Notification Service` notification intents through
|
||||
`notification:intents`;
|
||||
* `Notification Service -> Gateway`;
|
||||
* `Notification Service -> Mail Service`;
|
||||
* geo auxiliary ingest from gateway to geo service;
|
||||
@@ -626,13 +667,14 @@ The main example is `Lobby -> Game Master`:
|
||||
|
||||
## Redis as Data and Event Infrastructure
|
||||
|
||||
Redis is the first-stage shared infrastructure for:
|
||||
Redis is the initial shared infrastructure for:
|
||||
|
||||
* main persistent data of services where no SQL backend is yet introduced;
|
||||
* gateway session cache backing data;
|
||||
* replay reservation store for gateway;
|
||||
* session lifecycle projection;
|
||||
* internal event bus using Redis Streams;
|
||||
* notification-intent ingress through `notification:intents`;
|
||||
* notification fan-out;
|
||||
* runtime job completion events;
|
||||
* lobby/game-master propagation events;
|
||||
@@ -640,7 +682,7 @@ Redis is the first-stage shared infrastructure for:
|
||||
|
||||
Redis Streams are therefore the platform event bus in v1.
|
||||
|
||||
This is an accepted trade-off for simpler early-stage infrastructure.
|
||||
This is an accepted trade-off for simpler early infrastructure.
|
||||
Service boundaries must still stay storage-agnostic where future SQL migration is expected, especially in `Auth / Session Service`.
|
||||
|
||||
## Main End-to-End Flows
|
||||
@@ -791,7 +833,7 @@ sequenceDiagram
|
||||
Engine-->>GM: new turn result / maybe finished
|
||||
GM->>GM: update current_turn and runtime state
|
||||
GM->>Lobby: sync runtime snapshot
|
||||
GM->>Notify: publish new-turn event
|
||||
GM->>Notify: publish new-turn intent
|
||||
Notify->>Gateway: client-facing push events
|
||||
else generation failed
|
||||
Engine-->>GM: error / timeout
|
||||
@@ -820,7 +862,7 @@ sequenceDiagram
|
||||
GM->>GM: update runtime state
|
||||
GM->>Lobby: mark platform game finished
|
||||
Lobby->>Lobby: finalize game record
|
||||
GM->>Notify: publish finish event
|
||||
GM->>Notify: publish game-finished intent
|
||||
Notify->>Gateway: push user-facing/platform events
|
||||
```
|
||||
|
||||
@@ -923,7 +965,7 @@ Uses the normal authenticated client protocol, not the separate system admin UI.
|
||||
Allowed owner-admin actions are limited to the owner’s own private games and include at least:
|
||||
|
||||
* initiate enrollment;
|
||||
* distribute invite codes outside the system;
|
||||
* create and manage user-bound invites inside the system;
|
||||
* approve/reject applicants;
|
||||
* start game after enrollment;
|
||||
* force next turn while running;
|
||||
@@ -961,11 +1003,12 @@ Recommended order for implementation is:
|
||||
3. **User Service** (implemented)
|
||||
Regular-user identity, profile/settings, tariffs/entitlements, user limits, sanctions, and current `declared_country`.
|
||||
|
||||
4. **Mail Service**
|
||||
Internal email delivery for auth codes first, later for platform notifications.
|
||||
4. **Mail Service** (implemented)
|
||||
Internal email delivery for auth codes and platform notification mail.
|
||||
|
||||
5. **Notification Service**
|
||||
Unified async delivery of push and non-auth email notifications.
|
||||
5. **Notification Service** (implemented)
|
||||
Unified async delivery of push and non-auth email notifications, with
|
||||
real Gateway and Mail Service boundary coverage.
|
||||
|
||||
6. **Game Lobby Service**
|
||||
Platform game records, membership, invites, applications, approvals, schedules, user-facing lists, pre-start lifecycle.
|
||||
@@ -983,6 +1026,6 @@ Recommended order for implementation is:
|
||||
Auxiliary geo aggregation, review recommendation, suspicious-session blocking, declared-country workflow.
|
||||
|
||||
11. **Billing Service**
|
||||
Late-stage payment and subscription source feeding entitlements into `User Service`.
|
||||
Future payment and subscription source feeding entitlements into `User Service`.
|
||||
|
||||
This order gives the platform a usable public perimeter first, then identity/auth, then core gameplay lifecycle, then runtime orchestration, and only afterward secondary auxiliary services.
|
||||
|
||||
Reference in New Issue
Block a user