Ratings — Reference
The Ratings surface owns numeric and star ratings for SGEN content. It is the scoring plane only — separate from the Reviews surface, which owns the long-form written feedback that often accompanies a score. Anything that captures a "how would you rate this" from a visitor traces back to a record 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 wiring it into a public-site template. Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.
Overview
Ratings live under the Ratings module in SG-Admin. The module renders three primary views — the ratings list, the aggregation surface (averages and distribution histograms), and the per-content moderation queue — and exposes a small set of write operations for accept, reject, edit, recompute, and delete.
The module is intentionally separated from Reviews. A rating is a single numeric value (typically 1–5) attached to a content record. A review is a text body that may or may not include a rating. Treating the two as separate surfaces allows star ratings on products to roll up cleanly into Analytics without dragging the moderation overhead of long-form text along with them.
A second surface — per-content-type configuration — sits adjacent to the main module and controls the rating scale (1–5, 1–10, thumbs up/down), the rendering style (stars, numeric, slider), and whether anonymous visitors may submit a score. The configuration is per-content-type, not per-record.
Where it lives in SG-Admin:
- Sidebar: SG-Admin → Ratings
- URL prefix:
/sg-admin/ratings/ - View templates:
application/views/Admin/Ratings/
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Ratings → Product: "Heritage Tote Bag" │├──────────────────────────────────────────────────────────────────────┤│ Average 4.3 / 5 ││ Total ratings 287 ││ Distribution ││ 5 ★ ████████████████████████ 168 (58%) ││ 4 ★ █████████████ 78 (27%) ││ 3 ★ ███ 24 (8%) ││ 2 ★ █ 9 (3%) ││ 1 ★ █ 8 (3%) ││ ││ [Recompute] [Export CSV] [View moderation queue] │└──────────────────────────────────────────────────────────────────────┘Actions
The Ratings surface exposes the following operations. Each is described by what it does to the data, not by its internal method name.
List ratings
Returns the rating records visible to the current operator, paginated, with content reference, score, submitter identifier, submitted-at, and moderation status. Supports filtering by content type, score band, and moderation status. Driven by the data-table contract used across SG-Admin modules.
Read aggregations
Returns the average score, total count, and distribution histogram for a single content record or a content-type-wide rollup. Aggregations are precomputed by the rollup pipeline and refreshed on a fixed cadence; the recompute action below forces an immediate refresh.
Submit a rating (visitor-facing)
Accepts a score for a target content record from a visitor session. The action validates the score against the content-type's scale, applies the rate-limit configured for the content type, and records the rating in the queue with the moderation status set by the content-type configuration (approved by default, pending if pre-moderation is enabled).
Accept
Sets a single rating's moderation status to approved. Approved ratings are included in the aggregation rollups.
Reject
Sets a single rating's moderation status to rejected. Rejected ratings remain in the database for audit purposes but are excluded from aggregations.
Edit a rating
Replaces the stored score or moderation status for a single rating. Edits are audit-logged with the prior and new values. Edits should be rare — the typical moderation path is accept or reject.
Delete a rating
Hard-removes a single rating. Available only for the Administrator role. Aggregations are recomputed on the next rollup cycle (or immediately via the recompute action).
Recompute aggregations
Forces an immediate refresh of the average, total, and distribution for one content record or one content type. The standard rollup cadence is sufficient for most surfaces; recompute is exposed for cases where the operator needs the new value reflected immediately (a marketing email about to ship, a live broadcast referencing a current score).
Set per-content-type configuration
Stores the rating scale, rendering style, rate-limit, moderation default, and anonymous-submit flag for one content type. The configuration is consumed by the public-site renderer and by the submission validator on every incoming rating.
Data model
A rating 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.
| Field | Type | Notes |
|---|---|---|
id | integer | Primary key. Stable across edits. |
content_id | integer | Foreign key into the content table for the type. |
content_type | string | The content type slug. |
score | integer | Score on the configured scale for the content type. |
submitter_id | integer | User identifier when submitted by a signed-in visitor. NULL when anonymous. |
submitter_session | string | Session token when submitted by an anonymous visitor. Allows rate-limit enforcement without a user record. |
moderation_status | enum | One of approved, pending, rejected. |
submitted_at | timestamp | Set on initial submit. |
moderated_at | timestamp | Touched on accept, reject, or edit. |
moderator_id | integer | User who set the current moderation status. |
| Field | Type | Notes |
|---|---|---|
content_type | string | The content type slug. |
scale | enum | One of 1-5, 1-10, thumbs. |
rendering_style | enum | One of stars, numeric, slider. |
allow_anonymous | boolean | When false, only signed-in visitors may submit. |
pre_moderate | boolean | When true, submissions land in the queue with pending status. |
rate_limit_window_minutes | integer | Window for the submitter-side rate limit. |
rate_limit_max | integer | Max submissions per window. |
| Field | Type | Notes |
|---|---|---|
content_id | integer | Foreign key. |
content_type | string | Slug. |
average | decimal | Mean of approved scores. |
total | integer | Count of approved scores. |
distribution | object | Map of score → count. |
computed_at | timestamp | Last rollup time. |
RATING RECORD├── id integer primary key├── content_id integer foreign key├── content_type string slug├── score integer on configured scale├── submitter_id integer NULL when anonymous├── submitter_session string for anonymous rate-limit├── moderation_status enum approved | pending | rejected├── submitted_at timestamp├── moderated_at timestamp└── moderator_id integerCONTENT-TYPE CONFIG├── content_type string slug├── scale enum 1-5 | 1-10 | thumbs├── rendering_style enum stars | numeric | slider├── allow_anonymous boolean├── pre_moderate boolean└── rate-limit settingsAGGREGATION (precomputed)├── average · total · distribution└── computed_atPermissions
Access to the Ratings surface is gated at two layers.
Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Ratings admin surface. The visitor-facing submit action passes through a separate public-site gate that respects the per-content-type allow_anonymous flag.
Layer 2 — per-action capability. Within SG-Admin, each Ratings action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:
| Capability | Administrator | Editor | Viewer |
|---|---|---|---|
| List ratings | ✔ | ✔ | ✔ |
| Read aggregations | ✔ | ✔ | ✔ |
| Accept | ✔ | ✔ | — |
| Reject | ✔ | ✔ | — |
| Edit a rating | ✔ | — | — |
| Delete a rating | ✔ | — | — |
| Recompute aggregations | ✔ | ✔ | — |
| Set per-content-type configuration | ✔ | — | — |
Submission rules. The public submit action enforces the rate-limit window configured for the content type. Submissions exceeding the limit are rejected at the gate without writing a record. Anonymous submissions are rejected when allow_anonymous is false.
Audit. Every write — accept, reject, edit, delete, recompute, configuration change — emits an Activity Log entry. The log records the acting operator, the target record, and the field-level diff. Visitor submissions are logged in a separate submission stream rather than the Activity Log.
VISITOR SUBMITS RATING│▼┌───────────────────────────┐│ Public-site gate │ scale ok? rate-limit ok?│ │ anonymous allowed?└─────────────┬─────────────┘│ accepted▼┌───────────────────────────┐│ Write rating record │ status = approved OR pending└─────────────┬─────────────┘│▼┌───────────────┐│ pre_moderate? │└──────┬────────┘no │ yes▼ ▼included awaiting moderatorin │rollup │▼accept / reject│▼next rollup cyclerecomputes aggregationRelated references
- Reviews — Reference. Owns the long-form text body that often accompanies a rating. A review record may carry a rating reference; the rating itself lives in this module.
- Comments — Reference. Public comments share the moderation queue UX with Ratings; the two streams are stored separately.
- Analytics — Reference. Reads the Ratings aggregations and joins them against traffic, sessions, and conversion data.
- Custom Fields — Reference. Per-content-type rating configuration is exposed alongside Custom Fields for that content type.
- Custom Objects — Reference. Custom content types can opt in to the Ratings surface by enabling the rating-scale configuration.
- Activity Log — Reference. Records every Ratings moderation write.
/docs/ratings.