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

Nightfall Laravel Package

affandra-solusi-teknologi/nightfall

Nightfall is a Laravel package from Affandra Solusi Teknologi that provides a simple, configurable way to add nighttime-aware behavior to your application, with clean integration and minimal setup for scheduled or after-hours features.

View on GitHub
Deep Wiki
Context7

Getting Started

Reconcile the package identity before you install anything. The repository description reads "Laravel + Jetstream + TailwindCSS + Livewire Powergrid" — that is a starter kit boilerplate, not a maintenance scheduler. description.md describes a completely different package: fluent nightly maintenance windows, queue pausing, maintenance-mode toggling. Both cannot be true of the same tree. Before writing a single line of integration code, open composer.json in the repo and check name, type, and autoload.psr-4. If the namespace matches a scaffold, stop — you have the wrong package or a stale README. Everything below assumes the maintenance-scheduler description is the accurate one.

Assuming it is:

composer require affandra-solusi-teknologi/nightfall:1.0.21 --prefer-dist

Pin the exact version. There is no changelog for 1.0.2 → 1.0.21, so a caret range is a bet with no odds published.

Where to look first, in this order:

  1. vendor/affandra-solusi-teknologi/nightfall/src/ — the class tree tells you more than any README. Look for the ServiceProvider, a Facade, a config class, and an Events/ or Console/ directory.
  2. php artisan list | grep -i nightfall — the description promises artisan commands per lifecycle step; enumerate them and read their signatures.
  3. php artisan vendor:publish --provider="...NightfallServiceProvider" — publish the config and read every key before touching it.

First use case: a no-op window in local. Do not start with production cleanup jobs. Declare a single window that touches nothing — logs an event, pauses nothing — and confirm the whole lifecycle fires end to end:

// routes/console.php or a dedicated provider
Nightfall::window('smoke-test')
    ->dailyAt('03:00')
    ->onStart(fn () => logger('nightfall: window start'))
    ->onEnd(fn () => logger('nightfall: window end'));

Run php artisan schedule:list and php artisan schedule:test (Laravel 10+). Once you see start and end logged, you understand the contract. Only then enable maintenance mode or queue pausing.

Implementation Patterns

Keep declarations in a provider, not in Kernel.php. The package's premise is that maintenance logic lives in one predictable place. Honour that: a MaintenanceServiceProvider (or an App\Support\Nightfall config class) that registers all windows, with routes/console.php or Kernel::schedule() containing exactly one line. If a future developer has to grep three files to find out what shuts down at 3am, the package has failed.

Wrap the package behind your own interface. Given the undocumented change surface and single-maintainer risk, the cheapest insurance is a thin boundary:

interface MaintenanceWindows
{
    public function register(string $name, Closure $definition): void;
}

Bind the package's fluent API to it in a service provider. When the package is abandoned or a 2.x ships breaking changes, you swap one adapter instead of auditing every call site. This costs an hour now.

Drive observability through events, not by forking. The description explicitly promises events per lifecycle step. Listen to them in EventServiceProvider and route to your log channel, metrics, and Slack. This is the package's safest extension point: events are far less likely to change across patch releases than internal methods, and it keeps your monitoring code outside the vendor tree.

Event::listen(NightfallWindowStarted::class, fn ($e) => Metrics::increment("nightfall.{$e->window}.start"));

Per-environment overrides belong in the config file, expressed as env reads — not as conditional code. Keep production windows narrow and absolute; make local windows short and frequent so you can exercise them in seconds rather than waiting until 3am. The critical rule: CI must not fire windows. Add an explicit NIGHTFALL_ENABLED=false default and flip it to true only in the environment that legitimately needs it. A test suite that pauses the queue midway through is a test suite that hangs mysteriously.

Test with the framework's fakes, not with sleeps. Carbon::setTestNow(), Event::fake(), and Queue::fake() let you assert lifecycle behaviour without waiting for wall-clock triggers. Assert that your window declares correctly and that your listeners respond — don't assert the package's internals, which you don't control.

Compose with the scheduler, don't replace it. Nightfall sits alongside Kernel::schedule(). Use Laravel's withoutOverlapping() and onOneServer() at the boundary if the package doesn't, particularly if you run multiple app servers. Duplicate maintenance-mode toggles across nodes are survivable; duplicate cache purges are not.

Gotchas and Tips

Maintenance mode is global and blunt. If the package toggles maintenance mode via artisan down, understand the blast radius before enabling it on a customer-facing app. Check whether it supports --secret for ops bypass and --retry for the 503 header. Losing ops access to your own app during a maintenance window is a self-inflicted outage. Verify recovery: what happens if the process is killed between the start event and the end event? Does the app stay down? Test that deliberately by killing a window mid-flight in staging.

Cache clearing silently lifts maintenance mode. Laravel's maintenance mode file handling depends on the driver. If Nightfall's state lives in cache and your deploy runs php artisan optimize:clear, the app comes back up mid-window. Order your deploy steps so cache clears never overlap an active window — or verify the package persists to disk.

config:cache bakes env overrides at deploy time. Any env() call inside the published config becomes frozen once cached. If you planned to flip a per-environment value via a runtime env change, it won't take. Plan the values before the deploy, not during.

Queue pausing is per-connection and the resume burst is real. Pausing Redis does not pause SQS. Confirm which connection(s) the package acts on and whether Horizon workers honour it. When the queue resumes, every job that stacked up during the window releases at once — a thundering herd against your database at 4am. Mitigate with staggered delay() or jittered dispatch on the jobs likely to accumulate.

Overlapping windows and double-fires. Nothing in the description guarantees idempotency. Two windows overlapping, or a scheduler tick firing twice on multi-server setups, can run cleanup jobs concurrently. Prefer named, non-overlapping windows and lean on the framework's onOneServer() at the boundary. If the package offers no deduplication, add a cache lock around your destructive job bodies.

Timezone and DST. Confirm whether windows evaluate in config('app.timezone') or UTC, and what happens on the DST transition night when 02:30 either doesn't exist or occurs twice. If your app runs in a non-UTC timezone, put a test around this. A cleanup job that fires twice on one night per year is a bug you'll find in an incident review, not a test run.

The changelog gap is your debugging problem. Nineteen undocumented patch releases means the first time something behaves unexpectedly, you have no release notes to consult. Before adopting, run git diff 1.0.2..1.0.21 -- src/ and skim it — that diff is the changelog. Save it somewhere in your repo's decision record. If you're already on 1.0.2, do not leap-frog to 1.0.21 in one step on a production branch; step through tags so git bisect remains cheap.

Debugging hooks that actually work: php artisan schedule:list to confirm registration, php artisan schedule:test --filter=nightfall to fire one entry on demand, Event::listen('*', fn ($name) => logger($name)) temporarily to see the full event sequence, and an explicit nightfall log channel during the smoke-test window. Resist the urge to add dump() inside vendor/ — a composer install on a colleague's machine erases it and your debugging session.

Extension points, ranked by safety: config (safest) → events → artisan commands → the fluent API's public methods → service-provider overrides via the container → editing vendor source (never). If you find yourself needing the last one, you need a fork, and a fork needs an owner and a review cadence. Decide that consciously rather than discovering it during an incident.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource