# Done-Test Checks: Web Applications and Platforms

**Check library, version 1.** Rows to lift into the [done-test template](https://mangrove.co.uk/templates/done-test-template.md). Take what applies, delete the rest, and put a number in every threshold.

Pair this with the [front-end library](https://mangrove.co.uk/templates/checks/frontend-checks.md) for anything with a user interface.

## Identity and access

| ID | Check | Evidence | Pass |
|---|---|---|---|
| S1 | Every role in the permission model is demonstrated: what each can see and do, and what each is refused | Live, one session per role | |
| S2 | A user of role [X] cannot reach another tenant's or another user's data by changing an identifier in the URL or request | Live attempt, shown failing | |
| S3 | Session expiry, logout and password or credential reset work end to end | Live | |
| S4 | Administrative actions are logged with actor, action, target and timestamp, and the log is queryable | Live query | |

**On S2.** Object-level authorisation is the most common serious defect in a delivered web application, and it never shows up in a happy-path demo. Test it by trying it.

## Data

| ID | Check | Evidence | Pass |
|---|---|---|---|
| M1 | Migration from [source system] completes with row counts reconciled and [named spot-checks] verified against source | Migration report + live spot-check | |
| M2 | A backup taken today restores to a working system within [N], losing at most [N] of data | Recorded restore drill | |
| M3 | Data export is available in [format] for [named entities], so the client is never locked in | Live export | |
| M4 | Deleting a [record] removes or anonymises it everywhere it propagated, including derived tables, caches and search indexes | Live walkthrough | |

**On M2.** A backup nobody has restored is not a backup. This row is the difference between believing you have one and knowing.

## Operations

| ID | Check | Evidence | Pass |
|---|---|---|---|
| O1 | Deployment runs from CI with no manual steps, and a failed deploy rolls back automatically or within [N] | Deploy shown live | |
| O2 | A named alert fires within [N] minutes of [named failure] and reaches [named recipient] | Alert triggered live | |
| O3 | Logs are centralised, searchable, and retained for [N], with no personal data or secrets in them | Live query | |
| O4 | Configuration and secrets come from a managed store, not from the repository, and rotating one takes effect without a redeploy | Live rotation | |
| O5 | The runbook covers deploy, rollback, restore, and the three most likely failures, and a client engineer can follow it unaided | Walkthrough by that engineer | |

## Resilience

| ID | Check | Evidence | Pass |
|---|---|---|---|
| Y1 | Sustains [N] concurrent users with error rate under [X]% and p95 latency under [N]s | Load-test output | |
| Y2 | When [named dependency] is unavailable, the system degrades in the defined way rather than failing entirely | Dependency failure simulated | |
| Y3 | Idempotency: repeating a submission or webhook does not duplicate the effect | Live replay | |
| Y4 | Scheduled jobs are monitored, and a job that fails to run is alerted on rather than silently skipped | Live | |
