feat(news): add news endpoints and admin CRUD
Build, Test & Push Auth Service / quality-check (push) Successful in 51s
Build, Test & Push Auth Service / docker (push) Successful in 1m26s

Users see new entries once in a dialog after publication.
Admins manage entries via /api/admin/news with full audit trail.
This commit is contained in:
lobo committed 2026-10-01 10:03:07 +02:00
1 parent 39a4d5ae49
commit 2b2f45b9af
22 files changed
+694 -1

No files matched your search

+13 -1
View File
@@ -7,7 +7,7 @@ To Be Played is split into three repositories:
| Repository | Role |
|---|---|
| **ToBePlayed-Auth** (this one) | Users, login, settings, signs JWTs |
| **ToBePlayed-Auth** (this one) | Users, login, settings, platform messages (hints, mail, news), signs JWTs |
| ToBePlayed-Core | Steam library, backlog, wishlist, stats; verifies JWTs |
| ToBePlayed-Frontend | React single-page app |
@@ -74,6 +74,10 @@ To Be Played is split into three repositories:
and end time, type `DISMISS` or `ACCEPT`). The dashboard shows the running hints one at a time, newest first.
"Do not show again" on a `DISMISS` hint or "OK" on an `ACCEPT` hint is a row in `hint_done`, so the hint never
comes back for this user on any device. Creating and ending a hint are rows in `admin_audit`.
- **What's new**: a PLATFORM_ADMIN publishes news entries (plain text, English, German optional; edit and delete, no
drafts). The dashboard shows the entries published after `user_settings.news_seen_at` once in a dialog; "Got it"
sets the stamp to now (`PUT /api/news/seen`). A new user starts at the registration time. `/whats-new` lists all
entries. Editing an entry does not make it unseen again. Create, update and delete are rows in `admin_audit`.
- **Mails** from the platform mailbox: "a new registration waits" to the admin (`APP_MAIL_ADMIN_TO`, with the link
to the admin page), and to the user "we got your registration", then "your account is active" or "your
registration was denied", later "your account is blocked" and "your account will be deleted from <date>". The registration sends the browser language (`de` for a German browser, else `en`), which also becomes
@@ -108,6 +112,12 @@ To Be Played is split into three repositories:
| `GET` | `/api/admin/hints` (`{results}` with `status` PLANNED/ACTIVE/ENDED by the server clock and `doneCount`, newest first) | PLATFORM_ADMIN |
| `POST` | `/api/admin/hints` (`{textEn, textDe, kind, startsAt, endsAt}`; `201 {id}`, `400 INVALID_HINT`) | PLATFORM_ADMIN |
| `PUT` | `/api/admin/hints/{id}/end` (`204`; a planned hint never starts) | PLATFORM_ADMIN |
| `GET` | `/api/news` (`{results}` with `seen`, newest first) | access token |
| `PUT` | `/api/news/seen` (`204`) | access token |
| `GET` | `/api/admin/news` (`{results}`, newest first) | PLATFORM_ADMIN |
| `POST` | `/api/admin/news` (`{titleEn, titleDe, textEn, textDe}`; `201 {id}`) | PLATFORM_ADMIN |
| `PUT` | `/api/admin/news/{id}` (same body; `204`; `404 NEWS_NOT_FOUND`) | PLATFORM_ADMIN |
| `DELETE` | `/api/admin/news/{id}` (`204`; `404 NEWS_NOT_FOUND`) | PLATFORM_ADMIN |
| `DELETE` | `/api/users/me` (`{password}`; `204` and both cookies cleared, `403 INVALID_PASSWORD`, `429`) | access token |
| `GET` | `/api/steam-link/callback` | public, Steam's redirect back; binding cookie; redirects to the frontend settings |
| `PUT` | `/api/users/settings/appearance` | access token |
@@ -159,6 +169,8 @@ the login module writes "view as" to the audit table through `shared/audit/Admin
use each other.
`hint` (dashboard hints and their admin API) uses `JdbcTemplate` in a `repo` package too, and audits through
`shared/audit/AdminAuditLog`.
`news` (what's new entries and their admin API) is built the same way as `hint`; the seen stamp is a column of
`user_settings`, read and written by SQL in its own repo.
`mail` writes each mail as a finished text into `mail_outbox` (`JdbcTemplate`, `repo`), in the transaction of the
event, and `MailOutboxService` sends the rows every minute over SMTP. Other modules reach it through the port
`shared/mail/AccountMailer`. Without `SPRING_MAIL_HOST` mail is off: the rows wait and go out once a host is set.