feat : comment feature
This commit is contained in:
@@ -158,12 +158,58 @@ with the latest version reported by Lunaris.
|
||||
- Enable the Discord Message Content intent and grant the bot View Channel and
|
||||
Send Messages in the configured channels.
|
||||
|
||||
### Guide comments
|
||||
|
||||
Comment tables live in the dedicated PostgreSQL `comments` schema: `comment`,
|
||||
`thread`, `revision`, `attachment`, `revision_attachment`, `reaction`,
|
||||
`push_subscription`, and `read_state`.
|
||||
|
||||
Character guides have a Comment section at `/{slug}/comment`. Stygian comments
|
||||
appear at the bottom of `/stygian?schedule={id}` and remain accessible at
|
||||
`/stygian/comment?schedule={id}`; both share the selected schedule's discussion. Readers can
|
||||
browse anonymously; posting, replies, likes, and dislikes require an account.
|
||||
Replies expand inline with connector lines; replies to replies identify their recipient.
|
||||
The Thai comment UI supports image paste (Ctrl+V) with previews and loading skeletons.
|
||||
Comment boards and the admin inbox receive Redis-backed SSE change events;
|
||||
reads after each event recheck authorization. Reconnecting refreshes missed updates.
|
||||
Signed-in authors can enable browser notifications after posting. New replies notify
|
||||
only the direct parent author, excluding self-replies. Notification clicks open the
|
||||
root thread, load the relevant reply page, and highlight/focus the exact reply.
|
||||
This uses the existing `WEB_PUSH_PUBLIC_KEY`, `WEB_PUSH_PRIVATE_KEY`, and
|
||||
`WEB_PUSH_SUBJECT` configuration, with subscriptions in `comments.push_subscription`.
|
||||
Likes, dislikes, and admin hearts update optimistically and save in the background;
|
||||
a failed save rolls the reaction back and shows an error.
|
||||
|
||||
Each comment or reply supports 4,000 characters and up to five JPEG, PNG, or
|
||||
WebP images, each no larger than 10 MiB. Image bytes are uploaded to the
|
||||
S3 bucket through Bun’s `S3Client`; PostgreSQL stores only object keys, metadata,
|
||||
and revision references. Browsers load images directly from `S3_PUBLIC_URL`. Videos are unsupported. Authors can edit
|
||||
or delete their comments, and the “แก้ไขแล้ว” link exposes previous text and images.
|
||||
Deletion permanently removes the comment and every descendant reply, including their
|
||||
revision history, attachment metadata, and reactions. Their S3 images are also deleted.
|
||||
|
||||
`/admin/comments` provides the cross-guide inbox, guide/schedule filtering,
|
||||
visible/hidden and unanswered filters, replies, reactions, admin hearts, and
|
||||
hide/restore moderation. Conversation buttons appear only on comments with replies;
|
||||
the dialog shows a thread skeleton while loading. Admin-only unread badges update
|
||||
via SSE, cap at `99+`, and link to the guide inbox. Opening the inbox marks its
|
||||
selected guide (or all guides) read for that admin. Hiding a root also hides its replies. Moderation actions
|
||||
are recorded in the activity log. Comment reads and legacy attachment redirects
|
||||
are not cached; guide content caches are independent of discussions.
|
||||
|
||||
The comment migration must run before deploying these pages. For PostgreSQL
|
||||
integration verification, point `DATABASE_INTEGRATION_URL` at a migrated test or
|
||||
development database and run `bun run test tests/comments.integration.test.ts`.
|
||||
The suite creates isolated fixtures and removes them afterward; image storage is
|
||||
mocked while decoding and database operations are exercised.
|
||||
|
||||
### Media visibility
|
||||
|
||||
| Upload path | Visibility |
|
||||
| --- | --- |
|
||||
| Presigned staged upload | Private in S3. `/media/[id]` allows public access only while a published guide references the object; otherwise administrator authorization is required. |
|
||||
| Direct guide image upload | Public CDN object, including uploads made for drafts. |
|
||||
| Comment attachment | Stored in Bun S3 and loaded directly from `S3_PUBLIC_URL`. Hiding removes image links from public comment responses; existing URLs remain accessible until the S3 object is deleted. `/api/comments/images/[id]` only redirects old links after a visibility check. |
|
||||
| Commission attachment | Served from `S3_PUBLIC_URL`; anyone with the URL can view it. |
|
||||
|
||||
Keep sensitive material out of the direct upload path and commission attachments.
|
||||
|
||||
Reference in New Issue
Block a user