---
id: TST-ACC-CLS-026
title: Guarded fiscal-period state changes
kind: integration
product_area: accounting
module: close
revision: 1
status: draft
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
repository: services-accounting
files:
  - >-
    modules/fiscal-close/tests/integration/services/persistence/fiscal-periods.integration.spec.js
implements:
  - ATS-ACC-CLS-001-03
  - ATS-ACC-CLS-003-05
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 3
isolation: >-
  The suite owns test-identifier workspaces and fixture records, removed by its
  teardown.
binding_policy: >-
  Each binding identifies the assertions this suite executes; combined scenarios
  may require other bound suites. Existence is not a recorded execution result.
evidence:
  - >-
    services-accounting:modules/fiscal-close/tests/integration/services/persistence/fiscal-periods.integration.spec.js
  - provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/persistence/fiscal-periods.integration.spec.js
    assertion_titles:
      - 'fiscal close persistence: a fiscal period’s status (integration)'
      - locking a period
      - answers the period with its close columns
      - is refused outside a transaction
      - answers 404 for a period the tenant does not have
      - 'every move the transition table allows, in turn on alpha 2026 period 1'
      - 'moves open → closing, naming the run that holds it'
      - 'moves closing → open when the close fails, letting go of the run'
      - moves open → closing again under a new run
      - >-
        moves closing → closed, recording the closer and now and keeping the run
        that closed it
      - >-
        moves closed → reopening, clearing the closer and keeping the run it
        undoes
      - >-
        moves reopening → closed when the reopen fails, with the closer and the
        time it is given
      - 'moves reopening → open when the reopen finishes, counting the reopen'
      - stores what it answered
      - the moves it refuses
      - 'refuses every move the transition table does not allow, by name'
      - refuses a move to the status the period already has
      - leaves the period as it was after a refused move
      - >-
        refuses a move from a status the period is no longer in, telling the
        writer it changed
      - >-
        refuses the second of two writers that read the period open, once the
        first has moved it
      - refuses closing a period without the run that holds it
      - refuses closing a period without its closer
      - answers 404 for a period the tenant does not have
      - is refused outside a transaction
      - 'answers 404 for another tenant’s period, and leaves it open'
      - the year of the periods it moves (bravo 2026)
      - stays open while any period is not closed
      - stays open while its twelfth period is closing
      - becomes closed exactly when its twelfth period closes
      - becomes open again when one period starts reopening
      - >-
        becomes closed again when the reopen fails and the period is closed
        again
      - is open once the period has reopened
real_dependencies: >-
  Production persistence and mapping run with application-role transactions and
  workspace policies on PostgreSQL. Fixture records and fixed context values
  supply the inputs; the service and database enforcement under assertion remain
  real.
product_intent: proposed
implementation_evidence: observed
---
# Guarded fiscal-period state changes

## Verification Boundary

The suite checks its declared service or persistence boundary against local PostgreSQL. Bindings identify the assertions it contributes to a capability case; they do not establish every assertion in a combined case.

## What This Suite Proves

The writer suite exercises six valid period moves, attribution changes, reopen counting and refused invalid or stale expected states.

## What It Does Not Prove

This register records assertion scope without claiming a passing run or complete coverage of every rule and scenario variant.

## Real Dependencies and Test Doubles

Production persistence and mapping run with application-role transactions and workspace policies on PostgreSQL. Fixture records and fixed context values supply the inputs; the service and database enforcement under assertion remain real.

## Must Not Be Doubled

Keep production queries, writes, mappings, application-role privileges and database constraints real wherever they are the subject of an assertion. Recording financial ports establish invocation behavior; actual recognition and reversal require the suite using the real posting service.
