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

Story Laravel Package

orchestra/story

Orchestra Story is a Laravel CMS package for Orchestra Platform that adds a simple content publishing layer for stories, pages, and posts. It provides Eloquent-backed models, migrations, and admin-friendly workflows for managing structured content.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Story is not a general-purpose Laravel package — it is a first-party extension of Orchestra Platform v3.2, and its service provider now extends Orchestra\Foundation\Support\Providers\ModuleServiceProvider rather than raw Laravel loaders. That single fact determines the architectural conversation: adopting Story is functionally a decision to run Orchestra Platform as the admin/foundation layer. The 80% it delivers is commodity internal CMS surface — one Content model covering posts and pages, admin CRUD, slugs, publication status, taxonomy, Markdown authoring (SimpleMDE v1.9.1), plus publishable migrations, config, and views. If our admin layer is already Orchestra, Story is a cheap add-on. If it is not, Story is a Trojan horse for a platform migration we have not scoped.

Integration feasibility. The integration seam is deliberately narrow and well-marked: StoryPlugin for menus, assets, and admin screens; ContentPolicy + AuthServiceProvider for authorization; and the front end consumed as a headless content source by querying Content from our own controllers and routes. That last point is the important one for a TPM — Story owns admin CRUD, presentation is ours. Anything built inside Story's admin surface beyond what StoryPlugin sanctions becomes a merge conflict against the next Orchestra bump. Feasibility is therefore high conditional on discipline, and low if the team treats it as a framework to extend.

Technical risk. Three named risks, in order:

  1. Authorization is the real upgrade surface. v3.2.0 removes the CanManage middleware and replaces it with AuthServiceProvider + ContentPolicy. Leftover CanManage references are hard runtime failures; a misregistered policy fails in the more dangerous direction — either 403s to legitimate editors or fails open to unrelated authenticated users. This needs a staged rollout with per-role, per-route verification, not a composer update.
  2. Content::$morphClass removal. Any polymorphic relation pointing at Story content that assumed the old property breaks. The fix is getMorphClass() plus an explicit Relation::morphMap(), and it is the second-most-common "worked in staging" failure.
  3. Unsettled public API. v3.2.0 removes two public surfaces and deprecates a third (Acl aliases → Orchestra\Support\Facades\ACL). With zero dependents and a 0.3 score, there is no community to catch the next breaking change. We are the maintainer, and we should price that in.

Key questions for the team before any commitment:

  • Are we already on Orchestra Platform v3.2, or is this the first step toward it? Sequence the platform decision first; Story is a downstream consequence.
  • Who is the named internal owner for Story maintenance across Orchestra upgrades? Answer before adoption, not after the first incident.
  • Does the roadmap within two quarters require versioning, editorial approval workflow, localization, or structured/typed content modeling? Nothing in this release signals any of those, and they are scoping signals against adoption rather than gaps to patch later.
  • Is the content surface plain posts + pages + Markdown, or is it structured content? Story is the former.
  • Where does content rendering live? If the answer is "inside Story," re-scope.

Integration Approach

Stack fit. Story fits only inside an Orchestra Platform v3.2 admin. Concretely that means: Laravel with Orchestra's service-provider, ACL, and routing conventions present; orchestra/platform or orchestra/foundation pinned to a 3.2-compatible line; Story's migrations, views, and config loaded through Orchestra's ModuleServiceProvider conventions rather than plain loadMigrationsFrom/loadViewsFrom. Verify the fit in an hour rather than a sprint: php artisan route:list --path=story and php artisan migrate --pretend after install confirms provider registration and migration loading, and both fail loudly on the wrong stack. If Orchestra is absent, the honest estimate is that adapting Story to plain Laravel costs more than writing a small posts/pages module — and leaves us maintaining a fork with no upstream path.

Migration path. Treat this as two migrations, sequenced, not one:

  1. Platform migration (if applicable). Move to Orchestra Platform v3.2 and confirm ACL, roles, and routing conventions are stable in our environment. Do not bundle Story into this step; we want a clean platform baseline to diagnose against.
  2. Story adoption. Install against the stable platform, run the smoke test (create a post and page in the admin, render both from our own front-end route gated on status === 'published'), then retire any interim content surface.

Compatibility. The compatibility contract is narrow and should be documented as such: depend only on title, body, slug, status, and the URL helpers url(), editUrl(), deleteUrl(). Use the v3.2 factories Content::newPostInstance() / newPageInstance() rather than new Content so per-type defaults survive. Do not extend Content, do not override its internals, do not bind Blade deeply to anything outside that five-field surface. If a future migration off Story is plausible, put an interface or DTO between Story and our views now — it costs an afternoon and buys an exit.

Sequencing.

  • Week 0: platform prerequisite check; name the internal owner; confirm the roadmap does not require versioning, approvals, localization, or structured content within two quarters.
  • Week 1: install, smoke test, register StoryPlugin for menus/assets, define Relation::morphMap() for story_content.
  • Week 2: build the front-end rendering layer (our routes, our controllers, our views) and the authorization test suite — every ability in ContentPolicy (view, create, update, delete) with a positive and negative case per role. This suite is the regression gate for the authorization model and the precedent for how every other admin module enforces permissions.
  • Week 3: pin the slug-on-publish behavior, re-publish SimpleMDE assets, clear compiled caches, verify url() after a rename.
  • Ongoing: a recurring Story line item on every Orchestra upgrade — coupled roadmaps, not a one-time cost.

Operational Impact

Maintenance. This is the dominant operational cost and it should be presented to stakeholders as such: near-zero upfront cost plus a permanent, single-owner upgrade obligation tied to Orchestra releases. Every Orchestra upgrade becomes a Story upgrade becomes a migration task in the plan. Budget it as a recurring line item, not an integration line item. Two mechanical de-risking tasks belong in the backlog immediately: grep and remove every CanManage reference, and replace Acl aliases with Orchestra\Support\Facades\ACL while the change is still trivial.

Support. With zero dependents and a 0.3 score, external support is effectively nil — no Stack Overflow corpus, no third-party extensions, no community catching breaking changes. Support is internal and must be staffed internally. The mitigation is architectural discipline plus a written runbook covering the three most likely incidents: authorization 403s, broken slugs/URLs, and polymorphic relation failures. For a 403, the checklist is ordered — route:list --path=story -v to confirm middleware, php artisan about to confirm the provider, then check AuthServiceProvider registration, policy discovery or explicit Gate::policy() binding, and finally whether the user's Orchestra role carries the matching ACL action. That third check is the one most often forgotten.

Scaling. The CMS is admin-side only and will not sit on the hot path. Public traffic hits our own controllers querying Content; the scaling story is therefore ours, not Story's. Two things matter: explicit query scoping on publication state (where('status', 'published') with an index on status/published_at) rather than relying on implicit global scopes, and cached rendered bodies keyed on updated_at if the public surface is high-traffic. Markdown rendering through Orchestra's Format facade should not be mixed with a fallback parser like league/commonmark in production — inline HTML handling differs and the inconsistency will surface as a content bug, not a config bug. Pick one.

Failure modes. Ranked by user-visible blast radius:

Failure Symptom Detection
Policy misregistered Silent 403s to editors, or fail-open to authenticated users Per-role authorization tests
Slug drift on edit Live URLs break after a title change url() assertion in tests; pin slug on publish
$morphClass removal Polymorphic relations traverse nothing Regression test on every content relationship
Leftover CanManage middleware Hard runtime failure on that route Codebase grep, pre-deploy
Stale SimpleMDE assets Toolbar renders but behaves inconsistently Re-publish assets, clear compiled caches
Provider double-registration Duplicate routes/views from mixed provider styles route:list review after any provider rebase

The fail-open authorization case is the one to escalate on: it is silent, it is a permissions breach rather than an outage, and the standard smoke test will not catch it.

Ramp-up. Low for a Laravel-fluent engineer, provided Orchestra is already in place — the reading order is short and stable: Content, then ContentPolicy + AuthServiceProvider, then the story routes, then StoryPlugin, then published config/views only if overriding. Budget half a day to the authorization model specifically, since it is both the highest-risk area and the precedent for every other admin module. If Orchestra is not already in place, ramp-up is not measured in Story at all — it is measured in Orchestra Platform, and that estimate belongs in the platform decision, not here.

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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator