Skip to content

ci: seed a published inspection form for the driver inspection contract - #652

Merged
roncodes merged 5 commits into
mainfrom
feat/ci-seed-inspection-form
Sep 11, 2026
Merged

ci: seed a published inspection form for the driver inspection contract#652
roncodes merged 5 commits into
mainfrom
feat/ci-seed-inspection-form

Conversation

@roncodes

@roncodes roncodes commented Sep 9, 2026

Copy link
Copy Markdown
Member

What

scripts/ci/mint-api-key.php seeds what the driver inspections contract needs:

  1. A published inspection form for the CI organisation: organisation-wide (subject_uuid null), two flat items (brakes/critical, lights/medium), create_issue_on_failure and create_work_order_on_failure on, published_at set, reasserted on every run. Echoes SEEDED_INSPECTION_FORM_ID=.
  2. Typed field groups on that form. fleetops#319's second cut builds a form from the custom-field system, so a form with only items is empty under it. The seed adds two groups: walk-around checks at grid_size 2, then meter and sign-off at 1. Between them they carry two pass-fail fields with severity and on-fail settings, a free-text note, an odometer number field (unit km, role odometer) and the driver signature. items stays, so a stack on the first cut is unaffected.

Every block is guarded, so a stack without the FleetOps release that carries it runs exactly as before:

  • the form on class_exists(InspectionForm::class);
  • the field groups on defined() for the class constants, which only exist on the second cut, plus class_exists for Category and CustomField.

Why

The inspections API in fleetops#319 lists published forms and files against one, and forms are console-authored: no consumable route can create one. So the Postman contract in postman#60 needs one seeded, or its requests answer 404 or 422.

An earlier revision of this PR also seeded a public inspection link, with its token and PIN, and wired them into the postman-contract action. Those requests have been dropped from postman#60 because the public link routes serve only the console, so that seed and the action changes were reverted. This PR no longer touches the action.

Order

fleetops#319, then this, then postman#60.

Validation

  • The script parses under php -l with a <?php tag prepended; it is a tinker snippet, deliberately tagless.

Not run against a live stack: none carries the fleetops branch yet.

Noticed, not changed

The mint step echoes every MINTED_ and SEEDED_ line before masking any of them, so the minted API key, platform token, storefront key and network key reach the job log unmasked. They belong to the throwaway stack the run creates, so the risk is low, but masking them before the echo would be a small separate change.

The driver inspection endpoints (fleetops#319, postman#60) list published
forms and submit against one, and no consumable route creates a form, so the
contract run seeds one: organisation-wide, two items, both *_on_failure
settings on, reasserted on every run. Guarded on the model existing, so
stacks without the FleetOps release that carries inspections are unaffected.
@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (2612278) to head (008598f).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##                main      #652   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
  Complexity        38        38           
===========================================
  Files            174       174           
  Lines           3163      3163           
===========================================
  Hits            3163      3163           
Flag Coverage Δ
api 100.00% <ø> (ø)
console 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The second cut of inspections stops reading a form's flat JSON `items` and
builds it from the custom-field system instead: groups are Category rows
owned by the form, fields are CustomField rows subjected to it. A form seeded
with only `items` is empty under that cut, so the seed now creates two groups
-- walk-around checks at grid_size 2, then the meter and sign-off at 1 --
carrying two pass-fail fields with severity and on-fail settings, a free-text
note, an odometer number field (unit km, role odometer) and the driver
signature. `items` stays as it was so a stack on the first cut is unaffected.

Guarded the way the form already is. GROUP_FOR and FIELD_FOR only exist on
the FleetOps release carrying the second cut, and an undefined class constant
is a fatal error rather than a catchable one, so both are read through
defined() with the literal values behind them; Category and CustomField are
class_exists-checked so the block skips whole rather than half-running.
Idempotent on the same look-up-then-reassert pattern as every other fixture,
category_uuid included, so a re-run moves a field instead of duplicating it.
The public inspection endpoints (Retrieve a Public Inspection Form,
Upload a Public Inspection Photo, Submit a Public Inspection) take
nothing but a link token, and a link can only be minted from the
console, so the seed mints one.

mint-api-key.php creates an InspectionLink for the seeded "CI Contract
Pre-trip" form, for the seeded driver: multi-use, active, expiring in a
day, with the token rotated each run and used_at cleared. It prints
SEEDED_INSPECTION_LINK_TOKEN and SEEDED_INSPECTION_LINK_FORM_ID, and is
guarded on the inspection_links.token column so an older FleetOps skips
it instead of aborting the rest of the seed.

The postman-contract action reads both lines into step outputs and
passes them to the runner as inspection_link_token and
inspection_link_form_id. The token is masked before the step echoes the
SEEDED_ lines, because a mask only hides later output, and it is
scrubbed from the --verbose artifacts, which masks do not reach.
The seeded link gets a fresh PIN each run, which also clears a wrong-PIN count
or lock from an earlier run. It is masked before the SEEDED_ lines are echoed,
passed to the runner as inspection_link_pin, and scrubbed from the verbose
artifacts. A stack from before PINs seeds none, and its links ask for none.
The public inspection-link routes serve only the console's public page, so
they are not documented in the Postman collection, which covers the
consumable API. With those requests gone, nothing in the contract run uses
the seeded link, token or PIN. The published form and its field groups stay:
the v1 inspection requests need them.
@roncodes
roncodes marked this pull request as ready for review September 11, 2026 10:56
@roncodes
roncodes merged commit a5dea4b into main Sep 11, 2026
10 checks passed
@roncodes
roncodes deleted the feat/ci-seed-inspection-form branch September 11, 2026 10:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant