Reference → Discussions — Reference

Discussions — Reference

The Discussions surface is the comment and threaded-conversation engine for a site. It owns the comment records themselves, the threading model that connects replies to their parents, the moderation queue that decides which comments surface publicly, the anti-spam ruleset that filters submissions before moderation ever sees them, and the ban-list integration that holds repeat offenders out of the queue entirely. Every comment under a post, every reply under a comment, and every notification mailed to a thread participant traces back to records managed here.

This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or mapping a legacy Disqus or native WordPress comment set into SGEN. Customer-facing walkthroughs for moderating discussions and configuring policies live in the customer docs set; this page describes the shape of the surface, not the editorial flow.


Overview

Discussions live under the Discussions module in SG-Admin. The module renders five primary views — the comment moderation queue, the comment detail view (with the surrounding thread), the ban list, the anti-spam settings panel, and the per-post discussion settings panel — and exposes a set of write operations for approve, reject, mark-as-spam, reply, edit, soft delete, restore, permanent delete, ban, unban, and bulk action.

The module is paired by convention: one half renders the views and prepares the data (queue, thread, ban list, settings), the other half handles writes and returns AJAX responses (moderation actions, ban writes, settings updates). The pairing matches the broader SG-Admin convention used across Pages, Posts, Forms, Media, and Users.

Where it lives in SG-Admin:

  • Sidebar: SG-Admin → Discussions
  • URL prefix: /sg-admin/discussions/
  • View templates: application/views/Admin/Discussions/
A comment is two things stored together: the comment body and metadata (author name, author email, author URL, IP, user agent, posted timestamp, parent comment ID, attached post ID) and the moderation state (pending, approved, rejected, spam, trash). The two are edited together but live as distinct shapes on the record.

Discussions are paired with the Posts and Pages modules: every comment attaches to either a post or a page record. The per-post discussion settings (open / moderated / closed) live on the post record itself, but the discussion-wide defaults live in this module's settings panel.

┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Discussions → Moderation queue [Pending: 24] │├──────────────────────────────────────────────────────────────────────┤│ Author On post Excerpt Status ││ ───────────────── ────────────────── ───────────────────── ─────││ □ Maria Reyes Launch announcement excited to see… pending ││ □ spam-bot-9182 Five tips for site "Great article, visit… spam ││ □ Tom (anon) Engineering deep… Quick question about… pending ││ □ Editor (staff) Customer story Approved and replied. approved││ □ banned-user-2 News update (held — author banned) blocked ││ ││ [⋯ Approve] [⋯ Reject] [⋯ Spam] [⋯ Reply] [⋯ Ban author] [⋯ Bulk] │└──────────────────────────────────────────────────────────────────────┘

Actions

The Discussions surface exposes the following operations. Each is described by what it does to the data and to the public surface, not by its internal method name.

List moderation queue

Returns the comments waiting on operator action, paginated, with author, target post, excerpt, posted timestamp, and current moderation state columns. Supports column sort, free-text filter across author and excerpt, state filter (pending / spam / rejected / approved / trash), and post filter (queue scoped to a single post). The default view shows pending and spam together — the two states an operator most commonly drives.

Approve comment

Moves the comment from pending or spam into approved. Approved comments surface on the public post page immediately. The author is notified by email if the comment is a reply to a previously approved comment on the same post (configurable in the settings panel).

Reject comment

Moves the comment into rejected. Rejected comments do not surface publicly and the author is not notified. Used for spam, abuse, or off-topic content that the operator does not want to keep around for reference.

Mark as spam

Moves the comment into spam and feeds the comment body, author email, and source IP into the anti-spam training set. Future submissions matching the same signature route directly to spam without hitting the queue.

Reply to comment

Opens a reply form scoped to the comment's thread. The reply posts as an operator-authored comment, attributed to the calling user. Operator replies skip the moderation queue and surface publicly on next render. The replied-to author is notified by email.

Edit comment

Opens the comment body in a small editor. Submit replaces the stored body and stamps an "edited by operator" flag visible only in SG-Admin. The public surface re-renders with the new body on next request.

Edits to a comment body do not change the original posted timestamp. The "edited" flag is operator-side only — readers see a comment timestamped at original-post-time, with the operator-edited body.

Soft delete

Moves the comment into trash. Trashed comments disappear from the moderation queue and from the public surface. Replies attached to the trashed comment also disappear from public view but remain queryable from the trashed-replies filter.

Restore

Moves the comment out of trash back to its prior moderation state (pending or approved). Attached replies re-emerge.

Permanent delete

Hard-removes the comment record. Available only after a soft delete. Replies attached to the comment become orphaned — the thread re-points the replies to the deleted comment's parent (collapsing the tree), so the conversation remains coherent.

Manage ban list

The ban list holds author identifiers (email, IP, or both) that should not be allowed to comment. Submissions matching a ban-list entry route directly to a blocked state without hitting the moderation queue. The list view shows entry, scope (email / IP / both), date banned, banning operator, and a free-text reason field.

Ban author

A shortcut from the comment detail view that adds the author's email and source IP to the ban list. Used in one motion with reject-or-spam to close out a problematic submitter.

Unban

Removes a ban-list entry. Future submissions from the previously banned identifier route through the normal pipeline.

Bulk action

Applies an action (approve / reject / spam / trash / restore / permanent delete / ban author) to every selected row in the queue. Used to clear a flood of spam in one motion. Bulk action emits a single Activity Log entry summarizing the batch.

Edit per-post discussion settings

A focused settings panel scoped to one post. Owns the discussion policy for that post (open / moderated / closed), the closure window (auto-close after N days), and an override for the site-wide reply notification policy.

Edit anti-spam ruleset

Owns the regex-and-signature filter set, the third-party anti-spam connector configuration (when one is attached), the keyword denylist, the link-count threshold (comments with more than N links auto-route to spam), and the new-author throttle (per-IP comment rate cap).


Data model

A comment record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.

FieldTypeNotes
idintegerPrimary key. Stable across edits.
target_typeenumpost or page.
target_idintegerForeign key to the post or page record.
parent_idintegerForeign key to the parent comment for replies. Null for top-level.
thread_root_idintegerDenormalized pointer to the top-level ancestor for fast thread retrieval.
author_namestringDisplay name. Operator-authored comments carry the operator's display name.
author_emailstringUsed for the reply-notification email and for ban-list matching.
author_urlstringOptional. Renders as a link on the public surface.
author_user_idintegerForeign key to a user record when the author is a logged-in operator. Null for anonymous.
source_ipstringSubmitter IP. Used for ban-list matching and throttle enforcement.
user_agentstringSubmitter user agent. Used for anti-spam signature matching.
bodytextThe comment text. Markdown subset supported.
body_htmltextRendered HTML. Generated on save and on edit; never authored.
moderation_stateenumpending, approved, rejected, spam, trash.
edited_by_operatorbooleanTrue when an operator has edited the body.
edited_by_user_idintegerForeign key to the operator who edited.
posted_attimestampSubmit time. Immutable across edits.
moderated_attimestampSet on the first moderation action.
updated_attimestampTouched on any edit.
A ban-list entry carries:
FieldTypeNotes
idintegerPrimary key.
scopeenumemail, ip, or both.
email_valuestringRequired when scope is email or both.
ip_valuestringRequired when scope is ip or both. Supports CIDR.
reasonstringFree-text. Operator-side only.
banned_by_user_idintegerForeign key to the operator who created the entry.
banned_attimestampImmutable.
Threading model. Replies reference their direct parent via parent_id and the conversation root via thread_root_id. The denormalized root pointer lets the read path fetch a full thread in a single indexed query, rather than a recursive walk. Thread depth is configurable in the settings panel; the default is 5 levels.

Soft-delete semantics. moderation_state = trash is the soft-deleted state for individual comments. Trashed comments retain all other fields. Permanent delete removes the comment row and orphans the replies up to the deleted comment's parent.

Anti-spam signature. A submitted comment is signed by a hash of body text + author email + source IP + user agent. The signature feeds the spam-training set when an operator marks-as-spam. Future submissions with a matching signature route directly to spam without queue.

PUBLIC-SITE COMMENT SUBMIT│▼┌──────────────────────────┐│ Per-post policy check │ closed → reject; moderated/open → continue└──────────────┬───────────┘│▼┌──────────────────────────┐│ Ban-list match │ email or IP banned → state = blocked└──────────────┬───────────┘│ no match▼┌──────────────────────────┐│ Throttle check │ per-IP rate cap exceeded → reject└──────────────┬───────────┘│ ok▼┌──────────────────────────┐│ Anti-spam ruleset │ signature match → state = spam│ ├─ signature matching ││ ├─ link-count threshold ││ ├─ keyword denylist ││ └─ third-party connector│└──────────────┬───────────┘│ pass▼┌──────────────────────────┐│ Per-post policy applies │ moderated → state = pending│ │ open → state = approved└──────────────┬───────────┘│▼Comment persisted│▼Reply-notification email(if reply + author opted in)

Permissions

Access to the Discussions surface is gated at two layers.

Layer 1 — admin gate. Every action under SG-Admin passes through the standard admin access check at request entry. Unauthenticated requests never reach the Discussions surface. The public-site comment submit entry point bypasses this gate but routes every submission through the per-post policy, ban list, throttle, and anti-spam pipeline described above.

Layer 2 — per-action capability. Within SG-Admin, each Discussions action checks a capability on the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and a Moderator role is a common custom addition on community-heavy sites. The capability map is:

CapabilityAdministratorEditorModeratorViewer
List queue
Approve / reject / spam
Reply
Edit comment body
Soft delete
Restore
Permanent delete
Manage ban list
Bulk action
Edit per-post policy
Edit anti-spam ruleset
Custom roles defined under Settings → Roles override the default map. The Moderator role typically holds the day-to-day queue operations but not the global settings or the permanent-delete capability.

Self-protection rules. An operator cannot ban their own email or IP. The ban list cannot grow beyond the configurable site-wide ceiling (default 10,000 entries) without an explicit raise under Settings → Discussions. Anti-spam rule edits are throttled — no more than 20 ruleset edits per hour, to prevent a misconfigured automation from emptying the queue.

Audit. Every write — approve, reject, mark-as-spam, reply, edit, delete, restore, ban, unban, settings change — emits an Activity Log entry. The log records the acting operator, the comment or ban entry, and the change shape (state transition for moderation, field-level diff for edits, summary for bulk). Public-side comment submissions are not in the Activity Log — the volume would swamp the log; the comments themselves are the audit surface for submissions.

REQUEST → /sg-admin/discussions/...│▼┌────────────────────────┐│ Admin gate │ unauth → reject└──────────┬─────────────┘│ authed▼┌────────────────────────┐│ Capability check │ role lacks cap → reject│ (per-action) │ (custom roles override defaults)└──────────┬─────────────┘│ allowed▼┌────────────────────────┐│ Self-protection rules │ ban-self / list-ceiling /│ │ rule-edit-throttle → reject└──────────┬─────────────┘│ passes▼write executes│▼Activity Log entry│▼Public submissions bypassActivity Log; comments arethe audit surface for those.

Related references

  • Posts — Reference. Every comment attaches to either a post or a page. The Posts module owns the discussion-policy flag on the post record.
  • Pages — Reference. Same — page comments live here, page-level discussion policy lives on the page record.
  • Users — Reference. Operator-authored comments and replies reference user IDs. Per-action capability checks resolve against Users.
  • Email — Reference. Reply notifications and operator-mention emails route through the Email module's templates.
  • Settings — Reference. Discussion-wide defaults, thread depth, throttle thresholds, and the ban-list ceiling live in Settings.
  • Activity Log — Reference. Every moderation write surfaces here for audit and review.
For the corresponding customer-facing walkthrough — clearing a comment queue, banning a repeat offender, configuring an anti-spam policy — see the Discussions section of the customer docs at /docs/discussions.
On this page