V1 Web PWA · Walk result

Journey result: Tenant bulk operations and exports

A dated evidence record for V1 Web PWA: observed behavior, current source reconciliation, automation evidence, and explicit proof limits.

verdict: partial· 2026-06-25
2sections2 minread

On this page
  • Walked: 2026-06-25; updated 2026-07-02 by Codex against local real-BFF dev infrastructure
  • Verdict: partial pass - the local BFF API spine now proves platform-only scope gates, users bulk-operation validate/dry-run/stage/commit with real row-level commit outcomes, entitlements bulk-operation commit into the customer profile entitlement projection, rosters bulk-operation commit into the OneRoster roster projection, persona_assignments bulk-operation commit into the active persona projection, unsupported content commit failure without false committedAt, validation-error blocking, per-operator isolation, bulk-export manifest creation/read/verification, export matrix failure behavior, and audit-search read-back. The operator /operator/tenant browser panel now covers content export creation, manifest/file hash inspection, verification, release approval, released-file download, response hash/residency headers, and release/download audit read-back through the live BFF. CSV upload parsing, upload preview/row diff UI, multi-actor approval separation, and real content/taxonomy commit executors remain open.
  • Primary specs: apps/oshun/web/e2e/tenant-bulk-operations-export-bff.spec.ts, apps/oshun/web/e2e/tenant-bulk-operations-export-ui.spec.ts

Observations#

  • Bulk-operation routes reject missing auth and workspace-scoped tenant admins, then accept platform operators.
  • Clean users operations advance through the enforced state machine one stable state at a time and cannot be committed twice.
  • Clean entitlements operations use the seeded account id, commit through the real customerAuthStateStore.updatePlan path, and are verified by reading /v1/profile before and after the commit (free -> premium).
  • Clean rosters operations commit through oneRosterApplyStore.apply and are verified by reading /v1/admin/lms/oneroster for the deterministic bulk-row commit id and tenant roster totals.
  • Clean persona_assignments operations commit through activePersonaStore.set and are verified by reading /v1/personas/active as the assigned subject for the committed persona and surface.
  • Valid content operations can validate, dry-run, and stage, but the commit boundary proves the missing executor fails loud: terminal failed, committedAt: null, empty commitOutcomes, explicit no commit executor is wired failure reason, and failed audit-search event.
  • The dry-run plan classifies :create, :update, and :skip target refs, and commit records one outcome per row.
  • Invalid rows validate into visible issues but cannot advance to dry-run.
  • Bulk exports return secret-free summaries first, inline file content only on detail read, and an integrity verifier that recomputes the manifest/files.
  • Unsupported export matrix pairs and mismatched record kinds fail closed.
  • The /operator/tenant bulk-export panel now drives the same real BFF from the browser: create content JSON export, inspect manifest/file hashes, verify, approve release with a rationale, download the released file, and read back structured executed/release-approved/file-downloaded audit events.

Out of scope#

  • Browser UI for bulk CSV upload, preview, row diff, and commit confirmation.
  • Real residency metadata lookup for each exported row.
  • Multi-actor export approval separation and retention-expiry enforcement beyond the current single-operator release handoff.
  • Real commit executors for content and taxonomy rows beyond the now-covered loud-failure contract.