TenantAtlas/specs/258-customer-review-productization/research.md
ahmido 966b7af472
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m0s
feat: productize customer review workspace (#310)
## Summary
- productize the customer review workspace and released-review drilldown into a calmer customer-safe governance flow
- make review-pack and evidence-proof access explicit, capability-aware, and auditable in the shared Filament resources
- add focused Pest coverage, browser smoke coverage, and the full Spec 258 artifact package

## Notes
- Filament stays on v5 with Livewire v4 surfaces; no provider registration changes were introduced
- no new global-search scope, destructive action surface, or asset registration was added
- bounded additive audit action IDs were added for workspace open and evidence proof open events

## Validation
- focused Pest feature suites for workspace, review detail, review-pack, and evidence flows
- bounded browser smoke: `tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #310
2026-04-30 18:15:32 +00:00

11 KiB

Research — Customer Review Workspace Productization v1

Date: 2026-04-30
Spec: spec.md

This document resolves the planning decisions for the smallest safe productization follow-up to Spec 249.

Decision 1 — Keep the existing customer review workspace as the canonical landing surface

Decision: Productize the existing ../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php page instead of creating a second customer-review page, new Resource, new panel, or customer portal shell.

Rationale:

  • The repo already has the canonical admin-plane route, current tenant prefilter behavior, and bounded test family for this page.
  • The gap is productization of the current disclosure contract, not missing routing or missing persistence.
  • Reusing the existing page keeps the follow-up aligned with Spec 249 and avoids a second customer-review vocabulary.

Alternatives considered:

  • Add a second customer-facing page or shell.
    • Rejected: duplicates the existing workspace route and widens scope into shell-level IA.
  • Convert the workspace into a new Resource.
    • Rejected: this is still a read-only workspace report, not a new persisted object family.

Decision 2 — Keep the existing released-review detail route as the only secondary context surface

Decision: Continue to use ../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php as the secondary context surface reached from the workspace by the existing customer_workspace query flag.

Rationale:

  • The current detail page already suppresses management actions when launched from the customer-workspace flow.
  • The current route already writes customer-workspace review-open audit metadata.
  • Productization should deepen understanding on the current drilldown path instead of inventing a second detail page.

Alternatives considered:

  • Add a customer-only review detail page.
    • Rejected: would duplicate detail truth and drift from the current policy/audit path.
  • Push all new explanation back onto the workspace page only.
    • Rejected: would keep the first drilldown operator-heavy and incomplete.

Decision 3 — Reuse the existing review summary and artifact-truth seams for findings, accepted-risk, and proof framing

Decision: Reuse the current TenantReview.summary payload, ../../apps/platform/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php, and current review/evidence/pack relationships for customer-safe findings, accepted-risk, and proof framing.

Rationale:

  • The workspace page already derives finding_outcomes and risk_acceptance summary content from the current review payload.
  • ArtifactTruthPresenter already normalizes review and pack freshness/publication semantics.
  • The productization gap is wording, priority, and explicit unavailable-state behavior, not missing domain truth.

Alternatives considered:

  • Introduce a customer-review presenter or new derived persistence layer.
    • Rejected: adds structure without new source-of-truth need.
  • Inline a second page-local taxonomy for findings and proof states.
    • Rejected: creates shared-language drift across workspace, review, and pack surfaces.

Decision 4 — Keep accepted-risk accountability rooted in existing finding-exception truth

Decision: Accepted-risk accountability remains derived from existing FindingException and current decision truth where available; missing accountable-person or accountable-role data must surface as partial/unavailable disclosure rather than a fabricated customer-safe summary.

Rationale:

  • The spec explicitly forbids new persistence and new decision stores.
  • Existing FindingException truth already includes owner, approver, current decision, validity, review due, and evidence reference relationships.
  • Productization requires better accountability framing, but not a parallel accepted-risk model.

Alternatives considered:

  • Add a new customer-accountability projection.
    • Rejected: violates the no-new-persistence goal.
  • Hide accepted-risk accountability when details are incomplete.
    • Rejected: weakens the governance-of-record objective and obscures truthful partiality.

Decision 5 — Keep workspace and tenant isolation on the current capability-first seams

Decision: Reuse ../../apps/platform/app/Services/TenantReviews/TenantReviewRegisterService.php, ../../apps/platform/app/Services/Auth/RoleCapabilityMap.php, and ../../apps/platform/app/Support/Auth/Capabilities.php as the isolation and entitlement seams.

Rationale:

  • The current workspace page already uses canAccessWorkspace(...), authorizedTenants(...), and the current workspace context.
  • The existing test family already proves 404 semantics for out-of-scope tenant targeting on the workspace route.
  • Capability-first reuse avoids new role families or customer-only policy forks.

Alternatives considered:

  • Add new customer-review roles or customer-specific policy branches.
    • Rejected: outside scope and unnecessary for the current admin-plane audience.
  • Resolve optional proof access by hiding the entire review.
    • Rejected: the review should remain readable even when optional proof is unavailable.

Decision 6 — Treat access, absence, unavailable, expired, and redacted conditions as derived disclosure states only

Decision: The follow-up should make access, absence, unavailable, expired, and redacted conditions explicit across workspace, review, evidence, and pack paths, but these remain derived view semantics rather than new persisted statuses.

Rationale:

  • The current workspace page already distinguishes No published review available yet and pack availability from persisted review lifecycle state.
  • The spec explicitly rejects new state families and new persistence.
  • Explicit customer-safe disclosure is the sellability gap; a new persisted taxonomy is not.

Alternatives considered:

  • Add a new customer-availability enum family.
    • Rejected: presentation-only distinction with no new lifecycle consequence.
  • Leave absence and unavailable states implicit.
    • Rejected: that is the current productization gap.

Decision 7 — Reuse the current review-pack and evidence proof routes instead of adding new proof viewers

Decision: Keep ../../apps/platform/app/Http/Controllers/ReviewPackDownloadController.php, ../../apps/platform/app/Filament/Resources/ReviewPackResource/Pages/ViewReviewPack.php, and ../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php as the only proof/detail routes reused by this feature.

Rationale:

  • Current pack download already enforces tenant access, capability checks, readiness, expiry, and audit logging.
  • Current evidence resource routing already exists and is referenced by review and pack truth presenters.
  • The follow-up only needs clearer proof-pointer semantics and explicit unavailable states, not a new viewer family.

Alternatives considered:

  • Add a new customer-proof page or customer-only download endpoint.
    • Rejected: duplicates existing review-pack and evidence seams.
  • Surface raw evidence payloads directly on the workspace page.
    • Rejected: violates customer-safe disclosure hierarchy.

Decision 8 — Reuse the existing audit pipeline and extend it only where access moments are still missing

Decision: Keep all auditing on ../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php and ../../apps/platform/app/Support/Audit/AuditActionId.php. Existing review-open and pack-download actions stay authoritative, and only bounded additive action IDs should be considered if workspace access or proof access moments are not yet covered.

Rationale:

  • The current customer-workspace review handoff already logs TenantReviewOpened.
  • The current signed pack download route already logs ReviewPackDownloaded.
  • The repo does not currently show a matching evidence-proof-open audit on the customer-workspace flow, so that is the bounded gap to evaluate.

Alternatives considered:

  • Create a new customer-review audit table or analytics stream.
    • Rejected: unnecessary persistence and duplication.
  • Leave workspace/proof access unaudited.
    • Rejected: the spec explicitly requires auditability for those consumption moments.

Decision 9 — Keep browser coverage bounded to the existing smoke harness

Decision: Reuse ../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php as the single browser smoke proof and expand only the existing tests/Feature/Reviews/* family for the rest.

Rationale:

  • The repo already has a browser harness for the review-detail-to-workspace handoff and calm disclosure checks.
  • The rest of the productization contract is better proven in focused feature tests for omission rules, access states, and audit metadata.
  • Adding a broader browser family would expand governance cost without clearer business proof.

Alternatives considered:

  • Add multiple new browser tests for each proof path.
    • Rejected: too heavy for a bounded productization follow-up.
  • Rely on browser testing alone.
    • Rejected: feature tests remain the narrower proof for RBAC and disclosure-state coverage.

Decision 10 — Keep the feature asset-light and non-search-expanding

Decision: Do not add a new asset bundle, new panel assets, or any new global-search scope as part of this follow-up.

Rationale:

  • The work is a content/disclosure/productization pass over existing Filament surfaces.
  • Existing review, review-pack, and evidence resources already avoid global-search exposure in this customer-safe path.
  • The user explicitly scoped out heavy asset strategy and new global-search work.

Alternatives considered:

  • Add new visual infrastructure or customer-safe asset loading.
    • Rejected: no product need for this slice.
  • Add a new search entry point for the customer workspace.
    • Rejected: outside the tenant-safe reuse boundary and unnecessary for the current route.