Skip to content

Conversation

@ayghri
Copy link

@ayghri ayghri commented Dec 6, 2025

This PR adds a comment moderation mechanism with an approval phase. When enabled, new comments require admin approval before becoming visible to other users. Admins can see all comments (both approved and unapproved), while regular users only see approved comments.

Features

  • New NEED_APPROVAL setting: When set to true, enables comment moderation
  • Admin approval workflow: Admins see "Approve" button on unapproved comments and "Disapprove" button on approved ones
  • Visibility control: Unapproved comments are hidden from non-admin users
  • Migration safe: Uses Unapproved bool field (defaults to false) so existing comments remain visible after upgrade

Configuration

Command line Environment Default Description
--need-approval NEED_APPROVAL false Enable comment moderation: new comments require admin approval before being visible to other users

Backend Changes

Store Layer (backend/app/store/)

  • comment.go: Added Unapproved bool field to Comment struct
  • comment_test.go: Added test for JSON serialization of unapproved field

Service Layer (backend/app/store/service/)

  • service.go:
    • Added NeedApproval bool to DataStore struct
    • prepareNewComment(): Sets Unapproved = true for new comments when NeedApproval is enabled
    • SetApproved(): New method to approve/disapprove comments
    • filterUnapproved(): Filters out unapproved comments for non-admin users
    • Updated Get(), Last(), and Find() to filter unapproved comments
  • service_test.go: Added comprehensive tests for approval functionality

API Layer (backend/app/rest/api/)

  • rest.go:
    • Added NeedApproval to config endpoint response
    • Added route PUT /api/v1/admin/approve/{id}?site=...&url=...
  • admin.go: Added setApprovedCtrl handler for approval endpoint

Server Configuration (backend/app/cmd/)

  • server.go: Added --need-approval / NEED_APPROVAL CLI flag

Frontend Changes

Types & API (frontend/apps/remark42/app/common/)

  • types.ts: Added unapproved?: boolean to Comment type, need_approval: boolean to Config type
  • api.ts: Added approveComment() and disapproveComment() API functions
  • static-store.ts: Added need_approval default value

Redux Store (frontend/apps/remark42/app/store/comments/)

  • actions.ts: Added setApprovalState() action creator
  • actions.test.ts: Added tests for approval actions

UI Components (frontend/apps/remark42/app/components/comment/)

  • comment.tsx: Added visual indicator for unapproved comments, passes needApproval config to actions
  • comment-actions.tsx: Added Approve/Disapprove button (only shown when needApproval is true and user is admin)
  • connected-comment.tsx: Connected setApprovalState action to component
  • Tests: Updated comment.test.tsx and comment-actions.spec.tsx with approval tests

Packages (frontend/packages/api/)

  • clients/public.ts: Added approve and disapprove methods to PublicClient

Documentation

  • site/src/docs/configuration/parameters/index.md: Added need-approval / NEED_APPROVAL parameter documentation

Design Decisions

  1. Unapproved bool vs Approved bool: Used Unapproved so that Go's default false value means comments are approved. This ensures existing comments remain visible after migration without requiring a database update.

  2. Config-driven UI: The approval button only appears when both need_approval is true AND the user is an admin. This keeps the UI clean when moderation is disabled.

  3. Comment visibility: The comment author can always see their own unapproved comments. Other non-admin users cannot see unapproved comments at all.

Testing

  • ✅ Backend unit tests (Go): cd backend/app && go test ./...
  • ✅ Frontend unit tests (Jest): cd frontend/apps/remark42 && pnpm test
  • ✅ TypeScript type checking passes
  • ✅ All existing tests pass

@ayghri ayghri requested a review from umputun as a code owner December 6, 2025 12:07
@ayghri ayghri force-pushed the feature/comment-approval branch from 5818177 to 39c5e54 Compare December 7, 2025 04:35
@codecov
Copy link

codecov bot commented Dec 7, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.27%. Comparing base (658bf30) to head (39c5e54).
⚠️ Report is 5 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1975      +/-   ##
==========================================
+ Coverage   62.19%   64.27%   +2.08%     
==========================================
  Files         132      142      +10     
  Lines        3026     3320     +294     
  Branches      764      798      +34     
==========================================
+ Hits         1882     2134     +252     
- Misses       1140     1182      +42     
  Partials        4        4              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant