Announcements

Site news replaces the weekly Discord export → news.json pipeline. Abstract Play is the source of truth; Discord #announcements is mirrored on first publish only.

Front plan: announcements fan-out architecture (living plan in maintainer docs). Phase 0 locked 2026-09-16.

DynamoDB

Single-table keys (stage table abstract-play-dev / abstract-play-prod):

Item pk sk Notes
Announcement ANNOUNCEMENT <id> id = UUID for new posts; Discord import uses snowflake message.id
Published index (GSI) ANNOUNCEMENT_PUBLISHED <publishedAt>#<id> List published, newest first; project metadata + reactionCounts

Announcement fields (core):

Reactions (minimal v1):

User read cursor (on USER settings, not a separate item):

API queries

Query Auth Role
announcements_list Public Published only; pagination; includes reactionCounts
announcement_get Public By id; attachmentUrls for keys
announcements_admin_list Admin All statuses
announcement_save Admin Draft create/update; edit published (no fan-out)
announcement_presign_upload Admin Image upload for drafts/edits
announcement_publish Admin First-publish fan-out only
announcements_mark_read Auth Bump announcementsLastReadAt
announcement_react Auth Toggle allowlisted emoji
announcement_reactions_mine Auth { ids: string[] } → user's emojis per id

Register handlers in lib/announcements/authHandlers.ts alongside feedback patterns.

Unread and in-app bell (front)

Notification prefs

Channel Setting key Default When
In-app bell rows inAppNotifications.announcements on Synthetic list only
Email notifications.announcements (email map) off First announcement_publish only; recipients from ANNOUNCEMENT_NOTIFY index (synced on update_user_settings)
Push notifications.announcements (same email map) off First announcement_publish only

Edits to published posts do not re-send email/push or reset unread cursor.

Dev vs prod

Stage announcement_save / presign announcement_publish
prod (WEBSOCKET_STAGE=prod) Admin allowed Admin allowed
dev (WEBSOCKET_STAGE=dev) Admin allowed (draft/composer testing) 403 announcements_publish_disabled_on_dev

Front play.dev: disable Publish in admin UI (VITE_REAL_MODE=development). Ops import CLI is not gated.

Publish vs edit

Target announcement_publish (first time) announcement_save on published
Site list/get Visible Immediate update
Static news.rss Regenerate + upload Regenerate (same <guid>)
Discord webhook POST once; store discordMessageId No auto-update
Email / push If pref on No
Unread cursor Users see new items No re-notify

Retract: status: retracted; hide from list/RSS; Discord follow-up manual or bot later.

Discord webhook (v1)

Env: ANNOUNCEMENTS_DISCORD_WEBHOOK_URL (secrets manager per stage).

Example payload:

{
  "content": "**{title}**\n{excerpt}\nhttps://play.abstractplay.com/news/{id}"
}

Excerpt = plain-text first ~200 chars of body, unless the body contains an excerpt marker <!--ap:discord-excerpt-end--> (HTML comment in markdown). With the marker, Discord uses plain text before the marker and always appends …; text after the marker is site-only. The marker is stripped for /news, RSS, and preview. Full markdown and images live on site only.

Attachments

Discord history import

Reactions (site v1)

Related