roundly-consulting/events-for-laravel
A lightweight events package for Laravel that streamlines defining, dispatching, and listening to application events. It offers a clean, framework-native API with sensible defaults and simple registration, so you can add event-driven behaviour to your app without boilerplate.
Architecture fit
events-migrations, publishable routes/events.php, artisan commands (events:doctor, events:repair), a first-party fake (Events::fake()) with assertion helpers, policy-driven authorization, and JSON-LD serialization.events.resources.*, events.organizers / events.attendees aliases) and now round-trips aliases in responses — a deliberate API-contract decision, not just an internal refactor.TIMESTAMP range and DST write failures, and tightens schedule math. Architecturally the package stays the same; the schema substrate changes on MySQL/MariaDB.Integration feasibility
vendor:publish --tag=events-migrations (adds only 0008) then php artisan migrate. Feasible in a normal sprint, but the migration rebuilds seven tables on MySQL/MariaDB, so it is an operational change, not a code-only bump.routes/events.php must hand-edit middleware (UseConfiguredGuard on the outer group). Hosts that did not publish are unaffected.events:doctor gives a pre-flight/post-flight signal (warns while the events table still stores TIMESTAMP), which is useful for gating a rollout.Technical risk
TIMESTAMP → DATETIME on seven tables is generally a copying ALTER in MySQL/MariaDB, holding locks proportional to table size. Needs a window or an online-schema-change tool.PATCH /events/{event}/attendees/{rsvp} previously leaked the manager view to any signed-in user; read routes now recognise configured guards. Both are fixes worth expediting, but they change 403/422 behaviour that existing clients and tests may rely on.type now renders the configured alias (user) rather than the class basename (User); clients comparing on basename break. A manager's confirm() without a reference now means "paid another way" and drops the online checkout — downstream reconciliation/refund logic must be re-verified.EventFullException / TierSoldOutException when a waitlisted party would fit; rescheduling an announced event to a date already past returns 422 invalid_schedule; reschedule() clears draft doors time.Events::fake() now records builder chains and attendee-initiated payment requests; assertNo…() pairs previously passed for no-op calls and now do not. Expect a wave of test failures that are corrections, not regressions.Key questions
pt-online-schema-change / gh-ost available and permitted?routes/events.php and config/events.php published locally (i.e. does the manual middleware step apply)?type against a class basename?confirm() without a payment reference and currently expect the checkout to survive?Date::use(CarbonImmutable::class) in play (previously fatal on save)?events.routes.auth_middleware, and do read endpoints see the same caller identity as write endpoints after upgrade?Stack fit
auth:sanctum called out). No non-standard infrastructure is introduced.0008 — both column types are equivalent there — so only MySQL/MariaDB installs carry migration cost.Events::fake() assertion semantics changed in both directions, so CI will be the primary detector of behaviour assumptions.Migration path
^1.1; deploy application code first — 1.1 runs against the old TIMESTAMP schema (events:doctor warns), so deploy and migrate can be decoupled.php artisan vendor:publish --tag=events-migrations; diff the published directory to confirm only 0008 is added and nothing previously published is rewritten.routes/events.php was published, add UseConfiguredGuard to its outer group and commit that edit alongside the dependency bump.php artisan migrate with the application's exact DB connection env (host, database, session time zone) during a low-traffic window; capture row counts and migration duration for the runbook.events:doctor and confirm the TIMESTAMP warning is gone; spot-check starts_at, sale windows, holds, check-ins, and created_at against a pre-migration snapshot.Compatibility
type, confirm() semantics, guest/waitlist precedence, stricter 422s), plus the mandatory middleware edit for hosts with published routes.migrate.events.resources.*, events.schedule.max_duration, waitlist.stop_promoting_before, events.routes.auth_middleware) are read, not renamed — but semantics shift (duration now measured in the event's own time zone or elapsed time, whichever is more permissive).Sequencing
Europe/Bratislava is the exact scenario called out) to prove both the conversion and the spring-forward write path.type comparison and confirm() call sites have been audited.Maintenance
events.resources.* mappings as host models and aliases evolve; the alias is now the public contract.Support
tier/guests, 422 invalid_tier for over-precise currency amounts, 422 invalid_schedule for reschedules into the past, EventFullException / TierSoldOutException when guests are added while a waitlist would fit, and RsvpPaymentRequestDiscarded when a hold is refreshed mid-checkout.confirm() without a reference is now a semantic "cash at the door" signal with wasPaid: false on exit; support scripts for refunds and attendance reporting must reflect that.Scaling
DATETIME and TIMESTAMP index characteristics are comparable; query performance should not regress and 2038 and DST-gap write failures disappear.migrate on the primary.Failure modes
UseConfiguredGuard → authenticated callers read as guests on read routes (private events, own RSVP, filter[mine], online link), i.e. a quiet functional and privacy regression rather than an error.type as class basename → silent misrouting in client code, not a server error.confirm() behaviour in downstream code → refunds issued against a checkout the package already dropped, or double-charges at the door.Ramp-up
confirm() semantics, waitlist precedence for guests, past-date reschedule rejection, and the new 422 codes.type comparisons and any consumer of the attendee PATCH response before rollout.How can I help you explore Laravel packages today?