SonaCORE

Referência / Quadra Command API

Accounting Periods

2 operações em Quadra Command API 0.2.0.

POST/v1/accounting-periods/{scope_id}/{yyyy_mm}/close

Close an accounting period

Close one account's accounting period, writing an immutable close record that **re-derives** the window rather than snapshotting it (RFC-028 §4).

⭐ **No `Idempotency-Key` header, deliberately.** RFC-028 D7 makes a close intrinsically idempotent — a repeat over an already-CLOSED period returns the stored record unchanged with `appended: false`, and is a no-op rather than an error. The resource state *is* the token. An `Idempotency-Key` would be a second and *weaker* mechanism (those records carry a TTL), and with an empty body the only 409 it could ever raise would be a complaint about the header.

⛔ The record is **not signed**. A checkpoint seals a journal sequence range and a UTxO set hash and commits nothing about the entry model, so no signature covers `net_by_node` (§4.3). A close is evidence because it is re-derivable.

Raises: 400: INVALID_PERIOD (yyyy_mm is not a calendar month) 404: ACCOUNT_NOT_FOUND 409: PERIOD_CLOSE_CONFLICT (the state moved under a concurrent close) 422: PERIOD_PRECEDES_EPOCH, PERIOD_CROSS_CHECK_FAILED, SCOPE_NOT_AN_ACCOUNT, PERIOD_TOO_LARGE

Parâmetros

NomeTipoDetalhe
scope_idstringpathobrigatório
yyyy_mmstringpathobrigatório

Respostas

StatusCorpoDetalhe
200PeriodCloseResponseResposta bem-sucedida
422HTTPValidationErrorErro de validação
POST/v1/accounting-periods/{scope_id}/{yyyy_mm}/reopen

Reopen a closed accounting period

Reopen a CLOSED period so it can accept postings and be closed again.

⛔ **Reopening appends.** The prior close record survives untouched, and closing again writes a *new* one — that is what makes a reopened period diffable against its previous close, which is what makes a retransmission explicable. No verb deletes or rewrites a close record, and no code path exists that could (RFC-028 §5 D5).

A repeat on an already-REOPENED period is a no-op.

Raises: 400: INVALID_PERIOD 409: PERIOD_NOT_CLOSED (an OPEN period has no row — there is nothing to reopen, and writing one would contradict RFC-028 §2)

Parâmetros

NomeTipoDetalhe
scope_idstringpathobrigatório
yyyy_mmstringpathobrigatório

Corpo da requisição

PeriodReopenRequest, opcional — opcional. Os campos estão listados em Esquemas, abaixo.

Respostas

StatusCorpoDetalhe
200PeriodStateResponseResposta bem-sucedida
422HTTPValidationErrorErro de validação

Esquemas

Os modelos que as operações acima aceitam e devolvem. Campos opcionais estão marcados como tal; um campo tipado como outro modelo está documentado sob o nome dele.

HTTPValidationError

CampoTipoDetalhe
detailarray de ValidationError

PeriodCloseResponse

The immutable close record, plus whether this call appended it.

CampoTipoDetalhe
appendedbooleanobrigatórioFalse when the period was already CLOSED: the stored record is returned unchanged and nothing was written. RFC-028 D7 makes a close intrinsically idempotent, so a repeat is a no-op rather than an error.
boundary_atstringobrigatórioExclusive upper bound — the São Paulo start of the day after window_to
checkpoint_hashstring, opcionalThat checkpoint's hash
checkpoint_idinteger, opcionalThe signed checkpoint covering journal_seq_no, or null when none does yet. ⛔ Never 'the latest' — a checkpoint seals a seq range, and naming one that does not cover this seq would claim an anchor that does not exist (RFC-028 §4.3).
close_seqintegerobrigatório1 for the first close, incrementing on each re-close
closed_atstringobrigatórioWhen this close was performed
closed_bystringobrigatórioCaller identity that performed it
covered_fromstring, opcionalThe first accounting day this record's evidence actually covers. Equal to window_from everywhere except the month holding the ledger's opening epoch, where it is the epoch day: that month closes (the opening entry set sits inside it, so cumulative net still equals the live balance), but §6 requires a record starting at the floor to say so rather than let a reader assume a full month.
cross_checkobjectBoth derivations' verdicts and the numbers they agreed on
derivation_versionintegerobrigatórioWhich §4.2 procedure produced this record
entry_set_countintegerobrigatórioEntry sets with a leg on this account in the window
epoch_atstring, opcionalThe ledger's opening-epoch instant
journal_chain_hashstring, opcionalJournal chain hash at that seq
journal_head_seq_nointeger, opcionalJournal head at derivation time
journal_seq_nointeger, opcionalJournal sequence number at the boundary
net_by_nodearray de objectPer (gl_node_id, layer, asset) DR/CR and net, sorted
periodstringobrigatórioYYYY-MM, in the América/São_Paulo accounting-day frame
record_hashstring, opcionalsha256 over the canonical rendering of the derived fields. ⛔ Not a signature: no signature covers these numbers (RFC-028 §4.3). A close is evidence because it is re-derivable.
ruleset_versionintegerobrigatórioGL mapping-ruleset version in force
scope_idstringobrigatórioThe account this period belongs to
window_fromstringobrigatórioFirst accounting day in the window
window_tostringobrigatórioLast accounting day in the window (inclusive)

PeriodReopenRequest

Optional reason, recorded on the head's state history.

CampoTipoDetalhe
reasonstring, opcionalWhy the period is being reopened — kept on the head's state history

PeriodStateResponse

One period's state. ⛔ Never 404 — absence is OPEN (RFC-028 §2 D2).

CampoTipoDetalhe
close_seqintegerNumber of closes performed; 0 while never closedPadrão 0
closesarray de objectEvery close record, in close order. ⛔ Reopening appends; nothing deletes one.
last_closed_atstring, opcional
last_closed_bystring, opcional
last_reopen_reasonstring, opcional
last_reopened_atstring, opcional
last_reopened_bystring, opcional
periodstringobrigatório
reopen_countintegerPadrão 0
scope_idstringobrigatório
statestringobrigatórioOPEN | CLOSED | REOPENED
state_historyarray de object
synthesizedbooleanobrigatórioTrue when this period has no row and was materialised as OPEN. Nothing is written when a month begins, so absence IS open.
updated_atstring, opcional
window_fromstring, opcional
window_tostring, opcional

ValidationError

CampoTipoDetalhe
ctxobject
inputnão declarado
locarray de string ou integerobrigatório
msgstringobrigatório
typestringobrigatório