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

Scheduling Bundle Laravel Package

novosga/scheduling-bundle

Scheduling bundle for Novo SGA that adds appointment booking, service and time-slot management, and queue-friendly workflows to PHP applications. Helps organize availability and connect scheduling with existing Novo SGA operations.

View on GitHub
Deep Wiki
Context7

Getting Started

Before writing any code, verify the package actually installs into your app:

composer require novosga/scheduling-bundle:^2.3
composer why-not novosga/scheduling-bundle 2.3.0

The second command matters most. v2.3.0 moves the package to Symfony 7.4 LTS, so anything in your dependency tree still holding symfony/* at 7.1–7.3 (or a Laravel version that caps below 7.4) will block the install with a confusing conflict message.

Then read vendor/novosga/scheduling-bundle/ in this order:

  1. The bundle class and Resources/config/ — the container wiring lives here. There is no Laravel service provider, no config/scheduling.php, no facade.
  2. The domain entities — Scheduling, Schedule, Service, Place/Unit, User. These are Doctrine-mapped, not Eloquent.
  3. The scheduling manager/service that creates and validates appointments.
  4. The console commands — v2.3.0 changed their datetime handling.

First use case: create a scheduling (appointment) for a service at a unit. This is the right place to start because v2.3.0 touched both ends of that flow — command input is now UTC, and confirmation display now uses the unit's timezone. Get that round-trip correct before anything else.

Implementation Patterns

Decide on the integration boundary first. This is a Symfony bundle with Doctrine entities. Three realistic options, in order of decreasing pain:

  • Run Nova SGA as a separate Symfony service and integrate over HTTP/queue. Almost always the right call for a Laravel shop.
  • Bridge the container — boot a minimal Symfony kernel inside a Laravel service provider and expose the scheduling manager as a singleton. Workable, but you now own two lifecycles.
  • Port the domain classes — the entities and value objects are largely framework-agnostic; mapping them to Eloquent is feasible for read-heavy use, but you lose the package's validation and the sync machinery.

Treat UTC as the storage contract. After the v2.3.0 fix, commands expect and emit UTC datetimes. Persist everything UTC, and convert only at the display edge:

// input boundary — normalise before handing to the scheduler
$startsAt = Carbon::parse($request->input('starts_at'), $unit->timezone)
    ->utc();

// output boundary — confirmation display follows the unit, not the app
$confirmation = $scheduling->startsAt
    ->copy()
    ->setTimezone($unit->timezone)
    ->translatedFormat('D, d M Y H:i');

The asymmetry is deliberate: the app config timezone is not the reference point. The unit's timezone is. Make sure the timezone column on your unit/place record is populated — a null there is the most likely source of "the confirmation says the wrong time" reports.

Wrap creation in a transaction with an explicit conflict check. The bundle validates schedules, but concurrency is your problem. Run the create inside DB::transaction() (or the Doctrine equivalent) and re-check overlap after acquiring the row.

The new sync button (PR #8) is a UI affordance that triggers a synchronization run. Treat it as an admin action, not a request-path action:

  • queue it rather than executing inline;
  • guard against overlapping runs (cache lock or withoutOverlapping on the job);
  • surface the run outcome in the UI so operators know it completed.

Hook notifications off domain events, not controller code. If the bundle dispatches events on scheduling lifecycle, subscribe to them and dispatch your own Laravel jobs from the listener — that keeps the bridge thin.

Gotchas and Tips

  • It is not a Laravel package. No auto-discovery, no Illuminate\Support\ServiceProvider, no publishable config. app(SchedulingManager::class) will not resolve it. Budget for adapters.
  • Doctrine and Eloquent can coexist, but not cheaply. Two connection configs, two migration paths, two identity maps. If you're bridging rather than porting, keep the models in separate namespaces and never let a Doctrine entity leak into a Blade view.
  • Symfony 7.4 is a hard floor and possibly a ceiling. Check composer why-not output before assuming a version bump is safe; the upgrade from 7.1 is LTS-aligned but will surface in any package still pinning older components.
  • Datetime regressions hide in tests, not in the browser. If your app timezone is UTC, pre-2.3.0 bugs were invisible. Add a test that sets the unit timezone to something non-UTC (e.g. America/Sao_Paulo) and asserts both the stored value and the rendered confirmation.
  • Dev tooling in PRs #6–#7 is not a runtime concern. PHPStan 2, PHPUnit 11, PHPCS 4 affect the package's own CI. If you fork or patch, expect new static-analysis rules and a stricter phpcs.xml.
  • "symfony 7.4 deprecations" (PR #7) means the package silenced its own deprecations — it does not mean yours are gone. Watch storage/logs/laravel.log and stderr after upgrading; deprecation notices from the bundle surfacing in your app usually mean a version mismatch in a transitive Symfony component.
  • Debugging the bridge: log at the boundary. Wrap the scheduling manager call in a try/catch that logs the UTC input, the unit timezone, and the resulting entity ID. Almost every "appointment at the wrong time" ticket resolves to one of those three values.
  • Extension points: prefer decorating the scheduling manager service over forking the bundle, and override service definitions in your own container config. Forking means re-applying patches on every patch release — and this package ships frequently.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console