docs: resolve four Phase 17 open questions (OQ1/OQ4/OQ8/OQ10), defer ReleaseGallery card affordance

This commit is contained in:
daniel-c-harvey
2026-06-19 13:42:19 -04:00
parent a715f4b28d
commit ebbaa3f84f
8 changed files with 177 additions and 63 deletions
+22
View File
@@ -307,6 +307,28 @@ Aggregate figures behind the public home hero stat row (`NowPlayingStats`). A si
- Aggregated in `TrackRepository.GetHomeStatsAsync`, surfaced via `ITrackService`/`TrackManager`. Controller is `StatsController` — a thin HTTP boundary; no domain logic lives there.
- Returns 200 on success. Returns 500 on query error.
## The event endpoints (Phase 16 anonymous telemetry)
Both endpoints are unauthenticated and rate-limited by the `"events"` fixed-window policy (30 requests / 60 s per IP, keyed on `Connection.RemoteIpAddress` after `UseForwardedHeaders()` resolves XFF). Returns `202 Accepted` — fire-and-forget contract; the `sendBeacon` client ignores the response. Controller: `EventController`.
### POST api/event/play (unauthenticated, rate-limited)
Records an anonymous play event. Client sends only the track `EntryKey` and a completion bucket; server-side release resolution joins track→release at write time (D4). Wave 16.1 drops any `anonId` the client sends — that field is wired in wave 16.3.
- **Body** (`PlayEventDto`): `{ "trackEntryKey": "...", "bucket": "partial"|"sampled"|"complete" }`.
- Validates: non-empty `trackEntryKey`; `bucket` must be a defined `PlayBucket` enum value.
- Delegates to `IEventService.RecordPlay`, which appends to `play_event` and bumps `play_counter`.
- Returns 202 on success. Returns 400 for missing/invalid fields. Returns 429 when the rate limit is exceeded. Returns 500 on a write failure (logged; beacon ignores it).
### POST api/event/share (unauthenticated, rate-limited)
Records an anonymous share event (a clipboard write from `SharePopover`).
- **Body** (`ShareEventDto`): `{ "targetKey": "...", "targetType": "track"|"release", "channel": "link"|"embed" }`.
- Validates: non-empty `targetKey`; defined `ShareTargetType` and `ShareChannel` enum values.
- Delegates to `IEventService.RecordShare`, which appends to `share_event`.
- Returns 202 on success. Returns 400 for missing/invalid fields. Returns 429 on rate limit. Returns 500 on write failure.
## ApiKey middleware behaviour
`ApiKeyAuthenticationMiddleware` runs on every request but only enforces on endpoints with `[ApiKeyAuthorize]` metadata.