Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Jev Moderation Laravel Package

phoenix1331/filament-jev-moderation

Filament plugin for JEV moderation that adds review queues, approval and rejection actions, and status tracking to your Laravel admin panel. Designed for teams that need clear, audit-friendly content moderation workflows, it streamlines oversight and keeps moderated items organized.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Ships as a Filament panel plugin (JevModerationPlugin::make()) that layers a review UI over phoenix1331/laravel-jev-moderation 0.2. The plugin deliberately routes all moderation writes through the core's approve() / reject(), so ReviewResolved and existing listeners/audit consumers keep working. That is the right boundary: the plugin owns presentation and workflow, the core owns decision state and events.
  • Scope is broader than a queue: review queue, read-only thresholds viewer, calibration widget, decision-volume chart, overview stats, author history, per-record decision history. It effectively becomes the moderation console for every moderated model in the panel.
  • Multi-model by design (models(), modelLabels(), authorRelation()/authorRelations(), closures throughout), which fits apps moderating several polymorphic types but adds configuration surface at boot.

Integration feasibility

  • Low-friction install: composer require, register the plugin, optionally scope with models([...]), set labels and author relations. No application migrations are described, implying the core owns schema — confirm before assuming zero-migration rollout.
  • Requires core 0.2; any existing integration on an earlier core needs the core upgrade first.
  • Invalid plugin values fail at panel boot rather than at render — fast feedback, but a bad closure or typo takes the whole admin panel down, not just the moderation pages.

Technical risk

  • v0.1.0, pre-1.0: no compatibility guarantees, expect breaking changes across minor versions. Pin exact versions and treat upgrades as changes requiring regression of the queue and action paths.
  • Authorization has two layers with different failure postures. authorize() is fail-closed (must return exactly true; otherwise access only in local), which is a safe default but a common misconfiguration — a closure returning truthy non-true silently 403s every page and widget. Action authorization falls back to allow once page access is granted when neither authorizeActionsUsing() nor a ModerationDecision policy is registered. That is a fail-open default for approve/reject/reclassify and should be treated as a required configuration step, not an optional one.
  • The review queue surfaces content "including content hidden from the site." This is correct for moderators but is a data-governance question: confirm whether viewing hidden content is itself audited, and whether it conflicts with any takedown/retention obligations.
  • Bulk selection spanning model types plus partial-failure semantics (skipped records for concurrent change, deletion, permission, or a policy removed from config) means outcomes are non-atomic. The notification reports counts and reasons, but operators should not assume all-or-nothing.
  • Thresholds are read-only in the UI; changing review_above / block_above / uncertain_below is a config deploy plus a per-model jev-moderation:rescan with a status target. If that rescan is run against the wrong status, moderator decisions get re-checked — a silent quality regression.

Key questions

  • Supported Filament major(s), PHP and Laravel versions, and DB engines? Notes are silent.
  • Is the "changed since page loaded" guard an optimistic-concurrency check (version/updated_at) or a re-read comparison? Determines how often bulk reviews partially skip in busy queues.
  • Pagination, query strategy, and index requirements for the cross-model queue at expected volume (hundreds vs. tens of thousands of decisions).
  • Are the 90-day calibration window, "since midnight," and 7/30/90-day ranges computed in app timezone or UTC?
  • i18n coverage for the UI beyond the navigation group label; the 1280px-with-sidebar layout note suggests viewport testing is desktop-first.
  • What is the retention/audit story for decision history, and does deleted content's retained history include the stored content copy?
  • Who owns the ModerationDecision policy in our app, and does Filament Shield cover approve/reject/reclassify cleanly?

Integration Approach

Stack fit

  • Assumes a Filament panel already in use and the Jev core already moderating at least one model. Best fit for teams that want an in-panel console rather than a bespoke admin screen; poor fit if moderation is expected to live outside Filament or in a separate service.
  • Natural pairing with Filament Shield for the ModerationDecision policy, which lets us avoid writing a custom authorizeActionsUsing() closure.

Migration path

  • Greenfield for this plugin, but not for the core: step 1 is confirming/upgrading to laravel-jev-moderation 0.2 and verifying policy config is readable and versioned.
  • No data migration is expected if the core owns schema; verify, and snapshot the DB before first boot regardless.
  • Existing ad-hoc moderation screens or tinker-based workflows should be retired only after the queue is validated in production, since this becomes the primary path for ReviewResolved emissions.

Compatibility

  • Pin plugin and core to exact versions; the plugin declares a hard dependency on core 0.2 while itself being 0.1.0, so both move together.
  • models() scoping is the compatibility lever: we can adopt without exposing every moderated type at once.

Sequencing

  1. Upgrade/confirm core 0.2; validate policies load and jev-moderation:stats runs clean.
  2. Install plugin with models([...]) limited to one low-risk type; set modelLabels() and authorRelation() explicitly rather than relying on defaults.
  3. Register authorize() returning exactly true for a named pilot group; verify 403 behavior for everyone else in a non-local environment.
  4. Register the ModerationDecision policy (or authorizeActionsUsing()) before enabling any approve/reject path — do not rely on the allow fallback.
  5. Run the queue in shadow mode alongside the existing process; compare DecisionVolumeChart and ModerationOverview override rate against jev-moderation:stats until they agree.
  6. Establish the config-change runbook (threshold edit → deploy → jev-moderation:rescan per model with the correct status target) and rehearse it once.
  7. Enable includeBlocked() and remaining models; roll out calibration review as a weekly moderator ritual.

Operational Impact

Maintenance

  • Pre-1.0 dependency with a fast-moving feature surface; budget recurring upgrade-and-regression time each minor release, focused on the queue, bulk actions, and authorization behavior.
  • Config is code: thresholds live in config, are only viewed in the UI, and require a deploy plus rescan. Expect a steady trickle of "why didn't the threshold change take effect" tickets until the runbook is documented and owned.

Support

  • Two-layer authorization is the most likely support burden: page-level 403s from a mis-typed authorize() return, and over-permissioned actions from an unregistered policy. Both are configuration, not bugs, and both need to be in the onboarding doc.
  • Moderator questions will cluster on reclassify (which categories are offered), report-vs-Jev category matching in filters, and why reports drop out of confidence-range filtering.
  • Single-maintainer risk is plausible for a 0.1.0 package; capture a fallback plan (fork, or revert to core-level workflows) before it becomes critical path.

Scaling

  • The queue is a cross-model, cross-type query joining decisions, content, and authors: the heaviest read path in the package. Validate with production-shaped data and add indexes if the core schema lacks them.
  • Widgets poll — ModerationOverview refreshes every minute per open panel. With many concurrent moderators this is continuous background load; confirm it is lazy/visible-only and consider lengthening the interval for large teams.
  • Bulk actions across model types issue per-record core calls; large selections will be slow and partially skip. Cap selection size operationally.

Failure modes

  • Panel boot failure from invalid plugin configuration (bad closure, unknown model, invalid rate) — takes down the admin panel, not just moderation. Mitigate with staging boots and config validation in CI.
  • Fail-open action authorization: anyone with page access can approve/reject if no policy is registered. Highest-severity misconfiguration.
  • Rescan against the wrong status re-checks moderator decisions, silently degrading calibration data.
  • Partial bulk outcomes: records changed, deleted, re-reported, rescanned, or policy-removed are skipped with counts and reasons; a record the core refuses is reported without halting the batch. Moderators must read the notification rather than assume success.
  • Deleted content retains decision history but loses author context, so author-history views will under-report for deleted material.

Ramp-up

  • Moderators: a short session on the queue, icon-button row actions and tooltips, reclassify, and reading the decisions history (confidence bars, deciding category, Jev version). The calibration widget is analyst-facing, not moderator-facing — teach it to whoever owns thresholds.
  • Engineers: config-change-and-rescan runbook, authorization setup, and the mapping between plugin options and panel behavior.
  • Expect the first threshold change to be the real ramp-up test; assign an owner for calibration review before enabling the widget broadly.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel