Skip to content

Releases: phoenix1331/filament-jev-moderation

Release list

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 17:08
v0.1.0
97e1f2b

Added

  • Review queue (Moderation > Review queue): every record whose latest decision is a flag (and a block with includeBlocked()), across every moderated model, with its current content (including content hidden from the site) under its type, author, category with its source beneath, confidence and time waiting, laid out to fit beside an open sidebar at 1280px. Most confident first, then longest waiting; reports show their reason and the category Jev gave before them. The navigation badge shows how many are waiting
  • Approve and reject in the review queue, for one record or a selection across model types, with an optional note (up to 2,000 characters). Reviews are recorded through the core's approve() / reject(), so ReviewResolved fires as usual. A record that changed since the page loaded (already reviewed, reported again or rescanned), was deleted, or that the moderator may not review is skipped, and the notification says how many; a record the core refuses (for example, its policy was removed from config) is reported with the reason without stopping the rest
  • Thresholds page (Moderation > Thresholds), read-only: each policy's review_above, block_above, uncertain_below and version from config, the models using it, and every calibration band alongside. Each suggestion comes with the php artisan jev-moderation:rescan command to run for each model after changing config, naming the status the change affects (flagged, or blocked after raising block_above) so moderators' decisions are never re-checked. A policy that cannot be read from config is listed with the reason instead of breaking the page
  • Calibration widget (CalibrationTable): for each policy and category, how often moderators overturned Jev in each 0.1 confidence band over the last 90 days (checked, overturned, upheld, override rate and missed), for the newest Jev version with a selector for older ones. Low-confidence flags get their own lane. Bands overturned more than overrideWarningRate() with at least minimumSample() reviews are highlighted with the threshold change they suggest: raise review_above or block_above, or lower uncertain_below. Below the review queue it lists only those bands (onlyFlagged), linking to the thresholds page for the rest
  • Volume chart widget (DecisionVolumeChart) below the review queue: decisions per day, stacked by status, over the last 7, 30 (default) or 90 days, with each status's total as text. Each status keeps one colour, checked for colour-blind and normal-vision separation in light and dark mode
  • Review queue row actions are icon buttons with tooltips, placed before the columns so they stay in view on narrower screens
  • Overview stats widget (ModerationOverview) above the review queue: records waiting and the oldest wait, automatic blocks since midnight, median time from queued to reviewed and the override rate over the last 7 days. The override rate counts reviews exactly as php artisan jev-moderation:stats does, so the panel and CLI agree, and turns red above overrideWarningRate() once minimumSample() flags and blocks have been checked. Add it to your own dashboard too; it refreshes every minute
  • Author history page, linked from the author in the review queue and on the decision history page: every decision about an author's content across the moderated types they author (through each model's author relation), newest first, each opening its history, with counts per status for the last 7 and 30 days. Content the core hides is included; deleted content is not, as its author can no longer be read
  • Decision history page (Moderation > Review queue > History), opened by clicking a queued row: the record's content as it is now and its author, then every Jev result, report, moderator review, rescan and failed check, newest first, with the moderator or reporter, note or report reason, Jev version, policy name and version, why Jev decided (including its own confidence for low-confidence flags), the copy of the content checked when the core stores one, and each result's category probabilities as a bar list with the deciding category highlighted. Opens on any decision for a shown model type, highlighting it; deleted content keeps its history
  • "View" link on each queued record to its page in your own Filament resource for the model (view page, else edit page, as the user is allowed), opening in a new tab; hidden when there is none. recordUrlUsing() replaces the default with your own URL, or null to hide it
  • Reclassify in the review queue: remove content under a corrected category when Jev picked the wrong one, recorded through the core's reject() with that category. Offers the harmful choices of the record's policy other than the category it was queued under; hidden when the record's policy was removed from config
  • Review queue filters: model type, category (a report matches on the category Jev gave before it; options are the choices of the shown models' policies), confidence range in percent (inclusive, reports drop out), source, and date queued
  • Requires phoenix1331/laravel-jev-moderation 0.2
  • authorize() decides who may use the moderation pages and widgets: the callback must return exactly true, and without one access is allowed in the local environment only. Pages return 403 on mount and every request; widgets too, even when mounted directly
  • Moderation actions (approve, reject, reclassify) are checked on top of authorize(): through authorizeActionsUsing() when given, else through a registered ModerationDecision policy (Filament Shield or your own; abilities approve, reject, reclassify), else allowed to anyone with access
  • JevModerationPlugin with make(), get() and current(), and options for the navigation group (default "Moderation", translatable), icon and sort; models([...]) to limit the plugin to some moderated models (default: every type with decisions); includeBlocked() to queue automatic blocks as well as flags; modelLabels([...]) to name model types; authorRelation() and authorRelations([...]) for author history (default: the user relation); overrideWarningRate() and minimumSample() for calibration. Closures are accepted throughout, and invalid values fail when the panel boots