Skip to content

[Enhancement] Confluence-style threaded comments for cases and simulations #164

@tomvothecoder

Description

@tomvothecoder

Summary

Add an API-backed comment system to case and simulation detail pages so signed-in users can discuss records in-context. V1 should support top-level comments plus one level of replies, optional section anchors, author attribution from existing /users/me auth, and soft deletion/edit history without changing existing case/simulation list payloads.

Is your feature request related to a problem?

Case and simulation pages currently have no persistent collaboration layer. The simulation detail view includes a temporary local-only comment stub, and case pages have no discussion surface at all. Users cannot leave durable context, ask follow-up questions, or capture review notes tied to a specific case/simulation section.

Describe the solution you'd like

Backend

  • Add a new comments feature with a single Comment model using existing IDMixin and TimestampMixin.
  • Use one table with nullable case_id and simulation_id, plus a DB check constraint that exactly one is set.
  • Fields: id, body, case_id, simulation_id, parent_comment_id, anchor_key, created_by, last_updated_by, edited_at, deleted_at, created_at, updated_at.
  • Keep replies in the same table; enforce max depth 1 by rejecting replies to replies.
  • Store comment body as plain text with preserved newlines in v1. Do not add markdown/rich-text rendering yet.
  • Use soft delete for all comments. Deleted comments stay in-place as tombstones so reply threads remain intact.
  • Reuse UserPreview for author info in responses.

API / interface changes

  • Add POST /cases/{case_id}/comments and GET /cases/{case_id}/comments.
  • Add POST /simulations/{sim_id}/comments and GET /simulations/{sim_id}/comments.
  • Add PATCH /comments/{comment_id} and DELETE /comments/{comment_id}.
  • POST accepts { body, anchorKey?, parentCommentId? }.
  • PATCH accepts { body }.
  • GET returns top-level comments with embedded replies, author preview, timestamps, editedAt, deletedAt, anchorKey, and parentCommentId.
  • Keep existing CaseOut and SimulationOut unchanged; comments load separately on detail pages to avoid bloating existing responses.

Rules and behavior

  • Any signed-in user can create top-level comments and replies.
  • Authors can edit/delete their own comments. Admins can delete any comment for moderation; non-authors cannot edit others’ comments.
  • Replies inherit the parent resource and anchor; server rejects mismatched resource IDs or nested reply depth > 1.
  • anchor_key is optional and frontend-controlled, not hard-enforced as a backend enum. Use stable keys such as case-metadata, reference-simulation, simulation-list, simulation-summary, outputs-logs, notes.
  • Sort root comments oldest-first within each anchor group; sort replies oldest-first.

Frontend

  • Add a new frontend/src/features/comments/ module with API helpers, hooks, and a shared CommentsPanel.
  • Replace the temporary local-only comments block in the simulation detail view with the shared panel.
  • Add the same panel to the case detail page.
  • Support: list threads, create comment, reply, edit own comment, delete own comment, read-only empty state for signed-out users, and anchor badge/filter UI.
  • Keep mutation handling simple and deterministic: submit, refetch thread list, show toast; no optimistic updates in v1.

Describe alternatives you've considered

  • resource_type/resource_id polymorphism was rejected because it loses DB-level foreign keys.
  • Separate case_comments and simulation_comments tables were rejected because they duplicate nearly identical logic.
  • Inline text-range comments were rejected for v1 because they require DOM anchoring, selection persistence, and brittle reattachment when layouts change.
  • Mentions, notifications, reactions, and rich-text/markdown rendering are deferred until basic threaded discussion proves useful.

Test cases and scenarios

  • Backend pytest coverage for create/list/edit/delete on both cases and simulations.
  • Validate DB/resource rules: exactly one parent target, reply depth limited to 1, replies cannot switch resource/anchor.
  • Permission tests: signed-out write rejected, author edit/delete allowed, non-author edit rejected, admin delete allowed.
  • Soft-delete tests: deleted comments remain in thread with tombstone state and preserved replies.
  • API serialization tests for nested replies and UserPreview.
  • Frontend verification via make frontend-lint, frontend type-check, and manual smoke on case/simulation detail pages because no frontend test runner is currently configured.

Additional context

  • Implement this as a new feature module rather than extending notes_markdown; notes are record metadata, comments are multi-user discussion.
  • Reuse existing auth/session behavior and /users/me identity for composer state and author attribution.
  • No notifications, email, activity feed, or cross-page comment counts in v1.

Assumptions and defaults

  • V1 targets page discussion with optional section anchors, not inline text selection.
  • Comment threads are one level deep only.
  • Comments are visible anywhere the underlying case/simulation is visible.
  • Plain-text bodies with newline preservation are sufficient for v1.
  • Existing case/simulation detail endpoints remain backward-compatible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions