---
id: DOM-ACC-CLS-001
title: Fiscal Period
realises: CON-ACC-CLS-001
product_area: accounting
module: close
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-ACC-CLS-fiscal-close
readable_by: []
lifecycle: STATE-ACC-CLS-001
custom_fields: none
identity: >-
  Books identifies a business unit’s month by its fiscal year and period number
  within the workspace. Month-End Close uses that existing calendar identity and
  does not create or delete periods. Calendar dates order the months across
  years.
attributes:
  - name: fiscal year and number
    kind: reference
    required: true
    computed: false
    notes: >-
      Books supplies the fiscal year and period number; the year determines the
      business unit for close requests.
  - name: business unit
    kind: reference
    required: true
    computed: false
    notes: >-
      The calendar’s owner supplies the unit used for sequencing, calendar
      selection and aging-basis checks.
  - name: 'name, start date and end date'
    kind: text
    required: true
    computed: false
    notes: >-
      Books maintains the label and dates. Closing uses the first date for
      sequence and the last date for readiness, recognition and aging.
  - name: closing state
    kind: enum
    required: true
    computed: false
    notes: >-
      The close service changes open, closing, closed and reopening through its
      period-state writer.
  - name: closed at and closed by
    kind: date
    required: false
    computed: false
    notes: >-
      Only a closed month has a close time and closer. Successful execution
      attributes the close to its requester.
  - name: holding or closing run
    kind: reference
    required: false
    computed: false
    notes: >-
      The period retains the active close’s reference while closing and its
      completed close’s reference while closed or reopening. Returning to open
      clears it; no foreign key enforces this backlink.
  - name: reopen count
    kind: number
    required: true
    computed: false
    notes: >-
      Each completed return from reopening to open adds one to the initial zero
      count.
  - name: current
    kind: computed
    required: true
    computed: true
    notes: >-
      The earliest month that is not closed is current, even across fiscal
      years; an entirely closed calendar has no current month.
  - name: fiscal year standing
    kind: computed
    required: true
    computed: true
    notes: >-
      A database trigger derives whether the year is closed from its periods.
      The calendar response uses the final period for the year’s close details.
relationships:
  - to: DOM-ACC-CLS-003
    cardinality: 'many requests for one month, with no more than one active holder'
    ownership: >-
      Runs reference their period; the period retains a backlink to its holding
      or completed close.
    cross_service: false
  - to: DOM-ACC-CLS-002
    cardinality: many transient evaluations for one month; the period stores none
    ownership: >-
      An evaluation consumes period state without owning or modifying the
      calendar.
    cross_service: false
  - to: DOM-ACC-CLS-004
    cardinality: >-
      one current closing snapshot per closed month, belonging to its closing
      request
    ownership: 'The completed run owns its record, and the period links to that run.'
    cross_service: false
invariants:
  - id: INV-DOM-ACC-CLS-001-01
    statement: >-
      The database accepts only open, closing, closed or reopening as a period
      state.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/db/fiscal-close.table.integration.spec.js#refuses
      a status that is not one of the four
  - id: INV-DOM-ACC-CLS-001-02
    statement: Close time and closer are present if and only if the month is closed.
    enforced_at:
      - database
      - service
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/db/fiscal-close.table.integration.spec.js#refuses
      an open period that names a closer and a time
  - id: INV-DOM-ACC-CLS-001-03
    statement: >-
      The service writer permits six state changes and rejects an update when
      the period has left its expected state.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/persistence/fiscal-periods.integration.spec.js#refuses
      the second of two writers that read the period open, once the first has
      moved it
  - id: INV-DOM-ACC-CLS-001-04
    statement: The service requires a run reference when moving a month into closing.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/persistence/fiscal-periods.integration.spec.js#refuses
      closing a period without the run that holds it
  - id: INV-DOM-ACC-CLS-001-05
    statement: >-
      The database rejects a negative reopen count, and the writer adds one on
      reopening-to-open.
    enforced_at:
      - database
      - service
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/persistence/fiscal-periods.integration.spec.js#moves
      reopening → open when the reopen finishes, counting the reopen
  - id: INV-DOM-ACC-CLS-001-06
    statement: >-
      Close and reopen validate month sequence at submission and locking, but
      their checks leave neighbouring periods unlocked.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-accounting:modules/fiscal-close/services/rules/period-sequence.ts:validatePeriodReopening
  - id: INV-DOM-ACC-CLS-001-07
    statement: >-
      The year’s database-maintained state is closed only when all its periods
      are closed.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/persistence/fiscal-periods.integration.spec.js#becomes
      closed exactly when its twelfth period closes
  - id: INV-DOM-ACC-CLS-001-08
    statement: >-
      Ordinary posting and unposting require open; close-owned recognition
      allows open or closing, and system reversal allows closed or reopening.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-accounting:modules/batches/services/posting-period-guard.ts:POSTING_PERIOD_RULES
  - id: INV-DOM-ACC-CLS-001-09
    statement: >-
      An exclusive close lock and a shared posting lock on the same period force
      the later transaction to wait.
    enforced_at:
      - database
      - service
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/jobs/close-concurrency.integration.spec.js#waits
      on the period row while the FOR SHARE is held
  - id: INV-DOM-ACC-CLS-001-10
    statement: >-
      A period referenced by a close run cannot be deleted while that reference
      remains.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/db/fiscal-close.table.integration.spec.js#refuses
      deleting a period a run names
physical:
  - fiscal_periods
  - fiscal_years
evidence:
  - >-
    services-accounting at f47cb263:
    modules/fiscal-close/services/persistence/fiscal-periods.ts;
    services/rules/transitions.ts, period-sequence.ts;
    services/periods/period-calendar.ts; services/readiness/close-calendar.ts;
    db/migrations/0064_fiscal_close_foundation.sql;
    modules/batches/services/posting-period-guard.ts;
    docs/fiscal-close/PHASE-2-PLAN.md §1, §5.
  - >-
    react-console at baf6dae3: components/accounting/close/period-selector.tsx,
    close-history.tsx; lib/accounting/close/checks.ts.
custom_field_declaration:
  provenance: unknown
  source: FND-ACC-CLS-053
---

# Fiscal Period

## What It Models

A fiscal period gives finance staff a monthly boundary for each business unit’s books. Books owns its calendar identity, dates and label. Month-End Close owns the attached closing state, attribution, run reference and reopen count. Posting modules consult this state before applying work to the month.

## Identity and Attributes

The year and period number identify the month. Its business unit comes from the calendar. Closing and reopening are protected working states that can persist after execution fails. Starting a reopen clears the current close attribution; the completed close’s record preserves the earlier evidence. The calendar computes which month is current rather than storing that designation.

## Relationships

One period can accumulate many close and reopen runs. A partial unique index limits queued or running requests for that period, while its protected state also prevents replacement of a retained failed run. Readiness belongs to an evaluation; the retained record belongs to the successful close.

## Invariants

The invariant rows specify state validity, attribution, sequencing and posting protection. State changes and postings contend on the same period row. That lock protects one month; sequence checks alone do not establish serialization across neighbouring months.

## How It Is Stored and Shared

Books stores the shared period and year rows. Close tasks write the closing fields through the state writer, and the database derives year status. Batch management and Reconciliation read these rows in their posting paths. The close service supplies the console’s calendar response. The design has no custom-field use; registration declarations remain unverified.

## Open Design Questions

Business-unit permission scope, signals for stranded work and cross-month concurrency need resolution or proof. Calendar ownership stays with Books while those questions are addressed.
