Comments: data model and API #91
Labels
No Label
area:auth
area:docs
area:export
area:ops
area:storage
area:supply-chain
auth
backend
blocked
collab
deployment
docs
effort:L
effort:M
effort:S
frontend
plugins
qa
vs-nfd
vs-nfd:blocker
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: stwaidele/dorfteich#91
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Kickoff put comments in scope: discussions attached to pages, with thread and resolve semantics.
Scope
Prisma models
comments(thread via parent_id, optional anchor, resolved_at) per data-model.md; endpoints: list per page (threaded, resolved filter), create (Markdown body, sanitized render via shared pipeline), edit/delete own (admins: delete any), resolve/unresolve; permission: reading follows page read; writing requires page read + the pond setting 'who may comment' (readers-and-up | editors-only — add the setting).Acceptance criteria
Technical notes
Dependencies
Depends on #52.
Size: ~1.5 days
Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add
deanden), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.Implemented in
4549d6d(pipeline green, 8/8; migration20260711220000_commentsauto-applied on Test + Int).Data model —
commentstable per data-model.md: thread viaparent_id(one level: replies attach to thread roots only — a reply-to-reply is rejected ascomment_parent_invalid, never silently reparented), optional opaqueanchoron roots,resolved_at/resolved_by,edited_at. FKs: page purge cascades the comments, root delete cascades its replies, a hard user delete nulls the author (pseudonymized accounts keep theirs).New pond setting
commentPolicy(readersdefault |editors) inpondSettingsSchema+updatePondInputSchema— rides the existing pond PATCH; the UI toggle lands with #92.API (
apps/api/src/comments/):GET /pages/:id/comments?filter=all|open|resolved— threaded list; resolved threads carrycollapsed: trueby default plus open/resolved counts (AC).POST /pages/:id/comments— root or reply; page read via the shared guard, then the write policy:readers→ page read,editors→ page write. 404-vs-403 semantics per #60: no read hides existence, failed policy on a readable page is an explicit 403comments_editors_only.PATCH /comments/:id— author only (comment_not_author), stampseditedAt.DELETE /comments/:id— author (roots with replies refuse with 409comment_has_replies— nobody takes other people's replies down), pond admins and Site Admins delete any thread (cascade).POST|DELETE /comments/:id/resolve— roots only, for everyone who may comment.Bodies are Markdown rendered through the shared sanitizing pipeline (
docToHtml(markdownToDoc(..))— the exact page renderer); the view carries both the rawbody(for edit forms) and the inerthtml. Error codes localized de+en.Acceptance criteria (all in
comments.e2e.db.test.ts, 5 tests):filter=open/resolvedplus thecollapsedflag asserted both ways; unresolve reopens.<script>+<img onerror>: the html contains<script>and no live tags.Next in the track: #92 (UI), #93 (watches), #94 (notifications — comment events will hook into
CommentsService).