Automated PR created by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #458
404 lines
37 KiB
Markdown
404 lines
37 KiB
Markdown
# Feature Specification: Spec 387 - Review Publication Resolution Decision UX v1
|
|
|
|
**Feature Branch**: `387-review-publication-resolution-decision-ux-v1`
|
|
**Created**: 2026-06-18
|
|
**Status**: Draft / Ready for implementation planning
|
|
**Input**: User-provided draft candidate "Spec 387 - Review Publication Resolution Decision UX v1" from `/Users/ahmeddarrazi/.codex/attachments/68c5630e-4d21-42fa-bba6-e49ee38ab08a/pasted-text.txt`.
|
|
|
|
## Repo-Truth Adjustment
|
|
|
|
The supplied draft describes a broad UX/productization pass after Spec 386. Current repo truth shows that Spec 386 already implemented much of the decision-first target:
|
|
|
|
- `ResolveReviewPublication` already renders "Review can't be published yet".
|
|
- The page already shows "Publication preparation".
|
|
- Technical proof is already placed under "Technical proof and operation history".
|
|
- Existing Spec 386 Feature and Browser tests assert decision-first copy, "Update required reports", hidden "Report-backed evidence", and confirmation behavior.
|
|
- UI-101 already registers the route as a browser-verified strategic surface with decision-first direction.
|
|
|
|
This Spec 387 package therefore narrows the user draft to residual hardening only:
|
|
|
|
- finish remaining operator-facing terminology mismatches such as "Generate review pack" versus "Prepare export" and "Return to publication" versus "Return to review";
|
|
- tighten modal heading, body, and submit labels so each mutating step names the actual action and states that it will not publish the review;
|
|
- add explicit readonly/capability-denied inspection copy instead of relying only on a disabled action tooltip;
|
|
- verify state-specific copy for waiting, failed, ready-to-continue, ready-for-publication, and no-blocker states;
|
|
- verify technical proof remains collapsed by default and does not compete with the next safe action;
|
|
- update or confirm UI audit coverage and screenshot evidence for this narrower hardening pass.
|
|
|
|
Spec 387 must not duplicate the Spec 386 workflow, data model, persistence, services, actions, route, navigation, or global search behavior.
|
|
|
|
## Candidate Selection Gate
|
|
|
|
- **Selected candidate**: Spec 387 - Review Publication Resolution Decision UX v1.
|
|
- **Source**: Direct user-provided candidate attachment.
|
|
- **Why selected**: The user explicitly supplied a ready Spec 387 draft, and repo inspection found residual copy/state/confirmation/readonly hardening gaps that are smaller than the original draft but still visible to operators.
|
|
- **Roadmap relationship**: Supports the roadmap's current productization and moat priority around customer-safe review consumption and decision-first governance workflows. This is a manual user-provided candidate; it does not reopen the active auto-prep queue, which currently says there is no safe automatic next-best target.
|
|
- **Close alternatives deferred**:
|
|
- Active auto-prep queue candidates remain closed or manual-promotion only in `docs/product/spec-candidates.md`.
|
|
- Management Report PDF staging/runtime validation remains tied to Specs 378-380.
|
|
- Governance artifact lifecycle/retention runtime remains manual-promotion backlog.
|
|
- Governance Inbox resolution intake and generic resolution adapters remain follow-up candidates, not hidden scope.
|
|
- Spec 386 must not be rewritten or converted back into preparation state.
|
|
- **Completed-spec guardrail result**:
|
|
- `specs/386-review-publication-resolution-workflow-v1/` is completed implementation context with route, UI, tests, screenshots, and UI audit registry evidence; it is not modified by this preparation.
|
|
- Related Specs 350, 351, 385, and UI-101 are dependency/context only.
|
|
- No existing `specs/387-*` package or `*387*` branch was found before Spec Kit creation.
|
|
- **Smallest viable implementation slice**: A focused UX/copy hardening pass over the existing Review Publication Resolution page and Review Detail blocked CTA, preserving all Spec 386 runtime behavior.
|
|
- **Gate result**: PASS, with scope reduction. The original draft is too broad relative to current repo truth; this narrowed slice is not already fully covered.
|
|
|
|
## Spec Candidate Check *(mandatory - SPEC-GATE-001)*
|
|
|
|
- **Problem**: The functional Review Publication Resolution page is already decision-first in structure, but a few remaining labels, modal affordances, disabled-action states, and state-specific messages can still expose internal workflow wording or leave the operator inferring the safest next step.
|
|
- **Today's failure**: Operators may still see "Generate review pack", "Return to publication", a generic confirmation submit label, or a disabled action without an explicit page-level permission explanation, even though the product intent is "prepare export", "return to review", and "this will not publish".
|
|
- **User-visible improvement**: The existing page becomes more immediately understandable: one next safe action, action-specific confirmation, no publish ambiguity, clear readonly inspection state, and technical proof available without dominating the first decision.
|
|
- **Smallest enterprise-capable version**: Adjust labels/copy/state handling on the existing page, add or update focused Feature/Filament/Browser tests, and refresh screenshot/UI coverage notes only where the rendered UI changes.
|
|
- **Explicit non-goals**: No new resolution data model, migrations, workflow engine, adapter framework, top-level navigation, global-search resource, auto-publish path, provider/evidence/review-pack service changes, customer-facing resolution flow, or new OperationRun lifecycle behavior.
|
|
- **Permanent complexity imported**: Focused copy mappings, tests, screenshots, and possibly a page-local extraction only if it replaces duplicated mapping. No new durable source of truth, no new enum/status family, no generic presenter/framework, and no new queue or storage behavior.
|
|
- **Why now**: Spec 386 just introduced the workflow, so this is the right time to remove residual implementation-first wording before the surface becomes a repeated operator workflow.
|
|
- **Why not local**: This is local to the existing resolution page and should stay local; the spec exists because the change is user-facing and must carry UI, RBAC, audit, and browser-smoke expectations without reopening Spec 386.
|
|
- **Approval class**: Workflow Compression.
|
|
- **Red flags triggered**: UI polish over a recently completed workflow. Defense: the scope is explicitly narrowed, no new architecture is approved, and implementation must prefer direct local mapping over a new framework.
|
|
- **Score**: Nutzen: 2 | Dringlichkeit: 1 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 2 | Wiederverwendung: 1 | **Gesamt: 10/12**
|
|
- **Decision**: approve as a narrowed residual UX hardening slice.
|
|
|
|
## Problem Statement
|
|
|
|
Spec 386 gave TenantPilot a resumable Review Publication Resolution workflow for blocked Environment Reviews. Current code already presents the main decision-first structure, but residual copy and state handling can still make the surface feel partly implementation-led.
|
|
|
|
The operator should be able to answer within five seconds:
|
|
|
|
1. Can I publish? No, not yet.
|
|
2. Why not? Required preparation inputs are missing, stale, running, or failed.
|
|
3. What should I do now? Take the one next safe action.
|
|
4. Will this publish automatically? No.
|
|
5. Where is proof? In collapsed technical proof and operation history.
|
|
|
|
## Business / Product Value
|
|
|
|
- Reduces operator hesitation during blocked review publication.
|
|
- Preserves the trust boundary that preparation actions never publish automatically.
|
|
- Keeps customer-safe review output separate from internal remediation mechanics.
|
|
- Makes support/proof details available without turning the page into a workflow-engine debug surface.
|
|
|
|
## Primary Users / Operators
|
|
|
|
- MSP or workspace operator preparing an Environment Review for publication.
|
|
- Workspace manager reviewing blocked publication state and next action.
|
|
- Readonly or support user inspecting an existing resolution case without execution rights.
|
|
- Customer-facing review consumers indirectly protected by the non-leakage boundary.
|
|
|
|
## Spec Scope Fields *(mandatory)*
|
|
|
|
- **Scope**: workspace-owned / managed-environment-scoped Review Publication Resolution UI over existing Spec 386 persistence and services.
|
|
- **Primary Routes**:
|
|
- `/admin/workspaces/{workspace}/environments/{environment}/environment-reviews/{record}`
|
|
- `/admin/workspaces/{workspace}/environments/{environment}/environment-reviews/{record}/resolve-publication`
|
|
- Customer Review Workspace only for leakage regression checks; no new customer resolution UI.
|
|
- **Data Ownership**:
|
|
- `ReviewPublicationResolutionCase` and `ReviewPublicationResolutionStep` remain Spec 386 workflow state.
|
|
- `OperationRun` remains execution/proof truth.
|
|
- Evidence Snapshot, Environment Review, Review Pack, and Stored Report remain artifact/review truth.
|
|
- Spec 387 adds no persisted truth.
|
|
- **RBAC**: Existing policies, capabilities, `ReviewPublicationResolutionStepAuthorizer`, `UiEnforcement`, workspace membership, and managed-environment entitlement remain authoritative. Non-member/not-entitled access remains deny-as-not-found; entitled members without execution capability may inspect only when current policies allow it.
|
|
|
|
For canonical-view specs:
|
|
|
|
- **Default filter behavior when tenant-context is active**: N/A. This spec does not add canonical-view filtering or revive retired `/admin/t` routes.
|
|
- **Explicit entitlement checks preventing cross-tenant leakage**: Existing `EnvironmentReviewResource` scoped record resolution and case policy checks remain mandatory; customer workspace leakage tests must continue to prove no internal resolution detail is exposed.
|
|
|
|
## UI Surface Impact *(mandatory - UI-COV-001)*
|
|
|
|
Does this spec add, remove, rename, or materially change any reachable UI surface?
|
|
|
|
- [ ] No UI surface impact
|
|
- [x] Existing page changed
|
|
- [ ] New page/route added
|
|
- [ ] Navigation changed
|
|
- [ ] Filament panel/provider surface changed
|
|
- [ ] New modal/drawer/wizard/action added
|
|
- [ ] New table/form/state added
|
|
- [ ] Customer-facing surface changed
|
|
- [x] Dangerous action changed
|
|
- [x] Status/evidence/review presentation changed
|
|
- [ ] Workspace/environment context presentation changed
|
|
|
|
Clarification: no new modal/action class is approved. Existing Filament action modal copy and existing page action states are changed. Customer-facing scope is negative leakage/regression coverage only unless implementation proves existing copy leaks or overclaims and updates this spec before changing customer-visible UI.
|
|
|
|
## UI/Productization Coverage *(mandatory when UI Surface Impact is not "No UI surface impact")*
|
|
|
|
- **Route/page/surface**:
|
|
- Review Publication Resolution page (`ResolveReviewPublication`)
|
|
- Environment Review detail blocked publication CTA
|
|
- Customer Review Workspace leakage boundary checks only
|
|
- **Current or new page archetype**: existing UI-101 Reviews strategic workflow surface; existing UI-040 Environment Review detail; existing UI-006 Customer Review Workspace for no-leakage boundary only.
|
|
- **Design depth**: Strategic Surface for UI-101; Domain Pattern Surface for CTA copy on UI-040; customer-safe regression only for UI-006.
|
|
- **Repo-truth level**: repo-verified and browser-verified through Spec 386.
|
|
- **Existing pattern reused**: UI-101 page report, Spec 386 page/action implementation, native Filament sections/badges/actions/modals, existing `UiEnforcement`, existing OperationRun link helpers.
|
|
- **New pattern required**: none. Direct local mapping is preferred. A new generic presenter or framework is not approved.
|
|
- **Screenshot required**: yes for changed states where feasible, under `specs/387-review-publication-resolution-decision-ux-v1/artifacts/screenshots/`.
|
|
- **Page audit required**: update UI-101 only if rendered structure/copy materially changes; otherwise record a no-new-route coverage note in the implementation close-out.
|
|
- **Customer-safe review required**: yes, negative leakage check only; no customer-facing resolution UI is planned.
|
|
- **Dangerous-action review required**: yes for existing high-impact/mutating step action and existing cancel action. Step execution keeps `->action(...)`, `->requiresConfirmation()`, server authorization, audit, and notifications from Spec 386.
|
|
- **Coverage files updated or explicitly not needed**:
|
|
- [ ] `docs/ui-ux-enterprise-audit/route-inventory.md`
|
|
- [ ] `docs/ui-ux-enterprise-audit/design-coverage-matrix.md`
|
|
- [x] `docs/ui-ux-enterprise-audit/page-reports/...`
|
|
- [ ] `docs/ui-ux-enterprise-audit/strategic-surfaces.md`
|
|
- [ ] `docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md`
|
|
- [ ] `docs/ui-ux-enterprise-audit/unresolved-pages.md`
|
|
- [ ] `N/A - no reachable UI surface impact`
|
|
- **No-impact rationale when applicable**: N/A.
|
|
|
|
## Cross-Cutting / Shared Pattern Reuse *(mandatory)*
|
|
|
|
- **Cross-cutting feature?**: yes, but limited to one existing workflow surface.
|
|
- **Interaction class(es)**: status messaging, action labels, header actions, confirmation modal copy, OperationRun links, proof disclosure, customer-safe review boundary.
|
|
- **Systems touched**:
|
|
- `ResolveReviewPublication`
|
|
- `ViewEnvironmentReview`
|
|
- `ReviewPublicationResolutionStepAuthorizer`
|
|
- `OperationUxPresenter` / `OperationRunLinks` only as existing link/copy context
|
|
- Customer Review Workspace leakage tests only
|
|
- **Existing pattern(s) to extend**: existing Spec 386 page methods, native Filament Actions, `UiEnforcement`, Filament badges/sections, existing OperationRun UX link helpers.
|
|
- **Shared contract / presenter / builder / renderer to reuse**: existing page-local mapping and shared OperationRun helpers. Do not introduce a cross-domain presenter.
|
|
- **Why the existing shared path is sufficient or insufficient**: The existing path is sufficient for runtime behavior. It is insufficient only in a few labels and state messages.
|
|
- **Allowed deviation and why**: page-local extraction is allowed only if it replaces duplicated mapping and stays review-publication-specific.
|
|
- **Consistency impact**: Button labels, modal headings, modal submit labels, run titles/notifications where touched, tests, and audit-facing copy must keep the same domain vocabulary.
|
|
- **Review focus**: no new workflow engine, no action-start bypass, no local OperationRun UX composition, no internal terms in the default operator layer.
|
|
|
|
## OperationRun UX Impact *(mandatory)*
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: yes, copy and link presentation only. No new OperationRun start/completion semantics.
|
|
- **Shared OperationRun UX contract/layer reused**: existing `OperationUxPresenter`, `OperationRunLinks`, and Spec 386 operation-link behavior.
|
|
- **Delegated start/completion UX behaviors**: queued toast/link/event/dedupe/terminal notification behavior remains unchanged and service-owned.
|
|
- **Local surface-owned behavior that remains**: action label, modal copy, "Open operation" secondary link, and proof disclosure ordering.
|
|
- **Queued DB-notification policy**: unchanged; no new queued DB notification.
|
|
- **Terminal notification path**: unchanged.
|
|
- **Exception required?**: none.
|
|
|
|
## Provider Boundary / Platform Core Check *(mandatory)*
|
|
|
|
- **Shared provider/platform boundary touched?**: no new shared seam. Existing provider/evidence/report/review/export steps remain source-owned.
|
|
- **Boundary classification**: platform-core UI vocabulary over a review workflow; provider-owned details stay behind existing proof/diagnostics.
|
|
- **Seams affected**: visible labels for existing step keys and proof links only.
|
|
- **Neutral platform terms preserved or introduced**: publication preparation, required reports, collect evidence, refresh review, prepare export, return to review, technical proof, operation.
|
|
- **Provider-specific semantics retained and why**: "Entra admin roles" and "Permission posture" may remain as report requirement labels because they are current report names visible to operators.
|
|
- **Why this does not deepen provider coupling accidentally**: no Graph/provider code is changed; provider-specific proof remains diagnostic and existing.
|
|
- **Follow-up path**: Resolution Proof & Currentness Contract, Governance Inbox Resolution Intake, and Restore Readiness Resolution Adapter remain follow-up candidates only.
|
|
|
|
## UI / Surface Guardrail Impact *(mandatory)*
|
|
|
|
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|
|
|---|---|---|---|---|---|---|
|
|
| Review Publication Resolution page copy/state hardening | yes | Native Filament page + existing Blade composition | action labels, status messaging, proof disclosure | page, detail | no | existing route only |
|
|
| Step confirmation modal copy | yes | Filament Action modal | confirmation/dangerous-action safety | action modal | no | existing action only |
|
|
| Environment Review blocked CTA copy | yes | existing Filament resource page/action | review publication action link | detail | no | copy/summary only |
|
|
| Customer Review Workspace leakage regression | no material customer feature change | existing page | customer-safe boundary | page | no | negative test/smoke only |
|
|
|
|
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
|
|
|
|
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|
|
|---|---|---|---|---|---|---|---|
|
|
| Review Publication Resolution page | Primary Decision Surface | Operator decides and executes the next safe preparation step | blocked/ready state, missing requirement summary, one primary action, no-auto-publish copy | operation links, proof artifacts, technical step keys if needed | Primary because it owns the blocked-publication fix flow | review publication preparation | removes internal workflow wording from the first decision |
|
|
| Environment Review detail blocked CTA | Primary Decision entry point | Operator decides whether to resolve blockers before publication | publication blocked explanation and one CTA | review sections/evidence/proof | Primary entry point only, not the whole workflow | review lifecycle | avoids promoting refresh/publish while blocked |
|
|
| Customer Review Workspace | Customer-safe context | Customer/output reader sees no internal resolution mechanics | customer-safe unavailable/preparing state where applicable | none from resolution case | Not a resolution surface | customer review consumption | avoids leakage and action confusion |
|
|
|
|
## Audience-Aware Disclosure *(mandatory when detail/status surfaces change)*
|
|
|
|
| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|
|
|---|---|---|---|---|---|---|---|
|
|
| Review Publication Resolution page | operator-MSP, manager, readonly inspector, support-platform | can/cannot publish, why, next action, no-auto-publish | proof links, operation status, evaluated time, safe reason code | raw provider/report/evidence payloads remain hidden | current step action, or open operation/return to review by state | proof/history collapsed; raw data absent | blocker stated once; checklist and proof add context only |
|
|
| Environment Review detail | operator-MSP, manager, readonly inspector | publication blocked explanation and CTA | evidence/review sections | raw details in existing deeper surfaces | resolve publication blockers while blocked | case internals hidden | detail points to workflow instead of duplicating it |
|
|
| Customer Review Workspace | customer/read-only, operator-MSP | customer-safe review availability only | none from internal resolution | internal resolution proof absent | none introduced | all internal resolution mechanics hidden | no duplicate or leaked blocker mechanics |
|
|
|
|
## UI/UX Surface Classification *(mandatory when operator-facing surfaces change)*
|
|
|
|
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
| Review Publication Resolution | Workflow / Primary Decision | Subject-driven workflow detail | run current preparation step, open operation, or return to review | direct page route from review | N/A | related links and proof disclosure | cancel in More with confirmation | none | existing resolve-publication route | workspace + environment + review | Publication preparation | can publish, blocker, next step, no-auto-publish | no collection/global search by design |
|
|
| Environment Review detail | Detail / Review Context | Existing review detail | resolve blockers or continue existing lifecycle | existing detail page | existing behavior only | secondary evidence/proof links | existing destructive actions remain separated | existing review collection | existing review detail route | workspace + environment | Environment review | publication blocked state | none |
|
|
|
|
## Operator Surface Contract *(mandatory when operator-facing surfaces change)*
|
|
|
|
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|
|
|---|---|---|---|---|---|---|---|---|---|---|
|
|
| Review Publication Resolution page | MSP/workspace operator | Resolve the current publication blocker without publishing | workflow detail | Why is publication blocked and what is the next safe action? | blocker summary, required reports, next safe action, checklist, no-auto-publish note | proof links, operation history, technical step keys | preparation readiness, operation execution state, artifact proof state | TenantPilot artifact/workflow work only; provider work only through existing source-owned actions | update required reports, collect evidence, refresh review, prepare export, return to review | cancel resolution; step execution is high-impact and confirmation-gated |
|
|
| Environment Review detail CTA | MSP/workspace operator | Enter resolution flow when publication is blocked | review detail | Can I publish, and if not where do I resolve blockers? | blocked explanation and resolve CTA | review/evidence details | review lifecycle/readiness | existing review lifecycle only | resolve publication blockers | existing publish/archive actions remain separate |
|
|
|
|
## Proportionality Review *(mandatory when structural complexity is introduced)*
|
|
|
|
- **New source of truth?**: no.
|
|
- **New persisted entity/table/artifact?**: no.
|
|
- **New abstraction?**: no by default. A page-local helper extraction is allowed only if it replaces duplicated mapping and stays bounded to `ResolveReviewPublication`.
|
|
- **New enum/state/reason family?**: no.
|
|
- **New cross-domain UI framework/taxonomy?**: no.
|
|
- **Current operator problem**: residual internal wording and generic modal affordances can slow or confuse the publication preparation decision.
|
|
- **Existing structure is insufficient because**: the existing page has the right architecture and most decision-first copy, but several labels and state messages still need alignment.
|
|
- **Narrowest correct implementation**: update existing local mappings, Blade copy, Filament action modal labels, and tests.
|
|
- **Ownership cost**: focused test/screenshot maintenance only.
|
|
- **Alternative intentionally rejected**: a new `ReviewPublicationResolutionDecisionPresenter` or generic resolution UI framework is rejected unless implementation proves the existing page methods are unsafe to maintain.
|
|
- **Release truth**: current-release UX hardening over an already implemented workflow.
|
|
|
|
### Compatibility posture
|
|
|
|
This feature assumes a pre-production environment. Backward compatibility shims, legacy aliases, and migration compatibility code are out of scope.
|
|
|
|
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
|
|
|
|
- **Test purpose / classification**: Feature + Filament/Livewire + Browser.
|
|
- **Validation lane(s)**: confidence + browser; fast-feedback for focused feature tests.
|
|
- **Why this classification and these lanes are sufficient**: The risk is visible UI and action confirmation behavior on an existing Filament page, plus customer non-leakage. No schema or Graph behavior changes are approved.
|
|
- **New or expanded test families**: add/update focused Spec 387 tests near existing Spec 386 Environment Review and Browser tests.
|
|
- **Fixture / helper cost impact**: reuse existing Spec 386 factories/helpers/fixtures; no new expensive global setup.
|
|
- **Heavy-family visibility / justification**: browser coverage is explicit because the feature is layout/copy/disclosure-sensitive.
|
|
- **Special surface test profile**: workflow-detail surface / standard-native-filament with browser smoke.
|
|
- **Standard-native relief or required special coverage**: ordinary Filament/Livewire action tests plus browser smoke for first-screen order, modal copy, collapsed disclosure, mobile, and customer non-leakage.
|
|
- **Reviewer handoff**: verify no new workflow mechanics, no enabled action for unauthorized execution, no internal terms in default UI, and no publish action on the resolution page.
|
|
- **Budget / baseline / trend impact**: low; one focused browser smoke may add explicit browser lane runtime.
|
|
- **Escalation needed**: document-in-feature if screenshots for some states cannot be produced with current fixtures.
|
|
- **Active feature PR close-out entry**: Smoke Coverage / UX Hardening / No New Workflow Mechanics.
|
|
- **Planned validation commands**:
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/EnvironmentReview/Spec387ReviewPublicationResolutionDecisionUxTest.php`
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/EnvironmentReview/Spec386ReviewPublicationResolutionWorkflowTest.php`
|
|
- `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec387ReviewPublicationResolutionDecisionUxTest.php`
|
|
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
|
|
- `git diff --check`
|
|
|
|
## User Scenarios & Testing *(mandatory)*
|
|
|
|
### User Story 1 - Understand the Blocked Publication Decision (Priority: P1)
|
|
|
|
As an operator opening a blocked review's publication preparation page, I need the first visible area to explain why the review cannot be published, which requirements are missing, and the one next safe action.
|
|
|
|
**Why this priority**: This is the core 5-second decision the page exists to support.
|
|
|
|
**Independent Test**: Open a blocked Environment Review resolution page and verify the first heading/card uses decision-first copy, required report labels, one primary next action, and no prominent internal case/step/proof terms.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** a blocked review with missing required reports, **When** an authorized operator opens the resolution page, **Then** the page shows "Review can't be published yet", the missing required reports, "Update required reports", and visible no-auto-publish copy before technical proof.
|
|
2. **Given** the same page, **When** the operator scans the preparation checklist, **Then** the checklist uses operator labels such as "Update required reports", "Collect evidence", "Refresh review", "Prepare export", and "Return to review".
|
|
|
|
---
|
|
|
|
### User Story 2 - Execute the Next Step With Clear Confirmation (Priority: P1)
|
|
|
|
As an authorized operator, I need the confirmation modal to name the exact preparation action, use a matching confirm button, and clearly state that the action will not publish the review.
|
|
|
|
**Why this priority**: Step actions can queue work or touch provider/evidence/report services; the safety boundary must be explicit.
|
|
|
|
**Independent Test**: Mount the Filament page, open each reachable step action confirmation, and verify title, body, submit label, `->requiresConfirmation()`, and server authorization remain intact.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** the current step is required reports, **When** the operator starts the action, **Then** the modal heading is "Update required reports?", the confirm button is "Update required reports", and the body says the review will not be published.
|
|
2. **Given** the current step is prepare export, **When** the operator starts the action, **Then** the visible copy uses "Prepare export" instead of "Generate review pack" by default.
|
|
|
|
---
|
|
|
|
### User Story 3 - Inspect Without Execution Rights (Priority: P2)
|
|
|
|
As a readonly user who is allowed to inspect an existing case, I need a clear explanation that I can inspect the preparation flow but cannot run the next action.
|
|
|
|
**Why this priority**: Disabled actions without page-level explanation can look broken or like a permission leak.
|
|
|
|
**Independent Test**: Open an existing resolution case as a readonly actor and verify the primary action is disabled or absent, execution remains denied server-side, and an explicit page-level permission message appears.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** a readonly actor with view access but no step execution capability, **When** the actor opens the resolution page, **Then** the page shows "You can inspect this preparation flow, but you do not have permission to run the next action." or equivalent.
|
|
2. **Given** the same actor attempts direct execution, **When** the action handler runs, **Then** the server denies execution and no operation/report/evidence/review-pack job is dispatched.
|
|
|
|
---
|
|
|
|
### User Story 4 - Keep Proof Secondary and Customer Surfaces Clean (Priority: P2)
|
|
|
|
As an operator or customer-safe reviewer, I need proof available for inspection without exposing internal resolution mechanics on the default page or customer workspace.
|
|
|
|
**Why this priority**: The workflow should feel like guided governance, not a visible workflow engine or support console.
|
|
|
|
**Independent Test**: Browser smoke verifies technical proof is collapsed by default on the resolution page and customer workspace does not show resolution case, step, OperationRun, proof, or internal blocker terms.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** an operator opens the resolution page, **When** the page first renders, **Then** "Technical proof and operation history" is collapsed by default and below the decision content.
|
|
2. **Given** a customer-facing review workspace, **When** a review is being prepared internally, **Then** no resolution case, step key, OperationRun link, proof link, or internal blocker reason code is visible.
|
|
|
|
### Edge Cases
|
|
|
|
- The linked operation is running: show operation-in-progress copy and do not expose another start/retry action while the operation is active.
|
|
- The linked operation failed: show safe failed-operation copy, safe reason only, and a retry action only if existing Spec 386 rules allow it.
|
|
- No blockers remain: do not create or emphasize a workflow; return the operator to the normal review publication path.
|
|
- Ready for publication: keep publish on the Environment Review detail page; never publish from the resolution page.
|
|
- Missing fixtures for a browser state: document the unavailable state in the screenshot index rather than widening product code.
|
|
|
|
## Requirements *(mandatory)*
|
|
|
|
### Functional Requirements
|
|
|
|
- **FR-387-001**: The resolution page MUST keep decision-first heading and summary copy as the first default-visible content.
|
|
- **FR-387-002**: The visible checklist and secondary return navigation/action label MUST use operator labels: `Check readiness`, `Update required reports`, `Collect evidence`, `Refresh review`, `Prepare export`, and `Return to review`.
|
|
- **FR-387-003**: Default operator-facing UI MUST NOT prominently show "Resolution Case", "Case Status", "Current step", "Resolution steps", "Report-backed evidence", "OperationRun", "Artifact proof", or raw step keys.
|
|
- **FR-387-004**: Technical proof and operation history MUST remain collapsed by default and below decision/next-action content.
|
|
- **FR-387-005**: Every mutating/high-impact step action MUST continue to execute through `Action::make(...)->action(...)`, keep `->requiresConfirmation()`, and use existing server-side authorization.
|
|
- **FR-387-006**: Step confirmation copy MUST include action-specific heading/body/submit labels and MUST state that the action will not publish the review, except the return-to-review step which must state that publishing remains separate. Each reachable current-step state MUST be covered by a test assertion or a named fixture-unavailable note.
|
|
- **FR-387-007**: The resolution page MUST NOT show a Publish action.
|
|
- **FR-387-008**: The Environment Review detail blocked state MUST keep `Resolve publication blockers` as the primary blocked-publication CTA and MUST NOT promote refresh or publish while blockers remain.
|
|
- **FR-387-009**: Readonly/capability-denied inspectors MUST see an explicit page-level permission message and no enabled executable primary action.
|
|
- **FR-387-010**: Customer-facing surfaces MUST NOT expose resolution case details, step keys, proof links, operation links, or internal blocker reason codes.
|
|
- **FR-387-011**: No new route, navigation item, global-search resource, model, migration, queue family, provider adapter, workflow engine, or auto-publish path may be added.
|
|
- **FR-387-012**: Existing Spec 386 audit, RBAC, source-owned action, failure redaction, and no-auto-publish guarantees MUST remain intact.
|
|
- **FR-387-013**: New or changed visible UI copy MUST use existing localization files/keys where practical; any bounded operator-only localization debt MUST be recorded in the implementation close-out.
|
|
|
|
## UI Action Matrix *(mandatory when Filament is changed)*
|
|
|
|
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|
|
|---|---|---|---|---|---|---|---|---|---|---|
|
|
| Review Publication Resolution page | `ResolveReviewPublication` | one current-step action when executable, `Return to review`/secondary nav, More with `Cancel resolution` | N/A | N/A | N/A | N/A | current-step action confirmation required; cancel confirmation required | N/A | Spec 386 audit remains required for mutating steps/cancel | No publish action; no global search; no top-level nav |
|
|
| Environment Review detail | `ViewEnvironmentReview` / `EnvironmentReviewResource` | existing lifecycle actions plus blocked CTA | existing detail route | N/A | N/A | existing | `Resolve publication blockers` primary while blocked | N/A | existing audit rules remain | Refresh/publish must not compete while blockers remain |
|
|
|
|
### Key Entities *(include if feature involves data)*
|
|
|
|
- **ReviewPublicationResolutionCase**: Existing Spec 386 workflow-state record; no schema or lifecycle expansion in Spec 387.
|
|
- **ReviewPublicationResolutionStep**: Existing Spec 386 step record; no new step keys or statuses in Spec 387.
|
|
- **OperationRun**: Existing execution proof; no new start/completion semantics in Spec 387.
|
|
|
|
## Success Criteria *(mandatory)*
|
|
|
|
### Measurable Outcomes
|
|
|
|
- **SC-387-001**: Browser smoke shows the first visible resolution page content answers blocked state, reason, next action, and no-auto-publish before proof/history.
|
|
- **SC-387-002**: Focused tests prove internal terms are absent from default operator UI and proof remains collapsed by default.
|
|
- **SC-387-003**: Focused tests prove each current-step confirmation keeps `->requiresConfirmation()` and action-specific no-auto-publish copy.
|
|
- **SC-387-004**: Focused tests prove readonly inspectors cannot execute the current step and see explicit permission copy.
|
|
- **SC-387-005**: Customer workspace regression proves no internal resolution mechanics leak.
|
|
- **SC-387-006**: No migrations, model changes, route additions, global-search resource, top-level navigation, or auto-publish behavior appear in the diff.
|
|
|
|
## Out of Scope
|
|
|
|
- New resolution persistence or status families.
|
|
- Generic resolution/workflow adapter frameworks.
|
|
- Provider/evidence/review-pack service behavior changes except label wiring to existing actions.
|
|
- Governance Inbox intake.
|
|
- Restore readiness adapters.
|
|
- Customer-facing resolution workflows.
|
|
- PDF/report runtime validation.
|
|
- Broad UI redesign beyond the existing resolution page and CTA copy.
|
|
|
|
## Assumptions
|
|
|
|
- Spec 386 is the source of runtime workflow truth and remains implemented.
|
|
- The current branch contains the latest Spec 386 code and tests.
|
|
- The user-provided draft is treated as manual promotion and is narrowed against repo truth.
|
|
- Any implementation that discovers a real runtime bug must update this spec/plan before expanding beyond UX hardening.
|
|
|
|
## Open Questions
|
|
|
|
None blocking. Implementation may choose whether small mapping cleanup stays as page-local methods or a page-owned helper; a generic/shared presenter is not approved without a spec update.
|
|
|
|
## Follow-up Spec Candidates
|
|
|
|
- Resolution Proof & Currentness Contract v1.
|
|
- Governance Inbox Resolution Intake v1.
|
|
- Restore Readiness Resolution Adapter v1.
|
|
- Provider/readiness-specific wording improvements if browser/user evidence shows continued friction.
|