Skip to main content

Spike: Introducing Case-Level Visibility

Summary

This spike proposes a safe, incremental way to introduce a new, simplified access model.

The goal is to introduce case‑level visibility and user‑level permissions in a way that:

  • avoids risky client migrations
  • allows us to test the new model in production ourselves
  • Preserves existing behaviour for all current customers

The approach relies on:

  • an organisation‑level feature flag
  • a strict v2 / v3 API boundary
  • incremental rollout of new permissions starting from current defaults

Core constraints and principles

Design principles

  • No after‑the‑fact customer migrations
  • No behaviour changes for existing organisations
  • Workspace scoping remains the foundation of all data access during development and testing
  • Default new data structures to match current production

Current production behaviour

Today, effective visibility behaves as:

  • Access is always scoped to the workspace
  • Within a workspace, all users can see all cases
  • Assets inherit visibility from the workspace

This baseline becomes the default mode for the new system.


Target simplified permission model (v3)

Roles

  • Admin
  • User

Admins:

  • Can view and edit all cases within the current workspace

Users:

  • Visibility is controlled at the case level

Case‑level visibility modes

Each case has an explicit visibility setting:

  • Workspace‑wide
    All workspace users can view/edit
    (default; matches current production behaviour)

  • Named users
    Only explicitly selected users can view/edit

Assets always inherit visibility from their case.


Testing case visibility in parallel

Organisation‑level flag

Introduce a new "feature flag" field on the organisation model, for example:

case_visibility_enabled bool (default: False)

API

Current state (v1/v2 relevant paths)

Current FE API calls

  1. Asset listing Page
  2. Asset Detail
  3. Custom Tracker Asset Form
  4. Self-Hosted Asset Form
  5. Generated Asset Form
  6. Tangible Asset Form
  7. Asset Seizure Selector
  8. Activity Component (transactions)
  9. Seizure Asset Wizard
  10. Wrapped Assets Hook
  11. Wrapped Operation Assets Hook

Assets are accessible in two ways:

Global assets

  • /assets
  • /assets/{id}
  • /assets/digital
  • /assets/physical
  • /assets/{id}/transactions
  • /assets/{id}/refresh
  • /assets/{id}/archive
  • /assets/{id}/restore

Operation-scoped assets

  • /operations/{id}/assets/digital
  • /operations/{id}/assets/physical

Generated client hooks in use on the frontend

  • useGetAssetsDigital
  • useGetAssetsPhysical
  • useGetAssetsId
  • usePostAssets
  • usePutAssetsId
  • useGetAssetsIdTransactions
  • usePostAssetsIdRefresh
  • useGetOperationsIdAssetsDigital
  • useGetOperationsIdAssetsPhysical

v2 APIs (legacy)

  • Preserve all existing semantics
  • No behavioural changes, e2e tests are not changed
  • Continue to serve all organisations

v3 API

Rules

  • Designed specifically for case‑level visibility
  • Use consistent scoping and PATCH semantics
  • Assets are always scoped to an operation
  • Adds a joint /assets endpoint which returns all asset types
  • Retains the /digital and /physical endpoints for backwards compatibility
  • Workspace context is implicit via session

Proposed v3 hook mapping

Capabilityv1 / v2v3
List specific asset typesGET /operations/{id}/assets/digital
GET /operations/{id}/assets/physical
GET /v3/operations/{operationId}/assets
List all asset typesGET /assetsGET /v3/operations/{operationId}/assets
Create assetPOST /assetsPOST /v3/operations/{operationId}/assets
Update assetPUT /assets/{id}PATCH /v3/operations/{operationId}/assets/{assetId}
Asset detailGET /assets/{id}GET /v3/operations/{operationId}/assets/{assetId}
TransactionsGET /assets/{id}/transactionsGET /v3/operations/{operationId}/assets/{assetId}/transactions
RefreshPOST /assets/{id}/refreshPOST /v3/operations/{operationId}/assets/{assetId}/refresh
Archive / restorePOST /assets/{id}/archive
/restore
POST /v3/operations/{operationId}/assets/{assetId}/archive
/restore

v3 Endpoints

GET    /v3/operations/{operationId}/assets (physical & digital)
POST /v3/operations/{operationId}/assets
GET /v3/operations/{operationId}/assets/{assetId}
PATCH /v3/operations/{operationId}/assets/{assetId}

GET /v3/operations/{operationId}/assets/digital
GET /v3/operations/{operationId}/assets/physical

GET /v3/operations/{operationId}/assets/{assetId}/transactions
POST /v3/operations/{operationId}/assets/{assetId}/refresh
POST /v3/operations/{operationId}/assets/{assetId}/archive
POST /v3/operations/{operationId}/assets/{assetId}/restore

Rollout

Phase 1

  • Add organisation‑level feature flag
  • Add organisation-level case visibility default
  • Add case permission fields, defaulted to organisation default
  • Disable the existing asset transfer mechanism
  • Implement v3 read paths
  • Enable the flag for internal organisations only

Phase 2

  • Introduce v3 write endpoints for case visibility
  • Allow patching cases to "named users" / "workspaces"
  • Expand v3 asset creation/update flows

Phase 3

  • Test real production usage internally
  • Identify edge cases and performance impacts

Phase 4

  • Toggle the feature for existing orgs, as needed.

Testing strategy

Aims

  • v2 e2e tests remain unchanged
  • v3 has its own dedicated e2e test suite

Key flows to test

  • Workspace‑wide default behaves identically to legacy
  • User loses access immediately when removed from a case
  • Assets are inaccessible once case visibility is revoked
  • Admin always has full access within the workspace
  • No cross‑operation or cross‑workspace leakage