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

Rotor Laravel Package

visavi/rotor

Rotor is a modular Laravel admin panel and CMS toolkit from Visavi. It helps you scaffold management interfaces with CRUD resources, authentication, menus, and a responsive UI, so you can manage users, content, and settings without building a backend from scratch.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Rotor is not a Composer library — it is an application skeleton: a Laravel 13 / PHP 8.3+ modular monolith with a modules/ plugin convention and an in-app administration surface. "Integration" therefore means platform adoption or HTTP-level federation, not dependency management. v14.8.0 does not change that framing; it adds evidence about the pace and shape of churn we would own.

Delta in this release that matters to a TPM

  • Module migrations become artisan-visible. php artisan module:migrate applies new migrations for enabled modules and resets settings cache; deploy.php runs it after artisan:migrate. This is the first upstream acknowledgement of the schema-provenance gap identified previously. It converts a hard blocker into a documented pipeline step — but activation-time application and the absence of rollback remain.
  • Core functionality continues to be pushed out into modules. Feedback and MailNotify were extracted from core; upgrading without installing them from the catalog silently stops outbound mail and removes the contact form. That is a new class of upgrade hazard: feature loss by omission, not by failure.
  • Hook API instability confirmed. The homepageView hook is removed in favour of Registry::homepage(). Only one minor release after our assessment argued for "hooks over core edits" — hooks are not a stable contract either.
  • Theme partial rename (_language_modal/_comment_edit_modal → *_dialog, data-dialog attribute). Any theme work we commission inherits a rename obligation per release.
  • API movement, in both directions. Additions: GET /api/comments, per-list sort values in the spec, structured vote error codes, and module-facing scopes (withUserVote(), capped()/CappableTrait, apiUser()). Tightening: ?user= now requires a token and returns 403 for guests. The surface is still per-module, still unversioned; the token change is a reminder that a federated client has no contract stability guarantee.
  • Two previously-listed risks retired. The empty-field null + strict_types TypeError is fixed, and error pages now render without a theme (correct status codes, JSON for API). spatie/laravel-ignition is removed, slightly shrinking the dependency-conflict surface.
  • cron.php for path-only cron hosts and hideable admin warnings reveal the target deployment: shared hosting, not container orchestrators. Useful signal for capacity planning, not a feature we would use.

Architecture fit

  • Core lives in app/; forum, blogs, gallery, language packs, and now feedback and mail notification are modules in modules/. Extension points are module registration, hooks (App\Support\Hook, Registry), Blade components and a declarative data-ajax contract. Fits a product that is a community/content site.
  • Poor fit for grafting forum/blog/gallery capability into an existing domain model. Modules assume ownership of their tables, routes, views, translations and settings screen; they do not compose into someone else's aggregate.
  • The generator (php artisan make:module Name --model=Item --admin --api) remains a hard dependency, not a convenience — copying a neighbouring module is documented as losing translations, changelog and model registration.
  • Frontend is Vite + Bootstrap utilities. v14.8.0 moves modals to native <dialog> and disclosure blocks to <details> (better accessibility, less bespoke JS), and replaces ad-hoc flash handling with notyf. Still no per-module JS bundle and no <script> execution inside ajax partials; anything beyond the {success, message?, html?, redirect?} contract requires core changes.
  • Front-page selection is now a registry concern (Registry::homepage()) with a FeedService::getLatest() fallback. Cleaner than the removed hook, but it means our theme and any custom homepage are coupled to a registry API that has already changed once.

Integration feasibility

  • Code-level reuse remains the expensive option: fork, own, track upstream. No composer require path.
  • HTTP-level reuse remains the tractable option: Rotor as a separate service on a subdomain, identity bridged via shared cookie domain or an OIDC/token shim, search and navigation federated at the edge. Cost is a second deployable and a session bridge; benefit is a capped blast radius and preserved merge-ability.
  • Sharing the users table directly is still unwise — core owns that schema and mutates it via database/upgrades/. Prefer a brokered identity mapping.
  • A federated consumer must now also handle the ?user= token requirement on user listings; assume further tightening at each minor release and keep the client contract behind our own adapter.

Technical risk

  • Licence: GPL-3.0 copyleft. Distributed forks (appliance, on-prem, shipped source) must be GPL; SaaS-hosted internal use is generally unencumbered (no network clause). Legal gate, unchanged, still blocks any code work.
  • Maturity/bus factor: small star count, apparently single-maintainer, no commercial support, developer docs agent-oriented and largely Russian (AGENTS.md). v14.8.0 is a substantive minor release — evidence of an active maintainer, and of velocity we must track rather than set.
  • Platform currency: Laravel 13 + PHP 8.3 leads the ecosystem; third-party packages we may want may not yet declare support. Removing ignition helps marginally.
  • Active deprecation cycle to 15.0. App\Classes\* is a bridge "until 15.0"; /mails and /admin/modules/module?module=Name are explicit bridges to 15.0; the homepageView hook is already gone. Assume at least one breaking removal per minor release and one large break at 15.0.
  • Schema lifecycle remains application-managed. Core splits database/migrations/ (fresh install) from database/upgrades/ (existing sites); module migrations apply on activation and, as of 14.8.0, can also be applied via module:migrate — but there is still no standard rollback and fresh vs. upgraded paths can diverge. module:migrate is materially better than nothing and should be treated as the load-bearing mechanism, not a safety net.
  • Upgrade completeness is now a correctness risk, not just a chore. Because features were extracted to catalog modules, a technically successful git merge + artisan migrate can leave mail broken and the contact form missing. This is the risk profile of a platform with a plugin marketplace, and it demands a checklist, not diligence.
  • Data remediation is occasionally manual. The pinned-news regression requires re-saving affected records once post-upgrade. Expect periodic one-off data touch-ups that our pipeline cannot express.
  • Dev/test friction: DB-touching commands must run in-container; --env=testing without .env.testing silently hits the real database; strict MySQL forbids truncate()/DDL under RefreshDatabase; a known "risky — did not close its own output buffer" failure mode exists. Suite must be made trustworthy before it is a quality gate.
  • Symlinked modules: a module may be a symlink into rotor-modules; absent in CI/prod it vanishes without error. module:migrate operating on "enabled modules" makes a silent absence harder to notice, not easier.

Key questions

  1. Is the product a standalone community/content site, or do we need these capabilities inside an existing domain model?
  2. Has Legal cleared GPL-3.0 against our distribution model (SaaS vs. shipped/appliance)?
  3. Must identity be shared with an existing user store, and is a token-broker bridge acceptable versus shared tables?
  4. What API contract does mobile require, and are we prepared to own an adapter that absorbs per-minor-release changes (latest: token-gated ?user=)?
  5. Do we need multi-tenancy, Postgres, or SQLite test portability? All three remain poor fits.
  6. Who is the named internal Rotor owner, and what is the upstream-tracking cadence — including a per-release check for newly extracted core modules?
  7. Is the target host able to run dedicated queue workers for in-app media/video conversion?
  8. Are we prepared to re-verify theme partials and hooks at every upstream minor? (One hook removed and two partials renamed in this release alone.)

Integration Approach

Stack fit

  • Laravel shop: low conceptual friction, high convention friction — module activation, dual migration trees, catalog-module installs, deploy steps.
  • Non-PHP shop: treat strictly as an external service; no code integration.
  • Frontend is mobile-first Bootstrap with no component library; native <dialog>/<details> improve baseline behaviour but provide nothing for a design-system-driven or dense desktop product.
  • Treat MySQL as a hard requirement: strict mode, upsert restrictions and upgrade files all assume it.
  • Do not design for shared hosting even though upstream optimises for it (cron.php, mail-less operation); we need containers, queue workers and object storage.

Migration path (dependency-ordered)

  1. Licence review — gate, ~1 week, no engineering effort until cleared.
  2. Bounded schema spike — fresh fork, Docker up, generate a throwaway module, activate it, run module:migrate, and document exactly what artisan migrate, activation and module:migrate each do and do not do. Exit criterion: can we reconstruct a production schema from git plus one documented activation step, deterministically, in CI? Two weeks, one senior Laravel engineer.
  3. Choose the mode — adopt (platform base), federate (separate service), or borrow (patterns only). Default: federate whenever an existing product is in play; adopt only if the product genuinely is a forum/community site and we accept fork ownership.
  4. If adopting — production pipeline that (a) dereferences module artifacts, (b) runs artisan:migrate then module:migrate as explicit logged steps, (c) asserts an expected enabled-module count at boot, (d) installs catalog modules we depend on (MailNotify, Feedback, and the content modules) as pinned artifacts rather than in-admin clicks. Then identity, theme, observability, and finally port differentiators as generated modules.
  5. If federating — subdomain and edge routing, auth bridge, shared navigation, cross-service search. Keep core untouched to preserve merge-ability, and put the token/?user= change behind our own adapter so upstream API tightening is a config change, not a release.

Compatibility

  • Pin PHP and Laravel; audit every added Composer dependency for declared Laravel 13 support. Note that core now ships without ignition — do not re-add a conflicting dev-error package without checking.
  • Custom modules must honour the platform contracts: default(0) counters, no partial-column upsert (use update() with CASE), HtmlCast/TextCast for user text, FileService::rules()/attach() (now also the API's file validation path), withUserVote(), capped()/CappableTrait, PlaceCast for normalised user-supplied place names, data-ajax responses with no bespoke window.* handlers. Deviating produces silent sanitisation gaps or TypeError 500s.
  • Prefer hooks and Registry over core edits — but assume both change at minor cadence and budget a verification pass per upgrade.
  • Themes are a moving target: alias/rename partials in a theme-owned compatibility layer so upstream renames (*_modal → *_dialog) are a one-line change.

Sequencing that actually gates

  • Legal sign-off → before any code.
  • Schema-provenance proof, now including module:migrate behaviour → before deploy design.
  • Module-generator smoke test → before feature estimation; it calibrates real velocity.
  • Catalog-module inventory and install automation → before first production upgrade, not during it.
  • Identity bridge → parallel with features, must land before user-facing launch.
  • Theme work → only after the module inventory is frozen, or it is rework.

Operational Impact

Maintenance

  • Fork ownership remains the headline cost; the module-extraction trend increases it. Budget ~15–25% of one engineer steady-state, materially more in a Laravel-major year — and 15.0 is explicitly a breaking removal (bridges for /mails, /admin/modules/module?module=Name and App\Classes\* all terminate there).
  • Schema changes still arrive as application-applied files, but module:migrate plus its inclusion in deploy.php gives us a defensible pipeline hook. Still required: a written runbook and a schema-snapshot/diff job across fresh-install and upgraded paths.
  • Adopt upstream's changelog.md / ## Unreleased convention for our own modules, and maintain a per-upgrade checklist covering: newly extracted modules, removals in "⚠️ При обновлении", theme partial renames, hook changes, and manual data re-saves.
  • Two full upgrade-and-rollback rehearsals per year, one of them on a restored production copy.

Support

  • No vendor, thin community, docs written for AI agents in Russian. Effectively self-support: designate a named Rotor owner, publish an English "house rules" page distilled from AGENTS.md plus our upgrade checklist, and schedule fork-upgrade reviews.
  • Security response is ours: we watch upstream, we backport. The licence permits it; nobody is obliged to help.
  • Release velocity is real but unreviewed by anyone but the maintainer. Treat every minor as potentially breaking until rehearsed.

Scaling

  • Conventional Laravel/PHP-FPM + MySQL; read replicas and shared Redis cache are the expected levers, to be validated in the spike since settings/registry/hooks are boot-time concerns, and module:migrate now also resets settings cache.
  • Known hot path: feed pagination — capped() deliberately pages only the first ~1,000 rows per section feed. Product-level cap; unbounded history means changing core and owning the divergence.
  • Media remains the capacity story: conversion on attach via FileService::attach(); galleries and uploads need dedicated queue workers and object storage sized up front. New attachment ordering/cover selection adds a write path but not new capacity risk.
  • Extracted mail module means outbound volume now flows through a catalog plugin — verify queue and rate behaviour under load before launch.

Failure modes, ranked

  1. Feature loss by omission after upgrade — extracted modules (now MailNotify, Feedback) not installed, so mail and the contact form disappear with no error. Mitigate with a pinned catalog-module manifest and a post-deploy smoke check of mail send and contact submit.
  2. Schema divergence between fresh installs and upgraded sites. Mitigate with a canonical snapshot, deliberate testing of both paths, and module:migrate as an explicit logged step.
  3. Module activation partially applying migrations with no rollback. Mitigate with a pre-activation snapshot and activation as a pipeline step, not an admin click.
  4. Missing symlink target in CI/prod → module silently absent. Mitigate by materialising modules into build artifacts and asserting expected module count at boot.
  5. 15.0 deprecation removal → hard break on bridges and App\Classes\*. Mitigate by banning new App\Classes\* imports, avoiding /mails and legacy admin module URLs, and tracking movement to App\Support\* and registry APIs.
  6. Theme/hook contract drift — partial renames and the homepageView removal break custom themes silently. Mitigate with a theme compatibility layer and a render test on key pages.
  7. API contract drift for federated clients — token-gated ?user=, per-list sort keys, evolving error shapes. Mitigate with an internal adapter and contract tests.
  8. Manual data remediation after upgrade (e.g. re-save pinned news once). Mitigate with a documented post-upgrade data task list per release.
  9. Ajax contract drift → JSON error where HTML expected. Partly mitigated upstream (JSON errors for any API error, status-correct error pages); keep a contract test on data-ajax responses.
  10. GPL non-compliance in a distributed build. Mitigate with licence notices, a source-offer process and an SBOM.
  11. Suite flakiness eroding the quality gate — risky-output-buffer and truncate() patterns under strict MySQL. Fix early or declare manual QA on those paths.
  12. Empty-field strict_types 500s — retired this release; keep casts on the code-review checklist to prevent regressions.

Ramp-up

  • A Laravel-fluent engineer is productive with the module generator within a week; non-obvious rules (module migrations, strict-MySQL upserts, file service, casts, ajax, registry) take ~3–4 weeks to internalise. The Russian-language agent docs accelerate tooling more than people — plan a human-facing onboarding artifact.
  • Indicative plan: 2-week gated spike; 5–6 engineer-weeks to production-capable adoption (pipeline incl. catalog-module automation, identity, theme, observability) before feature work; ~0.2 FTE steady-state, plus an explicit half-day per upstream minor for upgrade rehearsal.

Recommendation: conditional go, and only as a federated standalone community service — after Legal clears GPL-3.0 and the spike proves reproducible schema including module:migrate and activation on both fresh and upgraded paths. Do not adopt as the base for an existing product. This release improves the operational story (module migrations reachable from artisan, error-page correctness, fewer dependencies) while confirming the two structural costs we must accept: single-maintainer churn to a scheduled 15.0 break, and a platform where upgrading successfully can still remove features unless we install the modules core has shed. This remains an application you take ownership of, not a dependency you consume.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin