Some checks failed
Main Confidence / confidence (push) Failing after 59s
## Summary - sync platform-dev back into dev with the latest integrated feature and spec work - include the customer review workspace productization flow and its related review, review-pack, evidence, audit, and test updates - carry forward the recent governance and roadmap/spec updates already merged on platform-dev ## Included highlights - customer review workspace productization and customer-safe released-review drilldown - governance decision convergence work - cross-tenant compare and promotion work - external support desk handoff work - product, roadmap, permissions, and spec artifact updates ## Validation context - platform-dev currently contains the already-validated feature work from the merged branch PRs - latest customer review workspace batch included focused Pest suites, one bounded browser smoke, and Pint ## Notes - this is an integration PR from platform-dev into dev - no separate provider-registration or asset-strategy expansion is introduced by the customer review workspace slice Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #311
273 lines
12 KiB
Markdown
273 lines
12 KiB
Markdown
# Data Model — Customer Review Workspace Productization v1
|
|
|
|
**Spec**: [spec.md](spec.md)
|
|
|
|
No new persisted tables, projections, or customer-review entities are required for this follow-up. The feature reuses current tenant-owned review, finding-exception, evidence, review-pack, membership, and audit truth, then tightens the derived workspace and detail presentation contracts.
|
|
|
|
## Persisted Truth Reused
|
|
|
|
### Workspace / Tenant Entitlement Context
|
|
|
|
**Purpose**: Establish the active workspace boundary and the entitled tenant set before any workspace rows, proof links, or review detail routes are composed.
|
|
|
|
**Persisted carriers**:
|
|
- existing workspace membership records
|
|
- existing tenant membership pivot rows and role assignments
|
|
- existing capability registry and role-capability map
|
|
|
|
**Relevant fields / contracts**:
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- tenant membership role
|
|
- capability grants derived from [../../apps/platform/app/Support/Auth/Capabilities.php](../../apps/platform/app/Support/Auth/Capabilities.php)
|
|
- current workspace and remembered tenant context from the existing workspace context/session model
|
|
|
|
**Validation rules**:
|
|
- current actor must be a member of the current workspace or the route resolves as not found
|
|
- workspace rows and explicit tenant filters may only resolve for entitled tenants in that current workspace
|
|
- out-of-scope tenant targets remain `404` and must not leak draft/review existence
|
|
|
|
### TenantReview
|
|
|
|
**Purpose**: Canonical source for the released governance record, current outcome summary, findings summary, accepted-risk summary, proof pointers, and review-detail inspect target.
|
|
|
|
**Persisted carrier**: existing `tenant_reviews` rows via [../../apps/platform/app/Models/TenantReview.php](../../apps/platform/app/Models/TenantReview.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `status`
|
|
- `generated_at`
|
|
- `published_at`
|
|
- `summary`
|
|
- `evidence_snapshot_id`
|
|
- `current_export_review_pack_id`
|
|
- `published_by_user_id`
|
|
- `tenant`
|
|
- `evidenceSnapshot`
|
|
- `currentExportReviewPack`
|
|
- `sections`
|
|
|
|
**Embedded summary payload currently reused**:
|
|
- `finding_count`
|
|
- `finding_outcomes`
|
|
- `risk_acceptance.status_marked_count`
|
|
- `risk_acceptance.valid_governed_count`
|
|
- `risk_acceptance.warning_count`
|
|
- `publish_blockers`
|
|
|
|
**Validation / usage rules**:
|
|
- the workspace default path continues to use the latest published review per entitled tenant only
|
|
- internal-only review states remain off the customer-safe default path
|
|
- the customer-workspace drilldown stays on the existing review detail route under the existing query-context flag
|
|
- productization may refine how summary data is explained, but it must not move that truth into a new stored model
|
|
|
|
### FindingException
|
|
|
|
**Purpose**: Existing accepted-risk and accountability truth used to explain who accepted risk, why it is on record, and whether it needs follow-up.
|
|
|
|
**Persisted carrier**: existing `finding_exceptions` rows via [../../apps/platform/app/Models/FindingException.php](../../apps/platform/app/Models/FindingException.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `finding_id`
|
|
- `status`
|
|
- `current_validity_state`
|
|
- `requested_at`
|
|
- `approved_at`
|
|
- `effective_from`
|
|
- `expires_at`
|
|
- `review_due_at`
|
|
- `owner_user_id`
|
|
- `approved_by_user_id`
|
|
- `current_decision_id`
|
|
- `evidence_summary`
|
|
- `owner`
|
|
- `approver`
|
|
- `currentDecision`
|
|
- `evidenceReferences`
|
|
|
|
**Validation / usage rules**:
|
|
- accountability summaries should derive from existing owner/approver/current-decision truth where present
|
|
- missing accountable-person or accountable-role truth must surface as partial/unavailable disclosure, not fabricated customer-safe copy
|
|
- accepted-risk visibility remains read-only in this slice; no edit, renew, revoke, or approval behavior moves into the customer-safe path
|
|
|
|
### EvidenceSnapshot
|
|
|
|
**Purpose**: Existing proof artifact for evidence freshness, completeness, and optional supporting detail reached only after explicit user intent.
|
|
|
|
**Persisted carrier**: existing `evidence_snapshots` rows via [../../apps/platform/app/Models/EvidenceSnapshot.php](../../apps/platform/app/Models/EvidenceSnapshot.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `status`
|
|
- `completeness_state`
|
|
- `generated_at`
|
|
- `expires_at`
|
|
- `summary`
|
|
- `items`
|
|
|
|
**Validation / usage rules**:
|
|
- evidence proof remains optional, lower-priority, and capability-gated by the current evidence-view path
|
|
- raw payloads and unrestricted diagnostics remain out of the default-visible workspace and review detail path
|
|
- if implementation adds explicit proof-access auditing, it should stay on the shared audit pipeline
|
|
|
|
### ReviewPack
|
|
|
|
**Purpose**: Existing packaged governance artifact for current downloadable review output.
|
|
|
|
**Persisted carrier**: existing `review_packs` rows via [../../apps/platform/app/Models/ReviewPack.php](../../apps/platform/app/Models/ReviewPack.php)
|
|
|
|
**Relevant fields / relationships**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `tenant_review_id`
|
|
- `status`
|
|
- `generated_at`
|
|
- `expires_at`
|
|
- `summary`
|
|
- `file_path`
|
|
- `file_disk`
|
|
- `sha256`
|
|
- `operation_run_id`
|
|
- `tenantReview`
|
|
- `evidenceSnapshot`
|
|
|
|
**Validation / usage rules**:
|
|
- only current ready, unexpired packs remain available in the customer-safe flow
|
|
- review-pack access continues to use the existing signed download route and current capability check
|
|
- the feature must not surface generate/regenerate flows, even when a pack is unavailable
|
|
|
|
### Audit Log Event Family
|
|
|
|
**Purpose**: Existing auditable truth for explicit customer-review consumption moments.
|
|
|
|
**Persisted carrier**: existing `audit_logs` rows via [../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php](../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php)
|
|
|
|
**Relevant current action IDs**:
|
|
- `tenant_review.opened`
|
|
- `review_pack.downloaded`
|
|
|
|
**Potential bounded extensions only if implementation confirms a gap**:
|
|
- workspace access open event for the customer review workspace route
|
|
- evidence proof access open event for proof routes launched from the customer review flow
|
|
|
|
**Validation / usage rules**:
|
|
- auditable access remains on the shared audit path only
|
|
- no new audit store or mirror analytics stream is justified
|
|
- workspace, tenant, source-surface, and artifact identifiers stay in stable audit metadata when a new access moment is added
|
|
|
|
## Derived Read Models
|
|
|
|
### CustomerReviewWorkspaceEntry
|
|
|
|
**Purpose**: Derived row-level presentation contract for one entitled tenant on the existing workspace page.
|
|
|
|
**Persistence**: none; computed at request time
|
|
|
|
**Fields**:
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `tenant_name`
|
|
- `latest_published_review_id` (nullable)
|
|
- `latest_review_published_at` (nullable)
|
|
- `outcome_summary`
|
|
- `findings_summary`
|
|
- `accepted_risk_accountability_summary`
|
|
- `evidence_proof_state`
|
|
- `review_pack_state`
|
|
- `primary_review_url` (nullable)
|
|
- `review_pack_download_url` (nullable)
|
|
- `proof_detail_url` (nullable)
|
|
- `absence_note` (nullable)
|
|
- `unavailable_note` (nullable)
|
|
- `redaction_note` (nullable)
|
|
|
|
**Derivation rules**:
|
|
- exactly one derived entry exists per entitled tenant visible in the current workspace scope
|
|
- if a published review exists, the entry derives its customer-safe summary from that released record only
|
|
- if no published review exists, the entry surfaces an explicit absence note and omits deep links that depend on a released review
|
|
- if optional proof or pack access is blocked by capability or artifact state, the review remains readable while the secondary path becomes explicitly unavailable
|
|
|
|
**Validation rules**:
|
|
- entries may only be built for entitled tenants in the active workspace
|
|
- `review_pack_download_url` is present only when a current pack exists and the actor can consume it
|
|
- `proof_detail_url` is present only when the actor can open the proof route
|
|
- raw payloads, unrestricted diagnostics, provider IDs, and copied support context are never part of the default entry model
|
|
|
|
### CustomerReviewDetailPresentation
|
|
|
|
**Purpose**: Derived section contract for the existing released-review detail page when it is launched from the customer review workspace.
|
|
|
|
**Persistence**: none; computed from the existing review record and current query-context flag
|
|
|
|
**Fields**:
|
|
- `review_id`
|
|
- `tenant_id`
|
|
- `launched_from_customer_workspace` (boolean)
|
|
- `narrative_outcome_summary`
|
|
- `findings_summary`
|
|
- `accepted_risk_accountability_summary`
|
|
- `evidence_summary`
|
|
- `proof_pointer_state`
|
|
- `review_pack_state`
|
|
- `operator_actions_hidden` (boolean)
|
|
- `secondary_diagnostics_collapsed` (boolean)
|
|
|
|
**Derivation rules**:
|
|
- only the existing `customer_workspace` query context activates this productized secondary presentation mode
|
|
- the detail remains readable even when optional pack/evidence capabilities are absent
|
|
- management actions remain suppressed in this context
|
|
|
|
**Validation rules**:
|
|
- this derived model must not create a second review detail route or a second stored summary object
|
|
- secondary proof and support detail remain lower-priority than the narrative governance record
|
|
- duplicate equal-priority summary blocks between workspace and detail should be removed or reduced
|
|
|
|
### CustomerReviewPageState
|
|
|
|
**Purpose**: Request/query/session-backed page state already required for tenant-prefilter, remembered scope, and launch context continuity.
|
|
|
|
**Persistence**: request, URL query, and existing session-backed table state only
|
|
|
|
**Fields**:
|
|
- `tenant` prefilter (nullable)
|
|
- remembered tenant id in workspace context (nullable)
|
|
- `customer_workspace` detail context flag (boolean on the detail route)
|
|
- navigation context metadata when launched from other canonical pages (nullable)
|
|
|
|
**Validation rules**:
|
|
- explicit tenant prefilters must resolve to an entitled tenant or the request fails as not found
|
|
- any state required after Livewire interaction must remain hydrated via public/query/session-backed state
|
|
- no private property may own the control path for disclosure or filter restore
|
|
|
|
## Derived Disclosure States
|
|
|
|
This feature introduces no new persisted lifecycle or enum family. It does require explicit derived disclosure outcomes on existing surfaces:
|
|
|
|
- `available`: the actor can open the review/proof/pack path now
|
|
- `absent`: the underlying released artifact does not exist for this tenant yet
|
|
- `unavailable`: the artifact exists conceptually but is not currently consumable because of capability, readiness, or redaction limits
|
|
- `expired`: the artifact exists and was previously consumable, but time-based or release-lifecycle rules now block access while the surface still needs to explain why
|
|
- `redacted`: the route or surface remains visible, but protected details stay hidden behind existing redaction rules
|
|
- `partial`: the governance record is readable, but accountability/proof detail is incomplete in current source truth
|
|
|
|
These remain derived page semantics only and must not become stored status families.
|
|
|
|
## State Transition Summary
|
|
|
|
No new persisted lifecycle is added. Only derived surface transitions are expected:
|
|
|
|
- workspace open -> entitled tenant rows or truthful empty/absence state
|
|
- remembered tenant or explicit tenant query -> tenant-prefiltered workspace view
|
|
- workspace row with released review -> existing review detail route available
|
|
- workspace row without released review -> explicit absence state and no review-open action
|
|
- released review detail with optional proof/pack capability missing -> review remains readable and secondary path becomes unavailable
|
|
- released review detail with an expired pack/proof artifact -> review remains readable and secondary path becomes explicitly expired
|
|
- explicit workspace/review/proof/pack consumption -> shared audit event when covered by the current audit registry or a bounded additive action ID |