---
id: ATS-PFM-TNL-013
scope: CAP-PFM-TNL-013
product_area: platform
module: tenant-lifecycle
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
scenarios:
  - id: ATS-PFM-TNL-013-01
    title: Customer authority cannot request removal
    level: api
    proves:
      - BR-CAP-PFM-TNL-013-01
    preconditions: An eligible disabled workspace is available.
    steps: Request deletion as customer-admin and non-staff identities.
    expected: No deletion request is recorded.
    negative: true
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may
        not ask for a tenant to be deleted
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a caller who is not Rhythm staff
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#writes
        no request for a caller who is not Rhythm staff
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may
      not ask for a tenant to be deleted
  - id: ATS-PFM-TNL-013-02
    title: Confirmation rejects stale or mistaken decisions
    level: api
    proves:
      - BR-CAP-PFM-TNL-013-03
    preconditions: Staff have read a disabled workspace.
    steps: >-
      Submit wrong-name, identifier-as-name, short-reason and stale-version
      variants.
    expected: Each refuses and name errors identify the confirmation input.
    negative: true
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
        a confirmation that does not repeat the tenant's name as 400
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#names
        the confirmation in that refusal, so the person knows what to type
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a confirmation that repeats the tenant id, which is no longer what the
        person types
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a reason too short to tell anybody anything
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that has changed since the screen was drawn
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
        a body with no version as 400
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
      a confirmation that does not repeat the tenant's name as 400
  - id: ATS-PFM-TNL-013-03
    title: Ineligible workspace removal is refused
    level: api
    proves:
      - BR-CAP-PFM-TNL-013-04
    preconditions: 'Fixtures cover enabled, outgoing, locked, parent and protected workspaces.'
    steps: Request deletion for each.
    expected: >-
      The refusal identifies the failed condition and records no new
      protected-workspace request.
    negative: true
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still live, because people must lose access first
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still being implemented, for the same reason
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is being deleted
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is locked
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is somebody else parent
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a well-known tenant the whole development environment is built on
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
        a tenant that is still live as 409
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
      a tenant that is still live, because people must lose access first
  - id: ATS-PFM-TNL-013-04
    title: Database and service prevent duplicate requests
    level: api
    proves:
      - BR-CAP-PFM-TNL-013-05
    preconditions: The workspace has an open request.
    steps: Request another and attempt a direct duplicate insert.
    expected: Both refuse and one open request remains.
    negative: true
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a second request, naming the one that is open
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#leaves
        the tenant with exactly one request after the refusal
      - >-
        services-platform:modules/tenants/tests/integration/services/persistence/tenant-deletion-requests.integration.spec.js#refuses
        a second open request for the same tenant, by the index and not only by
        the service
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
        a second request for the same tenant as 409
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
      a second request, naming the one that is open
  - id: ATS-PFM-TNL-013-05
    title: Cancellation is retained rather than revived
    level: api
    proves:
      - BR-CAP-PFM-TNL-013-06
    preconditions: An earlier request is cancelled.
    steps: Request deletion again.
    expected: A new date and request are recorded beside the cancelled history.
    negative: false
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#allows
        a new request, with a new waiting period, once the first is cancelled
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#leaves
        the cancelled request in the history beside the new one
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#allows
      a new request, with a new waiting period, once the first is cancelled
  - id: ATS-PFM-TNL-013-06
    title: Standard wait honors the Production floor
    level: unit
    proves:
      - BR-CAP-PFM-TNL-013-07
    preconditions: Waiting-period inputs exercise default and configured values.
    steps: Compute eligibility for ordinary workspaces.
    expected: >-
      Default is thirty days; Production rejects thirteen and accepts fourteen
      days.
    negative: false
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#becomes
        eligible thirty days after the request
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#refuses
        a configured period below fourteen days rather than quietly raising it
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#accepts
        exactly fourteen days (the boundary, the negative control)
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#records
        the thirty-day waiting period Andrew set
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#fixes
        the date destruction may begin, thirty days on by the calendar of the
        tenant zone
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#answers
        the thirty-day waiting period
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#becomes
      eligible thirty days after the request
  - id: ATS-PFM-TNL-013-07
    title: No first activation selects the one-day path
    level: unit
    proves:
      - BR-CAP-PFM-TNL-013-08
    preconditions: The workspace has no first-activation record.
    steps: Compute eligibility inside and outside Production.
    expected: Both calculations select one day.
    negative: false
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
        one day, because no association ever used it
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
        one day in Production too, where the fourteen-day floor does not apply
        to it
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that was never provisioned wait one day
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
      one day, because no association ever used it
  - id: ATS-PFM-TNL-013-08
    title: Disposable acceleration is environment-limited
    level: unit
    proves:
      - BR-CAP-PFM-TNL-013-09
    preconditions: >-
      Fixtures include disposable and ordinary workspaces in Production and
      outside it.
    steps: Request reduced waiting periods.
    expected: Only disposable non-Production fixtures use the minute path.
    negative: true
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
        ten minutes outside Production, so an automated test can watch a whole
        deletion
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#is
        refused a period longer than the configured one, so the field can only
        shorten
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#is
        refused for a tenant that is not disposable, rather than ignored
      - >-
        services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#is
        refused in Production even for a disposable tenant
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        the disposable path in Production, where no tenant is disposable
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
      ten minutes outside Production, so an automated test can watch a whole
      deletion
  - id: ATS-PFM-TNL-013-09
    title: Request and watcher are recorded together
    level: api
    proves:
      - BR-CAP-PFM-TNL-013-10
    preconditions: Staff confirm an eligible disabled workspace.
    steps: Submit the deletion decision.
    expected: >-
      The scheduled request, copied identities, notice obligations, pending
      lifecycle and watcher job are recorded.
    negative: false
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
        the tenant name and customer, so the record still reads after the tenant
        is gone
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#records
        who asked and why
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#moves
        the tenant to deletion_pending
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#owes
        the notice destruction waits for
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#submits
        one schedule job with the request, before anything has waited
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#moves
        the tenant to deletion_pending, read back through the tenants API
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
      the tenant name and customer, so the record still reads after the tenant
      is gone
  - id: ATS-PFM-TNL-013-10
    title: Failed-build disposal uses its shorter wait
    level: api
    proves:
      - AS-JNY-PFM-TNL-002-03
    preconditions: The recovery journey includes a never-opened failed build.
    steps: Request its deletion after disabling it.
    expected: The recorded request becomes eligible a day later.
    negative: false
    data_needs: >-
      Use the workspace, caller and collaborator fixtures declared by the bound
      tests.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that was never provisioned wait one day
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#fixes
        that tenant date one day on
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
      a tenant that was never provisioned wait one day
evidence:
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may
    not ask for a tenant to be deleted
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a caller who is not Rhythm staff
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#writes
    no request for a caller who is not Rhythm staff
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
    a confirmation that does not repeat the tenant's name as 400
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#names
    the confirmation in that refusal, so the person knows what to type
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a confirmation that repeats the tenant id, which is no longer what the
    person types
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a reason too short to tell anybody anything
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a tenant that has changed since the screen was drawn
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
    a body with no version as 400
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a tenant that is still live, because people must lose access first
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a tenant that is still being implemented, for the same reason
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a tenant that is being deleted
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a tenant that is locked
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a tenant that is somebody else parent
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a well-known tenant the whole development environment is built on
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
    a tenant that is still live as 409
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    a second request, naming the one that is open
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#leaves
    the tenant with exactly one request after the refusal
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/persistence/tenant-deletion-requests.integration.spec.js#refuses
    a second open request for the same tenant, by the index and not only by the
    service
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses
    a second request for the same tenant as 409
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#allows
    a new request, with a new waiting period, once the first is cancelled
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#leaves
    the cancelled request in the history beside the new one
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#becomes
    eligible thirty days after the request
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#refuses
    a configured period below fourteen days rather than quietly raising it
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#accepts
    exactly fourteen days (the boundary, the negative control)
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#records
    the thirty-day waiting period Andrew set
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#fixes
    the date destruction may begin, thirty days on by the calendar of the tenant
    zone
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#answers
    the thirty-day waiting period
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
    one day, because no association ever used it
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
    one day in Production too, where the fourteen-day floor does not apply to it
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
    a tenant that was never provisioned wait one day
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#waits
    ten minutes outside Production, so an automated test can watch a whole
    deletion
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#is
    refused a period longer than the configured one, so the field can only
    shorten
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#is
    refused for a tenant that is not disposable, rather than ignored
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/deletion/waiting-period.spec.js#is
    refused in Production even for a disposable tenant
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
    the disposable path in Production, where no tenant is disposable
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
    the tenant name and customer, so the record still reads after the tenant is
    gone
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#records
    who asked and why
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#moves
    the tenant to deletion_pending
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#owes
    the notice destruction waits for
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#submits
    one schedule job with the request, before anything has waited
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#moves
    the tenant to deletion_pending, read back through the tenants API
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#fixes
    that tenant date one day on
---

# Schedule deliberate workspace deletion: Acceptance Test Set

## Coverage

| Rule | Proved by |
|---|---|
| `BR-CAP-PFM-TNL-013-01` | `ATS-PFM-TNL-013-01` |
| `BR-CAP-PFM-TNL-013-03` | `ATS-PFM-TNL-013-02` |
| `BR-CAP-PFM-TNL-013-04` | `ATS-PFM-TNL-013-03` |
| `BR-CAP-PFM-TNL-013-05` | `ATS-PFM-TNL-013-04` |
| `BR-CAP-PFM-TNL-013-06` | `ATS-PFM-TNL-013-05` |
| `BR-CAP-PFM-TNL-013-07` | `ATS-PFM-TNL-013-06` |
| `BR-CAP-PFM-TNL-013-08` | `ATS-PFM-TNL-013-07` |
| `BR-CAP-PFM-TNL-013-09` | `ATS-PFM-TNL-013-08` |
| `BR-CAP-PFM-TNL-013-10` | `ATS-PFM-TNL-013-09` |

| `BR-CAP-PFM-TNL-013-11` | no scenario: `FND-PFM-TNL-030` |
