- Removed outdated AddonsTableTest and related assertions.
- Unified service namespaces: migrated support classes to `Support` and service classes to `Services`.
- Added `name` column to the `addons` table and updated related models, migrations, and seeders.
- Replaced `AddonBootService` references with `AddonRuntimeService` throughout tests and codebase.
- Updated Rector configuration and Mago schema, improving import handling and schema validation.
- Simplified addon discovery logic, enhancing boot cache performance.
- Removed unused methods and adjusted runtime behavior for stricter validation and consistency.
- Renamed `addons.base_path` to `addons.paths.base` in configuration files.
- Added `schema_version` handling to `ManifestParser` to improve compatibility.
- Updated documentation with detailed addon implementation and boot process.
- Removed deprecated and unused configuration entries from `composer.json`.
Signed-off-by: Nabeel Shahzad <99736+nabeelio@users.noreply.github.com>
Replace the bespoke HashIdTrait with a Laravel-standard HasNanoIds trait
built on HasUniqueStringIds, mirroring HasUuids/HasUlids. Generation and
validation go through new Str::nanoid()/Str::isNanoid() macros (wrapping
hidehalo/nanoid), with the alphabet/length co-located on App\Contracts\Model.
- Apply HasNanoIds to Pirep, Flight, Acars, File; drop manual $keyType and
the now-redundant #[WithoutIncrementing] attribute
- Deprecate Utils::generateNewId() as a shim over Str::nanoid() and migrate
callers (FlightImporter, Maintenance, RouteForgeService, FileService,
VMSAcars)
- Remove HashIdTrait
- Factories generate nanoid ids so test data matches production
- Fix FlightService::getAccessibleFlightIds() casting nanoid flight ids to
int (0), which broke flight search under rank/typerating restrictions, and
drop matching (int) casts from the affected test assertions
- Renamed `PrimeService` to `AddonRuntimeService` for clarity and alignment with functionality.
- Introduced a new `discoverNewAddons()` method for identifying and handling unregistered addons.
- Updated test cases, services, and commands to use the new service class.
- Improved addon discovery logic and boot cache handling.
- Replaced `registry_id` uniqueness constraint with nullable definition to allow legacy addons.
Signed-off-by: Nabeel Shahzad <99736+nabeelio@users.noreply.github.com>
Closes#2221
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Automated database migrations and seeders during install and update
flows
* Real-time streaming of installation and update logs, plus automatic
redirect after update
* **Improvements**
* Installer wizard auto-advances to the correct step on load
* Better state handling and cached requirement checks to reduce repeated
work
* Safer, idempotent execution to avoid duplicate migration/update runs
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
Only the queue-worker schedule entry uses `withoutOverlapping()`. The
recurring cron tasks (`cron-five-minutes` … `cron-monthly`) do not.
If the scheduler is triggered through more than one path — which is
common on phpVMS (the built-in `/api/cron/{id}` web cron **and** a
system `schedule:run` cron), or a duplicate crontab entry — the same
task can run **concurrently**. It also stacks when a task runs longer
than its interval.
In practice this causes intermittent failures around the nightly run
(~01:00): two `CronNightly` handlers firing at once → race conditions,
double processing, occasional DB deadlocks.
## Fix
Add `->withoutOverlapping($ttl)` to the recurring scheduled tasks
(mirrors what the queue worker already does). A task that is already
running is skipped instead of started a second time. The TTL is a safety
release so a crashed task cannot hold the lock indefinitely.
- No change to **what** the tasks do or **when** they run — purely a
concurrency guard.
- Each `Schedule::call(...)` is already `->name(...)`d, so the mutex has
a stable key.
- TTLs are set comfortably above each task's expected runtime (5/15/30
min, hourly 55, nightly/weekly/monthly 120).
## Notes
- Requires a working cache lock store (already required for the existing
queue-worker entry).
- `update-last-run-time` is intentionally left untouched (it must run
every minute), and `queue-worker-cron` already has the guard.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Configured cron job schedules to prevent overlapping execution across
all scheduled intervals (5-minute, 15-minute, 30-minute, hourly,
nightly, weekly, and monthly).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Test/dev environment switched to PostgreSQL with persistence,
init/health checks; added formatting/linting config and a new dev
tooling dependency; updated editor config; removed legacy base YAML
seeds.
* **New Features**
* Centralized settings seeder and idempotent base-data seeder; seeding
flow refactored and PostgreSQL sequence-reset added.
* **Bug Fixes**
* Migrations made database-driver aware and duplicate-flight detection
tightened.
* **Tests**
* Test bootstrap now seeds settings via the new seeder.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The recurring cron tasks (cron-five-minutes … cron-monthly) had no
overlap protection, unlike the queue worker. When the scheduler is
triggered via more than one path — e.g. the built-in /api/cron web
cron together with a system `schedule:run` cron, or a duplicate
crontab entry — the same task can run concurrently. It also stacks
when a task runs longer than its interval. In practice this causes
intermittent failures around the nightly run (~01:00): two CronNightly
handlers firing at once → race conditions, double processing,
occasional DB deadlocks.
Add `withoutOverlapping($ttl)` so a task already running is skipped
instead of started a second time (mirrors the existing queue-worker
entry). The TTL is a safety release so a crashed task cannot hold the
lock indefinitely. No change to what the tasks do or when they run.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>