Commit Graph

7 Commits

Author SHA1 Message Date
Nabeel Shahzad
67c244240a
postgres fixes 2026-06-01 18:38:58 -05:00
Nabeel Shahzad
be1b32c67b
refactor(flight): move dpt_time/arr_time to API resource only
Reverses the modern Attribute-method approach: the Flight model no
longer carries dptTime/arrTime accessors. Instead, the canonical
columns are `departure_time` / `arrival_time` (Carbon, datetime:H:i:s
cast); the legacy `dpt_time` / `arr_time` `Hi`-formatted strings are
projected onto the JSON payload only by FlightResource at API response
time.

Why
- Public Attribute methods on a model are queryable surface and shouldn't
  be hidden behind protected visibility just to satisfy Larastan's
  modelAppends rule. Removing the methods (and the matching `$appends`
  entries) sidesteps the rule entirely.
- Keeps the API contract stable (`dpt_time`/`arr_time` still appear in
  responses, `departure_time`/`arrival_time` stay hidden) while
  internal code paths use the structured columns directly.

Model
- Removed `dptTime()` / `arrTime()` Attribute methods from Flight.
- Removed `dpt_time` / `arr_time` from `$appends`.
- Kept `departure_time` / `arrival_time` in `$hidden` (matches the
  contract locked by FlightResourceTimeFieldsTest).
- Dropped the now-unused `FlightTimeParser` import.

API resource
- FlightResource::toArray() now formats `dpt_time` / `arr_time` from
  the Carbon columns at response time. BidFlightResource inherits the
  projection via parent::toArray().

Form / factory
- FlightForm: TimePicker now binds to `departure_time` / `arrival_time`.
- FlightFactory: default state generates `departure_time` /
  `arrival_time` instead of the legacy keys.

Import / export plumbing
- Filament FlightImporter: kept the `dpt_time` / `arr_time` CSV column
  headers for backward compat; `fillRecordUsing` now parses via
  FlightTimeParser and writes through setAttribute('departure_time'/
  'arrival_time') to satisfy PHPStan's strict property typing.
- Filament FlightExporter: same CSV headers, `state()` callbacks
  format `Hi` from the structured columns.
- Service FlightImporter: transforms legacy keys to structured keys
  in import() before firstOrNew mass-assign.
- Service FlightExporter: overrides the array keys after the column
  loop so CSV columns continue to use the legacy header names with
  Carbon-derived values.
- LegacyImporter (old phpvms import): parses source `deptime`/`arrtime`
  into `departure_time`/`arrival_time` directly.

Tests
- Deleted tests/Unit/Models/FlightTimeAccessorTest.php (covered behavior
  that no longer exists on the model).
- FlightResourceTimeFieldsTest now seeds via `departure_time` /
  `arrival_time` factory state; assertions on the projected
  `dpt_time` / `arr_time` keys remain.
- ImporterTest: end-of-import assertions read
  `$flight->departure_time->format('Hi')` instead of `$flight->dpt_time`.

All four gates green; affected suites: 104 tests pass.
2026-05-23 12:05:09 -05:00
Nabeel Shahzad
28f49b97c3
feat(schema-modernization): foundations for RouteForge
Schema, model, Filament, cron, and visibility-semantics foundations
required by the RouteForge change. Four phases delivered as one
coherent change. Verified against four spec files (flight-bundles,
flight-time-storage, subfleet-capability, flight-visibility).

Phase 1.1 \xe2\x80\x94 Flight time columns
- flights.departure_time, flights.arrival_time TIME NULL
- Flight model accessors (Hi-format) + mutators (FlightTimeParser)
- FlightTimeParser supports 9 formats + Z/L/tz suffix stripping
- Migration backfills inline via chunked raw DB::table->update()
- Legacy dpt_time/arr_time VARCHAR columns preserved for one release

Phase 1.2 \xe2\x80\x94 Subfleet capability columns
- subfleets.cruise_speed, max_range_nm, route_types (CSV VARCHAR(64))
- FlightTypesCast splits/sorts/dedupes/logs-on-invalid
- routeforge defaults in config/phpvms.php
- SubfleetForm Operational Capability section

Phase 1.3 \xe2\x80\x94 Flight Bundles
- flight_bundles table + flights.bundle_id NOT NULL FK
- Default bundle seeded inline; existing flights backfilled
- FlightBundle model + factory + BundleObserver (queued recompute)
- FlightBundleResource as sole Flights nav entry (slug=flights,
  icon=OutlinedMap, sort=2)
- Nested FlightResource under FlightBundleResource (slug=flight,
  parentResource, create+edit only, no nav entry)
- FlightsRelationManager with relatedResource for full-page row actions
- FlightForm: bundle selector removed (route-bound), date inputs
  hidden when parent bundle owns dates, XSS-safe placeholder link
- Date columns stored as TIMESTAMP UTC, UI converts to local tz
- Soft-deleting a bundle leaves children non-deleted; visibility
  recompute sets visible=false (no cascade delete)
- Spatie Shield permissions: flight_bundle.* seeded

Phase 1.4 \xe2\x80\x94 Visibility semantics
- flights.active renamed to flights.enabled (admin source of truth)
- flights.visible is cron-managed combined state
- SetActiveFlights cron deleted; SetVisibleFlights cron added
- Two-pass bulk SQL UPDATE scoped by bundle, chunks of 500
- RecomputeBundleVisibility queued job dispatched on bundle save/restore
- Flight::scopeVisible added; scopeActive retained as plain alias
- Pilot-facing read sites use ->visible() (AirportController fix)
- FlightResource JSON + FlightExporter CSV expose both enabled+active
- Four-state status badge (Disabled / Disabled by Bundle / Enabled
  Out of Window / Enabled & In Window) replaces Visible toggle
- 5 visibility indexes added

Verification
- 469 Pest tests passed (2058 assertions)
- phpstan level 5 clean (646 files)
- pint --test clean
- rector --dry-run clean
- All four spec files PASS (28 requirements + 36 scenarios verified
  by kimi-spec-reviewer)

Migration path documented in docs/UPGRADING.md and openspec/changes/
schema-modernization-for-routeforge/.
2026-05-23 12:05:09 -05:00
Arthur Parienté
7490e72523
[8.x] refactor: use native php enum instead of class (#2210)
* wip

* refactor: update enum handling and improve type hints across models

* refactor: deprecate labels and select methods in HasSelect trait for better separation of concerns

* copilot suggestions
2026-05-12 16:29:41 -05:00
Arthur Parienté
992b6d343a
[8.x] feature: upgrade to Laravel 13 (#2204)
* upgrade to laravel 13

* phpstan

* rollback to symfony 7.4

* fix: ModuleService merge

* refactor: new rector rules
2026-05-06 11:27:21 -05:00
Nabeel Shahzad
f53b113e70
chore: enable Model::preventLazyLoading and fix existing N+1 violations
Enable Laravel's preventLazyLoading in dev/test environments to catch
N+1 query regressions during the upcoming repository refactor phases.

Fixes 3 distinct N+1 patterns revealed by the check (7 failing tests):

- Expense::ref_model: eager-load in ExpenseRepository::getAllForType
  and RecurringFinanceService::processExpenses (also in ImporterTest).
- Flight::airline: eager-load in SetActiveFlights::checkFlights where
  the Flight::ident accessor triggers lazy load via Log::info.
- Pirep::aircraft: add 'aircraft' to the eager loads in
  Api/UserController::pireps so the Pirep Resource doesn't lazy load
  aircraft during response serialization.

Part of Phase 0 for the Prettus repository removal.
2026-04-24 17:50:13 -05:00
Arthur Parienté
379a9b38cc
[8.x] feat: improve tests suite (#2166)
* wip

* fix simbrief tests

* more fixes

* run pint

* fix(tests): fake notifications in registration test

* refactor(tests): AI suggestions and performance improvements

* deprecation warning with PHP85

* fix(tests): fake notifications in access with valid invite test

* refactor(build): optimize autoload and remove unnecessary commands

* refactor(tests): update PHPUnit configuration and improve test structure

* refactor: put GeoJson under the right namespace
2026-03-18 16:35:19 -05:00