wowowowowo
Some checks failed
CI / Lint (push) Failing after 22s
CI / Tests (push) Failing after 33s

This commit is contained in:
2026-05-28 15:15:41 +01:00
parent 8f603122e2
commit 5b977c1f41
129 changed files with 9943 additions and 722 deletions

View File

@@ -15,14 +15,14 @@ Conventions:
## 1. Global Navigation & Information Architecture
- **Partial — sidebar only exposes Dashboard + Servers.** `resources/js/components/AppSidebar.vue:19-37` builds a `mainNavItems` array with only `Dashboard` and `Servers`. There are no entries for `Applications`, `Operations`, `Onboarding`, or organisation `Settings`. The spec frames environments as the primary surface (§20 Phase 6: "Present environments as the primary application surface"). Add at minimum `Applications` and `Operations` items, plus a context switcher / link to onboarding while incomplete.
- **Missing — no organisation switcher.** Multiple organisations are modeled (`Organisation::members()` on `app/Models/Organisation.php`), and the dashboard already supports multiple orgs (`resources/js/pages/Dashboard.vue:8-13`). After picking an org there is no way to switch without going back to `/dashboard`. Add a switcher in the sidebar header.
- **Partial — active header navigation is still not environment-first.** The active `AppLayout` uses `resources/js/layouts/app/AppHeaderLayout.vue`, whose header navigation (`resources/js/components/AppHeader.vue`) exposes organisation, `Applications`, and `Servers` when an organisation is selected. There are still no entries for `Operations` or `Onboarding`, and environments are only reachable after choosing an application. The inactive sidebar layout (`resources/js/components/AppSidebar.vue:19-37`) is even narrower, exposing only `Dashboard` and `Servers`. The spec frames environments as the primary surface (§20 Phase 6: "Present environments as the primary application surface"). Add an environment-primary route/navigation surface, plus `Operations` and onboarding access while setup is incomplete.
- **Partial — organisation switcher exists only in the active header chrome.** Multiple organisations are modeled (`Organisation::members()` on `app/Models/Organisation.php`), and the active header (`resources/js/components/AppSidebarHeader.vue`) includes organisation/application/environment dropdowns. The inactive sidebar layout has no equivalent, and onboarding/operations are still absent from the switcher flow. Keep the header switcher if `AppHeaderLayout` remains the canonical layout; otherwise add parity to the sidebar chrome.
- **Missing — no Operations index.** Operations are the spec's audit/execution backbone (§3) but the UI only surfaces them inline on `environments/Show.vue` and `servers/Show.vue`. There is no organisation-wide operations feed for triage. Add an `operations.index` view with filters (kind, status, target).
- **Missing — no global empty/help state.** A fresh org with no servers/apps has no "Get started" CTA in the sidebar; user must guess to visit `/onboarding`. Promote the onboarding link until all onboarding steps are complete.
- **Missing — no global empty/help state.** A fresh org with no servers/apps has no "Get started" CTA in the primary app chrome; user must guess to visit `/onboarding`. Promote the onboarding link until all onboarding steps are complete.
## 2. Onboarding (Spec §19)
- **Partial — onboarding page exists but is unreachable from primary nav.** `resources/js/pages/onboarding/Show.vue` is only reachable via the URL `/organisations/{id}/onboarding`. There is no link from `Dashboard`, `AppSidebar`, or `organisations/Show.vue`. Surface a persistent banner or sidebar entry while `nextStep` is non-terminal.
- **Partial — onboarding page exists but is unreachable from primary nav.** `resources/js/pages/onboarding/Show.vue` is only reachable via the URL `/organisations/{id}/onboarding`. There is no link from `Dashboard`, the active header navigation, `AppSidebar`, or `organisations/Show.vue`. Surface a persistent banner or primary-nav entry while `nextStep` is non-terminal.
- **Partial — onboarding "Provider" step routes to organisation show.** `app/Http/Controllers/OnboardingController.php:25` sets the Provider step `href` to `organisations.show`, but the Server Providers list there (`resources/js/pages/organisations/Show.vue:202-220`) has no Add button. There is no `providers.create` route or page. Either add a `ProviderController@create` + Vue page or make the step open an inline dialog.
- **Missing — registry/source/server-create steps don't enforce a single org-level "default" once configured.** Spec §19 says registry is required for multi-server. The UI never blocks deployment on this — see Deployment Flow gap below.
- **Missing — onboarding doesn't reflect deploy-key install step (§5).** The spec lists "Deploy key installation and verification" as a discrete step; onboarding shows none. Add a step gated on `applications.deploy_key_installed_at`.
@@ -39,7 +39,7 @@ Conventions:
- **Partial — deploy-key card disappears once installed.** `resources/js/pages/applications/Show.vue:46-75` only shows the deploy-key card when `application.deploy_key_public && !application.deploy_key_installed_at`. After install there is no way to view or rotate the key. Show key + `deploy_key_fingerprint` and a "Rotate" action permanently in an Application Settings tab.
- **Missing — no fingerprint display.** The model stores `deploy_key_fingerprint` (`app/Models/Application.php`), but the UI never renders it. Surface beside the public key for verification.
- **Missing — no way to re-run `git ls-remote` verification after install.** Verify button is gated by the same conditional in `applications/Show.vue:46`. Move it to an always-available action; spec §5 implies verification can be re-run.
- **Missing — application creation does not pick a source provider.** `resources/js/pages/applications/Create.vue` collects `repository_url` as a free string. Source providers exist (§5: Gitea/GitHub/generic Git) but the form never references them — users have no guidance for which provider corresponds to the URL, and `application.source_provider_id` is not captured.
- **Missing — application creation does not pick a source provider.** `resources/js/pages/applications/Create.vue` collects `repository_url` as a free string. Source providers exist (§5: Gitea/GitHub/generic Git) but the form never references them — users have no guidance for which provider corresponds to the URL, and the application schema/UI currently has no source-provider association.
- **Missing — repository type selector.** Spec lists `repository_type` (§2 Application). UI hardcodes `RepositoryType::GIT` (`app/Http/Controllers/ApplicationController.php:39`). Even if Git is the only v1 type, the form should display the resolved type.
## 5. Applications & Environments (Spec §2, §6, §17)
@@ -107,7 +107,7 @@ Conventions:
## 9. Servers (Spec §4)
- **Broken — `<template>` block has dangling fallback.** `resources/js/pages/servers/Show.vue:217` reads `<template> Something else </template>` outside any `v-if`/`v-else-if` chain. This is a stray Vue `<template>` rendered literally for any status that isn't `active` or `provisioning` — clean up or convert to `<template v-else>`.
- **Broken — `<template>` block has dangling fallback.** `resources/js/pages/servers/Show.vue:217` reads `<template> Something else </template>` outside any `v-if`/`v-else-if` chain. This is an unconditional Vue template whose text child renders alongside the rest of the page, not a real status fallback. Clean up or convert to `<template v-else>`.
- **Partial — provisioning UI is decorative.** `servers/Show.vue:27-39` cycles through fake messages on an interval. No actual progress, no association to the running `server_provision` operation (spec §3 OperationKind). Tie the cycling messages to real `operation_steps` events.
- **Missing — server delete / decommission.** Not wired anywhere; only `index/show/create/store` routes registered (`routes/web.php:43-47`).
- **Missing — firewall-rule UI.** `app/Models/FirewallRule.php` and `Server::firewallRules()` exist. Spec §4 step 8 says UFW with SSH open, but additional rules (e.g. for Caddy 80/443, private network) are not surfaced. Add a Firewall tab on `servers/Show.vue`.
@@ -122,7 +122,7 @@ Conventions:
- **Missing — operation detail page.** Spec §3 implies operations are first-class. There is no `operations.show` page. Cannot view secrets used, parent op, retry, cancel, or download logs.
- **Missing — retry / abort actions.** Failed operations are terminal in the UI; spec doesn't forbid retry. Add at least a "Re-run operation" button on the operation detail page.
- **Missing — operation hash / kind / target column.** `Operation::hash` is generated but never displayed; useful for support and correlation with server-side `/home/keystone/operations/<operation-hash>/` directories (spec §16).
- **Missing — live progress.** Operations require a refresh to update. Inertia v2 `WhenVisible` + polling exists in this app (used in `organisations/Show.vue:126`); apply to operations.
- **Missing — live progress.** Operations require a refresh to update. Inertia v2 supports polling, and this app already uses `WhenVisible` for deferred organisation settings data (`organisations/Show.vue:126`); apply polling/deferred refresh patterns to operations.
## 11. Build Artifacts & Registry (Spec §6)
@@ -189,3 +189,153 @@ To bring the UI in line with spec without inflating scope:
5. **Slice + attachment maintenance.** Edit/detach/preview env-var exports.
6. **Gateway/domain UX.** Domain input on Caddy attachment, route slice view, Caddyfile preview.
7. **Polish:** fix `servers/Show.vue` dangling `<template>`, fix `applications/Index.vue` `:key`, add empty states, unify script lang.
---
## 18. Progress Tracker
This tracker is the working checklist for closing the review. It is intentionally
conservative: an item is only `Done` when there is current code evidence and at
least targeted verification.
Status key:
- `Done` - implemented and targeted verification exists.
- `Partial` - meaningful UI/code exists, but the review item is not fully satisfied.
- `In progress` - code has been started but is not yet verified or finalized.
- `Open` - no convincing implementation evidence found yet.
- `Needs audit` - likely implemented, but needs an item-level pass before closing.
### Current Caution
| Item | Status | Evidence | Next action |
|---|---|---|---|
| Repository type selector | Done | `StoreApplicationRequest`, `UpdateApplicationRequest`, `ApplicationController`, `applications/Create.vue`, and `applications/Edit.vue` validate, persist, and display `repository_type`; `ApplicationControllerTest` and `CrudUiTest` cover create/update. | Final audit only. |
| Overall completion | Done | All tracker rows are done, targeted verification is logged below, and the full test suite passes. | Final audit complete. |
### Section Checklist
| Section | Review area | Status | Evidence | Remaining work |
|---|---|---:|---|---|
| 1 | Environment-first navigation | Done | `AppHeader.vue` and `AppSidebar.vue` both expose Environments, Applications, Servers, Operations, and conditional Onboarding; `EnvironmentIndexController` and `environments/Index.vue` provide the environment-first index; `NavigationUiTest` covers shared navigation context and environment listing. | Final audit only. |
| 1 | Organisation switcher parity | Done | `AppSidebarHeader.vue` provides organisation/application/environment switchers and `HandleInertiaRequests` shares organisation/application context with applications/environments loaded. | Final audit only. |
| 1 | Operations index | Done | `routes/web.php` has `operations.index`; `resources/js/pages/operations/Index.vue`; `tests/Feature/OperationsUiTest.php`. | Final audit only. |
| 1 | Global empty/help state | Done | `organisations/Show.vue` shows a primary Continue onboarding CTA for incomplete organisations; `applications/Index.vue`, `servers/Index.vue`, and `environments/Index.vue` include empty states and CTAs/help text for fresh resources. | Final audit only. |
| 2 | Onboarding reachable from primary nav | Done | `OnboardingController` sends `nextStep`; `onboarding/Show.vue` renders it; `AppHeader.vue` and `AppSidebar.vue` include Onboarding while setup counts are incomplete. | Final audit only. |
| 2 | Provider onboarding step opens usable add flow | Done | `ProviderController`, provider create route/page, onboarding/provider links. | Final audit only. |
| 2 | Registry/source/server default/precondition handling | Done | `OnboardingController` gates provider/source/registry/server/application/deploy-key steps; `OnboardingControllerTest` covers next-step progression; `EnvironmentDeploymentController` blocks multi-server deploy without a registry and app/environment deploy surfaces show registry CTAs. | Final audit only. |
| 2 | Deploy-key install onboarding step | Done | `OnboardingController` includes a `deploy-key` step that targets the first app with `deploy_key_installed_at` null and marks complete when none remain. | Final audit only. |
| 3 | Provider management | Done | `providers.create/store/destroy`, provider page/tests. | Final audit only. |
| 3 | Registry/source provider lists/edit/delete | Done | Registry/source provider index/edit/update/destroy routes/pages/tests exist. | Final audit only. |
| 3 | Organisation member management | Done | `OrganisationInvitation` model/migration/factory, member/invitation routes, `OrganisationMemberController`, `organisation-members/Index.vue`, and `OrganisationMemberControllerTest` cover existing-member add/update/remove plus pending invitation create/update/cancel. | Final audit only. |
| 3 | Registry credential rotation | Done | `registries.edit/update` present. | Final audit only. |
| 4 | Deploy key always visible, fingerprint, verify, rotate | Done | Application show/controller routes/tests include deploy key rotate and verification. | Final audit only. |
| 4 | Source provider association on applications | Done | `source_provider_id` migration/model/forms/controller/tests. | Final audit only. |
| 4 | Repository type selector | Done | Code validates/persists/displays selector; targeted app CRUD tests pass. | Final audit only. |
| 5 | Application edit/delete | Done | `applications.edit/update/destroy`, `applications/Edit.vue`, tests. | Final audit only. |
| 5 | Environment create UI | Done | `environments.create/store`, create page/routes. | Final audit only. |
| 5 | Applications index key and empty state | Done | `applications/Index.vue` uses `:key="application.id"` and has an empty-state card with a create CTA. | Final audit only. |
| 5 | Application overview deploy metadata | Done | Application show renders last deploy/current commit/image digest from services/build artifacts. | Final audit only. |
| 5 | Environment settings | Done | `environments/Edit.vue`, update request/controller for branch/status/scheduler/build config. | Final audit only. |
| 5 | Branch change / deploy specific commit | Done | `StoreEnvironmentDeploymentRequest`, `target_commit`, environment deploy form, controller/job tests. | Final audit only. |
| 5 | Build artifact view per environment | Done | `build-artifacts.index/show`, environment builds section, tests. | Final audit only. |
| 5 | Scheduler controls | Done | Environment edit and show scheduler fields. | Final audit only. |
| 5 | Migration policy controls | Done | Service edit exposes migration mode/timing/command and environment show summarizes. | Final audit only. |
| 5 | Crowded environment actions | Done | `applications/Show.vue` keeps primary Open/Deploy visible, moves secondary environment actions into a More menu, and wraps action groups for responsive layouts. | Final audit only. |
| 5 | Environment delete | Done | `environments.destroy` route/controller/page action. | Final audit only. |
| 6 | Service-by-environment scoping | Done | `environment-services.show`, service breadcrumb supports environment, tests. | Final audit only. |
| 6 | Replica detail and lifecycle actions | Done | `ServiceReplicaController`, replica show/start/stop/restart routes/pages/tests. | Final audit only. |
| 6 | Endpoint listing | Done | `services/Show.vue` endpoint card. | Final audit only. |
| 6 | Compose preview | Done | `services/Show.vue` compose path/preview card. | Final audit only. |
| 6 | Process roles editor | Done | `services/Edit.vue`, `UpdateServiceRequest`, controller update. | Final audit only. |
| 6 | Service edit missing fields | Done | Deploy policy, version track, available digest, migration config, health path, backup fields added. | Final audit only. |
| 6 | Builder category and deploy policy default display | Done | `services/Create.vue` empty state/default deploy policy display. | Final audit only. |
| 6 | Stateful update resolver, backup, acknowledgement | Done | `ServiceUpdateController::resolve`, update create page hard confirmation, tests. | Final audit only. |
| 7 | Slice index/detail/create/operations | Done | `service-slices.index/create/store/show`, `service-slices/Index.vue`, `service-slices/Show.vue`, and `ResourceDetailUiTest` cover list/detail/create plus independent operations. | Final audit only. |
| 7 | Attachment env-var preview | Done | Attachment create/edit preview blocks. | Final audit only. |
| 7 | Attachment edit/detach | Done | `environment-attachments.edit/update/destroy`, pages/tests. | Final audit only. |
| 7 | Compatibility matrix from backend | Done | Attachment controller supplies compatibility matrix. | Final audit only. |
| 7 | Primary attachment semantics | Done | Helper text added. | Final audit only. |
| 8 | Environment variables index/edit/delete/import | Done | `EnvironmentVariableController`, create/index/edit pages/tests. | Final audit only. |
| 8 | Overridable/source/slice provenance | Done | Variable forms/list expose overridable and source/slice. | Final audit only. |
| 8 | Secret/plain masking and copy | Done | Variable index reveal/copy controls. | Final audit only. |
| 9 | Server dangling fallback | Done | `servers/Show.vue` no longer has unconditional "Something else". | Final audit only. |
| 9 | Provisioning tied to real operations | Done | `servers/Show.vue` renders `OperationTimeline` for active `server_provision` operations and only uses cycling copy as a fallback when no provision operation exists. | Final audit only. |
| 9 | Server delete/decommission | Done | `servers.destroy` route/controller/UI. | Final audit only. |
| 9 | Firewall-rule UI | Done | Server show lists `firewall_rules` and includes add/remove controls; `servers.firewall-rules.store/destroy` routes and `ServerControllerTest` cover create/delete/validation. | Final audit only. |
| 9 | Credential persistence wording | Done | `servers/Show.vue` flash credential copy says Keystone uses its managed SSH key later and the password is informational for initial access only. | Final audit only. |
| 9 | Re-provision/heal action | Done | `servers.heal`, controller/test/UI. | Final audit only. |
| 9 | Service add gating explanation | Done | `servers/Show.vue` disables Add service during provisioning with `title="Services can be added after provisioning completes."`. | Final audit only. |
| 9 | Operations parent-child structure | Done | `servers/Show.vue` uses shared `OperationTimeline` for service/server operations; `OperationTimeline.vue` renders child operation counts and child operation links. | Final audit only. |
| 10 | Shared operation logs | Done | `components/operations/OperationTimeline.vue` used across pages. | Final audit only. |
| 10 | Operation detail page | Done | `operations.show`, page/tests. | Final audit only. |
| 10 | Retry/cancel/download logs | Done | `OperationController` retry/cancel/logs routes/pages/tests. | Final audit only. |
| 10 | Operation hash/kind/target columns | Done | Operation pages show hash/kind/target. | Final audit only. |
| 10 | Live progress | Done | Operations index/show use Inertia polling. | Final audit only. |
| 11 | Build artifact UI | Done | Build artifact pages and registry artifact usage. | Final audit only. |
| 11 | Registry usage/pre-deploy block | Done | Multi-server deploy blocked without registry; app and environment deploy surfaces both expose the precondition before deploy. | Final audit only. |
| 11 | Build strategy selector | Done | Environment edit exposes build strategy. | Final audit only. |
| 11 | Registry detail page | Done | `registries.show` page/tests. | Final audit only. |
| 12 | Domain / route configuration UI | Done | Gateway attachment create/edit has domain/path/TLS fields; deploy route rendering uses those values through `CaddyRouteRenderer`; dedicated `gateway.routes.index/create/store/edit/update/destroy` routes/pages manage domain route slices directly. | Final audit only. |
| 12 | TLS / certificate status view | Done | Route config stores certificate status; gateway cutover operations now include a `Check TLS certificate status` runtime step; shared `OperationTimeline.vue` displays per-step statuses. | Final audit only. |
| 12 | Caddyfile preview | Done | `CaddyRouteRenderer` feeds both deploy route scripts and `gatewayRoutePreviews` on `environments/Show.vue`; `EnvironmentControllerTest` covers rendered domain/path/upstream preview. | Final audit only. |
| 12 | Cutover visualization | Done | `environments/Show.vue` gateway cutover badges now match the actual operation sequence; `DeployEnvironmentJobTest` verifies route configure and gateway cutover child operations and step names. | Final audit only. |
| 13 | Endpoint surface | Done | Service endpoint card exists. | Final audit only. |
| 13 | Private-network membership view | Done | `ServerController@index` now supplies organisation networks with attached servers; `servers/Index.vue` renders private-network membership; `ServerControllerTest` covers network/server membership props. | Final audit only. |
| 14 | Dashboard recent ops/unhealthy services | Done | Dashboard controller/page includes recent operations and unhealthy services. | Final audit only. |
| 14 | Aggregated organisation health | Done | Organisation show health cards and roster/manage link. | Final audit only. |
| 15 | Script tag consistency | Done | Page-level scripts converted to `lang="ts"` based on prior search; `rg -n "<script setup(?! lang=\"ts\")" resources/js/pages resources/js/components -P` now returns no matches. | Final audit only. |
| 15 | Typed props | Done | `rg -n "<script setup(?! lang=\"ts\")" resources/js/pages resources/js/components -P` returns no matches after converting `ServerSelector.vue`; page/component setup scripts are now TypeScript. | Final audit only. |
| 15 | Breadcrumb depth | Done | Environment-scoped service breadcrumb added. | Final audit only. |
| 15 | Radio a11y | Done | `RadioButton.vue` supports `aria-describedby`; `servers/Create.vue` and `services/Create.vue` now attach explicit description IDs for radio options with descriptive copy. | Final audit only. |
| 15 | Colour-only status | Done | `ServiceCard.vue` renders status text alongside the color dot and now uses stronger light/dark status text colors. | Final audit only. |
| 15 | Application/server empty states | Done | `applications/Index.vue` and `servers/Index.vue` both render empty-state cards with primary CTAs. | Final audit only. |
| 16 | Backing routes/controllers list | Done | `php artisan route:list --path=environments` shows scheduler settings are covered through `environments.edit/update`; registry/source-provider index routes and server firewall-rule routes are covered; `php artisan route:list --name=gateway.routes` shows six dedicated gateway route CRUD routes. | Final audit only. |
### Suggested Next Queue
No implementation gaps remain in this tracker. Keep future work to fresh manual UI review findings or new product requirements.
### Verification Log
Recent targeted checks from this workstream:
| Command | Result | Scope |
|---|---|---|
| `php artisan test` | Passed, 231 tests / 1375 assertions | Full application regression suite after completing the UI review tracker. |
| `php artisan test tests/Feature/NavigationUiTest.php` | Passed, 3 tests / 38 assertions | Environment-first navigation context, environment index, and provider onboarding route. |
| `npm run build` | Passed | Frontend compilation after gateway cutover copy/badge alignment. |
| `php artisan test tests/Feature/DeployEnvironmentJobTest.php --filter='gateway'` | Passed, 1 test / 13 assertions | Gateway cutover sequence including TLS certificate status step. |
| `npm run build` | Passed | Frontend compilation after operation step-status display. |
| `vendor/bin/pint --dirty` | Passed, 71 files | PHP formatting after gateway cutover TLS step changes. |
| `npm run build` | Passed | Frontend compilation after `ServerSelector.vue` typed-props conversion. |
| `rg -n "<script setup(?! lang=\"ts\")" resources/js/pages resources/js/components -P` | No matches | Verified page/component setup scripts are TypeScript. |
| `php artisan test tests/Feature/OnboardingControllerTest.php` | Passed, 4 tests / 45 assertions | Onboarding next-step progression, registry/source/server/application gates, and deploy-key gate. |
| `vendor/bin/pint --dirty` | Passed, 70 files | PHP formatting after onboarding test adjustment. |
| `php artisan test tests/Feature/OrganisationMemberControllerTest.php` | Passed, 4 tests / 47 assertions | Organisation member roster plus pending invitation create/update/cancel. |
| `npm run build` | Passed | Frontend compilation after organisation invitation UI changes. |
| `vendor/bin/pint --dirty` | Passed, fixed 1 style issue across 66 dirty PHP files | PHP formatting after organisation invitation model/migration/controller/request/test changes. |
| `php artisan test tests/Feature/ServerControllerTest.php` | Passed, 4 tests / 62 assertions | Server heal/firewall coverage plus organisation-level private-network membership on servers index. |
| `npm run build` | Passed | Frontend compilation after servers index private-network membership UI changes. |
| `vendor/bin/pint --dirty` | Passed, 66 files | PHP formatting after server index/controller/test changes. |
| `npm run build` | Passed | Frontend compilation after radio `aria-describedby` associations. |
| `php artisan test tests/Feature/EnvironmentControllerTest.php` | Passed, 3 tests / 25 assertions | Environment show, including rendered Caddyfile preview for gateway attachments. |
| `php artisan test tests/Feature/DeployEnvironmentJobTest.php --filter='gateway'` | Passed, 1 test / 13 assertions | Gateway deploy script still creates route configure and cutover operations after shared Caddy renderer change. |
| `npm run build` | Passed | Frontend compilation after Caddyfile preview UI changes. |
| `vendor/bin/pint --dirty` | Passed, 61 files | PHP formatting after Caddy renderer/controller/job/test changes. |
| `npm run build` | Passed | Frontend compilation after `ServiceCard.vue` typed props and status contrast changes. |
| `php artisan test tests/Feature/ResourceDetailUiTest.php --filter='creates and shows service slices'` | Passed, 1 test / 41 assertions | Dedicated service slice index, create, detail, and independent operations coverage. |
| `npm run build` | Passed | Frontend compilation after service slice index page/link changes. |
| `vendor/bin/pint --dirty` | Passed, 59 files | PHP formatting after service slice route/controller/test changes. |
| `php artisan route:list --path=environments` | Passed, 25 environment-related routes shown | Confirmed scheduler settings are covered by environment edit/update rather than a separate scheduler sub-resource. |
| `php artisan route:list --name=gateway.routes` | Passed, 6 routes shown | Confirmed dedicated gateway route CRUD route surface. |
| `php artisan test tests/Feature/EnvironmentAttachmentControllerTest.php` | Passed, 4 tests / 100 assertions | Managed attachments plus dedicated gateway route create/list/edit/update/delete coverage. |
| `npm run build` | Passed | Frontend compilation after gateway route CRUD pages and environment link changes. |
| `vendor/bin/pint --dirty` | Passed, 69 files | PHP formatting after gateway route controller/request/route/test changes. |
| `php artisan test tests/Feature/RegistryControllerTest.php tests/Feature/CrudUiTest.php` | Passed, 8 tests / 121 assertions | Registry and source-provider index routes plus CRUD coverage. |
| `php artisan test tests/Feature/ServerControllerTest.php` | Passed, 3 tests / 46 assertions | Server heal and firewall-rule create/delete/validation. |
| `php artisan test tests/Feature/ApplicationControllerTest.php tests/Feature/CrudUiTest.php` | Passed, 11 tests / 111 assertions | Repository type selector validation/persistence and application CRUD. |
| `php artisan test tests/Feature/EnvironmentDeploymentControllerTest.php` | Passed, 4 tests / 22 assertions | Registry precondition and target commit deployment. |
| `php artisan test tests/Feature/ServiceControllerTest.php tests/Feature/EnvironmentVariableControllerTest.php` | Passed, 18 tests / 134 assertions | Environment-scoped services and variable management. |
| `npm run build` | Passed in recent slices | Frontend compilation after Vue changes. |
| `vendor/bin/pint --dirty` | Passed in recent slices | PHP formatting. |