---
id: TST-PFM-SEC-172
title: Users database and service checks
kind: integration
product_area: platform
module: security
revision: 2
status: draft
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
repository: services-platform
files:
  - modules/security/tests/integration/services/persistence/users.integration.spec.js
implements: []
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 3
isolation: Use the prepared test database and suite-owned fixture rows; retain shared seed records.
assertion_evidence:
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#security
      persistence: create-user
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#inserts
      a console user stamped with version 1 and the caller as creator, the e-mail trimmed
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#inserts
      a portal user in a tenant of its own customer
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#starts
      every user invited, whatever the input says: only the lifecycle operations move it
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a second console user of the same customer with the same e-mail, whatever its case
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a second member of the same tenant with the same e-mail
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#allows
      the same e-mail in two different walls: they are two unrelated people as far as the model is
      concerned
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a wall the access type does not allow, before the database does and in the database too
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a tenant that belongs to another customer, in the repository and in the database's own trigger
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a customer or tenant that does not exist as a ForeignKeyViolation
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      an id that is not usr_ and a ULID, and one that already exists
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#security
      persistence: get-user
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      a seeded user with its wall and system properties
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#answers
      undefined for an unknown id
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#finds
      a user by e-mail within one wall, case-insensitively, and never across walls
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#security
      persistence: list-users
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#lists
      every seeded user in id order
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#lists
      a customer's own users, both walls, and nobody else's
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#lists
      the members of one tenant only
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#lists
      the active users of a customer, skipping the invited and the suspended
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#security
      persistence: update-user
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#replaces
      the fields at the expected version and bumps it
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#never
      changes the lifecycle: a replacement cannot activate, suspend or re-invite an account
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#moves
      a user between walls only with the wall the access type requires
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a tenant of another customer, leaving the row as it was
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a duplicate e-mail in the wall, a stale version and an unknown id
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#security
      persistence: delete-user
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#deletes
      the user, answering the id; a locked user and an unknown id are refused
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#remembers
      who the person was: the wall, the name and the address they had, with when and by whom
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#remembers
      a portal member in the tenant they belonged to, so the wall is kept with the name
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#writes
      no former-user row for a locked user, because nothing was deleted
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#lets
      the same address be taken again afterwards, as a user with a new id
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#a
      delete the database refuses
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      it with the sentence that tells the administrator what to do instead
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#names
      the refusal user_undeletable, so a screen can act on it without reading the sentence
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#leaves
      the user exactly where they were
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#leaves
      no former-user row behind: the whole transaction went back
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#security
      persistence: the user lifecycle
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#markUserInvited
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#stamps
      the first invitation moment and keeps it through a resend
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a revoked membership, leaving the row untouched: nothing brings one back
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#answers
      undefined for an unknown user
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#activateUser
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#turns
      an invited user active, stamping the activation and verifying the e-mail
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#activates
      only from invited: the second attempt answers undefined, and a suspended one is never
      activated
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#suspendUser
      and reinstateUser
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#suspends
      a membership, naming who did it, and keeps the first moment when it is pressed twice
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reinstates
      only from suspended, clearing the suspension stamps
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      to suspend a revoked membership, leaving the row untouched
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#revokeUser
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#revokes
      from any state and keeps the first moment; no ordinary operation brings the row back
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reinviteRevokedUser
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#invites
      a revoked member back on the same row, clearing the stamps of the membership that ended
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#answers
      undefined for a membership that is not revoked, leaving it exactly as it was
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#answers
      undefined for an unknown user
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#recordUserAuthentication
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#stamps
      the sign-in without touching the status or the version a client holds
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#writes
      at most once in the interval, whatever a tab reload asks
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#stamps
      again once the interval has passed, so the column still answers when the person was last here
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#answers
      nothing and changes nothing for a user that is not there
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#platform.user_lifecycle_events:
      recordLifecycleEvent
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#one
      invitation recorded against a user
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#records
      who acted, on whom, what and with what outcome
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#records
      the request the action happened in, taken from the execution context
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#carries
      no reason for an action that succeeded
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#records
      the moment of the action from the execution clock
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#gives
      the event an evt_ id of the record grammar
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#a
      request id the caller states itself
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#records
      the request id the caller gives rather than the execution context’s
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#every
      action of the closed list
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#states
      exactly the seven actions these cases cover
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the invite action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the resend action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the revoke action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the accept action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the activate action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the disable action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the provision action, which no signed-in administrator performs
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#every
      outcome of the closed list
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#states
      exactly the three outcomes these cases cover
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the succeeded outcome
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the refused outcome with the words the API refused in
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the failed outcome with its operator-safe summary
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#an
      acceptance, which has no signed-in administrator
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      the trail newest first, each with its outcome and reason
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#lets
      the actor be the target themselves
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#the
      trail of a user nothing happened to
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      as empty
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#the
      limit the read applies
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      every event of the user by default
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      only the newest events when the caller states a limit
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#platform.user_lifecycle_events:
      the constraints the database enforces
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      an action outside the closed list by user_lifecycle_events_action_check
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      an outcome outside the closed list by user_lifecycle_events_outcome_check
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a second row with the same id by user_lifecycle_events_pk
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no actor
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no target
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no outcome
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#stamps
      the moment itself when a row states none
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#keeps
      the trail of a user that has been removed, carrying no foreign key to it
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#platform.user_password_events:
      recordPasswordEvent
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#the
      trail of one user, a refused reset and then a successful change
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      the trail newest first, each row with its action, outcome, reason and request
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#records
      who acted on whom for the administrator’s reset
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#lets
      the actor be the target themselves for a self-service change
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#records
      the moment of each action as an instant with its offset
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#the
      request a capability did not state itself
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#records
      the request id of the execution context
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#every
      action of the closed list
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#states
      exactly the two actions these cases cover
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the change_password action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the reset_password action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#every
      outcome of the closed list
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#states
      exactly the three outcomes these cases cover
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the succeeded outcome
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the refused outcome with the words the API refused in
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#accepts
      the failed outcome with its operator-safe summary
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#the
      trail of a user whose password nothing happened to
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      as empty
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#the
      limit the read applies
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      every event of the user by default
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#reads
      no more rows than the limit the caller states
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#platform.user_password_events:
      the constraints the database enforces
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      an action outside the closed list by user_password_events_action_check
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      an outcome outside the closed list by user_password_events_outcome_check
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a second row with the same id by user_password_events_pk
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no actor
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no target
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no action
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#refuses
      a row with no outcome
  - provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js#stamps
      the moment itself when a row states none
dependency_evidence: >-
  The prepared PostgreSQL database supplies the persisted fixtures and constraints exercised here.
  The file declares no substituted collaborators.
evidence:
  - >-
    services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js
  - >-
    Static review at the recorded source revision; executable results remain not-run and conformance
    remains not-verified.
binding_note: >-
  The file has no scenario binding established by this examination. Its executable checks remain
  registered without assigning them broader acceptance coverage.
examiner: codex
examined_at: '2026-10-23'
final_text: OpenAI
dependency_review:
  provenance: test
  source: >-
    services-platform:modules/security/tests/integration/services/persistence/users.integration.spec.js
  explicit_no_doubles: true
  identified_double_boundaries: []
---
# Users database and service checks

## Verification Boundary

The file exercises database or service behavior through the local integration harness. The assertion references identify the source checks for users.

## What This Suite Proves

The file supplies executable engineering checks for the named subject. No complete acceptance scenario is inferred from the file’s existence.

## What It Does Not Prove

This examination does not run the suite. Passing behavior, deployed conformance and the behavior of substituted dependencies require separate execution evidence.

## Real Dependencies and Test Doubles

The prepared PostgreSQL database supplies the persisted fixtures and constraints exercised here. The file declares no substituted collaborators.

## Must Not Be Doubled

Keep the queried database, applicable constraints and transaction boundaries real. Provider substitutes cannot establish delivery, cloud execution or cross-service recovery.
