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

Laravel Modules Forum Laravel Package

ozankurt/laravel-modules-forum

A Laravel package that adds a ready-to-use forum module to modular applications, including discussion threads, posts, categories, and moderation tools. It integrates with ozankurt/laravel-modules for clean, reusable community features and is easy to install and customize.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • This remains a drop-in Laravel package: it consumes only illuminate/contracts, database, and support, so it does not impose an application skeleton, service provider boot order, or routing convention beyond standard Laravel package discovery via spatie/laravel-package-tools.
  • The module surface is now split across a three-package family (laravel-modules-core, laravel-modules-interactions, and this package), all pinned to ^2.0. That makes the package a participant in a coordinated major-version release train rather than a standalone dependency — architecturally fine, but it means our upgrade unit of work is the trio, not this package alone.
  • Filament 3, 4, and 5 are all supported in the same 2.x line. For an admin-panel-dependent product this is the single most valuable architectural property of the release: it decouples our Filament upgrade from the Laravel 13 upgrade.
  • Caching posture is explicitly declared and unchanged: board and thread reads cached, ACL/policy reads deliberately uncached. That is a defensible correctness-over-throughput decision for authorization, and it is stable across the major version — no hidden performance regression vector here.

Integration feasibility

  • The hard gate is environmental, not code-level. PHP ^8.4 and Laravel ^13.0 are both mandatory; there is no dual-support window. Feasibility therefore collapses to a single question: can our application run on PHP 8.4 and Laravel 13 today?
  • Secondary gate is dependency resolution: ozankurt/laravel-modules-core ^2.0 and ozankurt/laravel-modules-interactions ^2.0 must resolve together with cviebrock/eloquent-sluggable ^12.0 || ^13.0. The sluggable disjunction is helpful — it lets us hold sluggable at 12 while other constraints settle.
  • The SQL hardening is a compatibility fix, not a behavioural change: DB::raw()/orderByRaw() narrowed to literal-string under Laravel 13, and the three affected call sites were rewritten using decrement()/increment()/incrementEach(). This is exactly the class of change that would otherwise have surfaced as a runtime TypeError or a static-analysis wall in our own code, and it is already done for us.
  • Test evidence is credible for a major bump: 145 passed / 461 assertions green, PHPStan level 8 clean, explicit CI matrix across PHP 8.4 × Laravel 13 × Filament 3/4/5. For a TPM this is sufficient to schedule integration spikes, not sufficient to skip our own regression pass.

Technical risk

  • Coordinated-release risk (highest). Any one of the three ^2.0 packages slipping or shipping a divergent minor leaves us unable to resolve. We should treat the trio as a single locked artefact set.
  • No dual-support window (high). Dropping Laravel 12 and PHP 8.3 means we cannot partially migrate, cannot run the new package alongside the old, and cannot A/B the upgrade. Rollback is a full revert of application code plus lockfile.
  • Counter-integrity regression (medium, well-mitigated). Replacing string-spliced post-count updates with decrement()/increment()/incrementEach() changes execution shape in ThreadObserver::created(), deleted(), and restored(). incrementEach() is a single atomic statement where the prior code was a concatenated DB::raw() — this is strictly safer under concurrency. ThreadDeletionDriftTest still asserts board.post_count matches recountBoard across soft delete and restore, which is the correct invariant. Residual risk is only for observers our own code extends or overrides.
  • scopeSearch() qualifier removal (low now, latent later). Dropping the getTable() prefix from the ranking CASE is safe because the scope never joins today. It becomes a correctness bug the moment a future maintainer composes scopeSearch() with a join. This needs a code comment or a guard test, not a code change.
  • Filament 5 support (low). Filament 5 is claimed supported but is the newest axis in the matrix; breadth of support reduces risk but dilutes depth of coverage per version. Pin explicitly to the Filament major we actually run.

Key questions

  1. Is Laravel 13 a stable target for our production timeline, or does this release land ahead of our platform's own Laravel 13 readiness?
  2. Are laravel-modules-core ^2.0 and laravel-modules-interactions ^2.0 published and stable as of this tag, or does the ^2.0 constraint currently resolve to nothing?
  3. Which Filament major are we on, and is there a documented deprecation timeline for Filament 3 within this package?
  4. Does any of our own code override ThreadObserver, extend Thread, or compose scopeSearch() with a join? If so, the SQL rewrites are not fully covered by upstream tests.
  5. Is the deliberate non-caching of ACL/policy reads acceptable at our peak read volume, or does this major version give us a reason to raise it?
  6. What is the rollback plan if the upgrade fails at integration — is a full revert of PHP 8.4 + Laravel 13 + the package trio acceptable to the release calendar?

Integration Approach

Stack fit

  • The package's stack assumptions now match a modern Laravel baseline exactly: PHP 8.4, Laravel 13, Pest 5, Orchestra Testbench 11. It will not be the limiting factor in a modernisation programme — it will be the first dependency ready, which is a good position for it to be in.
  • Three-package family with aligned ^2.0 majors is the right shape for a modular product. It does mean our composer.json should pin all three with matching constraints and a single upgrade ticket.
  • Filament 3/4/5 breadth means the admin layer is not on the critical path. We can take Laravel 13 now and Filament 5 later without touching this package again.

Migration path

  • There is no incremental path by design — the release drops Laravel 12 and PHP 8.3 with no overlap. Migration is a single cut: bump PHP to 8.4, bump Laravel to 13, bump this package and its two ^2.0 siblings together, resolve sluggable at ^12.0 || ^13.0.
  • Because the SQL rewrites ship with the version that requires Laravel 13, there is no intermediate step where we run Laravel 13 against a package that still splices DB::raw() literals. That ordering is correct and removes the most common major-upgrade failure mode.
  • Expect the real migration work to be in our code, not the package's: Laravel 13's literal-string narrowing will flag any DB::raw() in our own application the same way it flagged these three spots upstream.

Compatibility

  • Upstream compatibility is asserted and matrix-tested: PHP 8.4 × Laravel 13 × Filament 3/4/5. Downstream compatibility is unverified by definition — our observers, policy overrides, cache tags, and any custom Thread scopes are ours to prove.
  • Sluggable's ^12.0 || ^13.0 disjunction is the one deliberate compatibility escape hatch in the constraint set; use it to defer that bump rather than let it block resolution.
  • Behavioural compatibility for counter semantics is explicitly preserved and test-asserted. That is the one contract where "no change" needed to be proven rather than claimed, and it was.

Sequencing

  1. Confirm Laravel 13 GA and PHP 8.4 availability on our runtime images.
  2. Verify laravel-modules-core ^2.0 and laravel-modules-interactions ^2.0 are published and resolvable as a set.
  3. Upgrade PHP 8.4 and Laravel 13 in a branch; let static analysis and the full suite expose DB::raw() narrowing failures in our code.
  4. Bring in the package trio at ^2.0 together; resolve sluggable last.
  5. Run our own regression on soft-delete/restore post-count drift (recountBoard invariant) plus any custom observer overrides.
  6. Treat Filament as a separate, later workstream — do not bundle it with this upgrade.

Operational Impact

Maintenance

  • Steady-state maintenance load is low: standard Laravel package conventions, spatie/laravel-package-tools scaffolding, no exotic extensions. Fewer moving parts to babysit than a typical first-party module.
  • The maintenance event is concentrated: this is a hard-gate major that forces a platform-wide upgrade on the vendor's cadence, not ours. Laravel's annual major cadence means we should expect a repeat of this exercise roughly yearly, and budget for it as recurring platform work rather than a one-off.
  • The three-package ^2.0 alignment adds a coordination cost to every future major: three changelogs to read, three release dates to align.

Support

  • Upstream support signal is reasonable: PHPStan level 8, Pest 5, explicit CI matrix, and a test suite that asserts the one behaviour that mattered (board.post_count vs recountBoard across soft delete and restore). That is a maintainer who understands their own invariants.
  • Support risk concentrates in the ozankurt/* sibling packages. Our exposure to this package's quality is now partly exposure to those two packages' quality. Vendor diligence should cover all three.
  • The scopeSearch() qualifier removal is undocumented as a caveat and lives only in release notes. We should not expect upstream documentation to prevent a future maintainer from composing that scope with a join.

Scaling

  • Scaling characteristics are unchanged by this release: board and thread reads cached, ACL/policy reads deliberately uncached. Throughput ceiling and cache-invalidation design are identical to the prior major, so no capacity re-planning is triggered.
  • The uncached ACL/policy path remains the known read-scaling constraint. It is a correct default (authorization must not serve stale grants) but it will be the first thing to hit a database under read pressure. Flag it as an architectural watch item, not a defect.
  • The switch to incrementEach() consolidates post-count updates into a single atomic statement. That is a marginal write-scaling and lock-contention improvement, not a step change.

Failure modes

  • Lockfile deadlock: if any of the three ^2.0 packages lags, composer update cannot resolve and the whole upgrade stalls. Detect early — this is the most likely failure and it happens before any code runs.
  • Partial upgrade drift: running Laravel 13 with a stale package version, or PHP 8.4 with a stale modules-core, is unsupported and will produce confusing failures. Enforce the trio as one atomic change in composer.json.
  • Counter drift under concurrency: materially reduced by the incrementEach()/decrement()/increment() rewrite, but any application code that overrides or reimplements ThreadObserver::created()/deleted()/restored() inherits the old splicing risk. Audit overrides before upgrading.
  • Latent search-scope breakage: a future join composed with scopeSearch() would produce an ambiguous-column error or wrong ranking. Cheap to prevent with a comment or guard test at adoption time.
  • Rollback is all-or-nothing: reverting means PHP, Laravel, and three packages come back down together. Ensure the release is behind a feature flag or a deploy window with a rehearsed revert.

Ramp-up

  • Low ramp for the team: no new APIs, no new configuration surface, no new concepts introduced by this release. It is a compatibility major, so the learning curve is Laravel 13's, not this package's.
  • The one piece of genuine ramp-up is institutional knowledge about the SQL-literal narrowing rule and the scopeSearch() qualifier assumption. Both are capture-in-a-comment items, not training items.
  • Recommend a short written upgrade note in our repo covering: the trio must move together, literal-string narrowing will surface in our own DB::raw() calls, and scopeSearch() must never be composed with a join. That single note converts three latent failure modes into guarded ones at near-zero cost.
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.
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
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast