# ChartOfAccounts

## Description

ChartOfAccounts is the top-level container that organizes all GL accounts and account groups for a company. Each CoA is scoped to a single legal entity (via companyId from the organization module), carries a name, description, and a lifecycle status. The CoA inherits its base currency from the parent company's base currency assignment. A company may define multiple CoA records over time, but only one can be ACTIVE at any point, ensuring a single authoritative account structure drives all downstream posting.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createChartOfAccounts
    Draft --> Active: activateChartOfAccounts
    Active --> Archived: deactivateChartOfAccounts
    Draft --> [*]: deleteChartOfAccounts
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| activate | DRAFT | ACTIVE | [activateChartOfAccounts](../commands/ActivateChartOfAccounts.md) |
| deactivate | ACTIVE | ARCHIVED | [deactivateChartOfAccounts](../commands/DeactivateChartOfAccounts.md) |

### Command Definitions

- [createChartOfAccounts](../commands/CreateChartOfAccounts.md) - Create a new CoA in DRAFT status for a company
- [updateChartOfAccounts](../commands/UpdateChartOfAccounts.md) - Update mutable fields (name, description) of an existing CoA
- [activateChartOfAccounts](../commands/ActivateChartOfAccounts.md) - Transition CoA from DRAFT to ACTIVE
- [deactivateChartOfAccounts](../commands/DeactivateChartOfAccounts.md) - Transition CoA from ACTIVE to ARCHIVED
- [deleteChartOfAccounts](../commands/DeleteChartOfAccounts.md) - Permanently delete a DRAFT CoA

### Query Definitions

- [GetChartOfAccounts](../queries/GetChartOfAccounts.md) - Retrieve a CoA by id or companyId
- [ListAccounts](../queries/ListAccounts.md) - List accounts within this CoA (cross-reference)
- [ListAccountGroups](../queries/ListAccountGroups.md) - List account groups within this CoA (cross-reference)

### Models

- ChartOfAccounts

### Invariants

- CoA name is required and must be non-empty
- CoA description is optional and can be updated while in DRAFT or ACTIVE status
- CoA must reference a valid companyId from the organization module
- The referenced company must be in ACTIVE status at CoA creation time; creating a CoA for a DRAFT or INACTIVE company is rejected
- CoA inherits its base currency from the parent company; the company must have a base currency assigned (guaranteed by the ACTIVE status requirement, since company activation requires base currency)
- Only one CoA per company can be in ACTIVE status at a time; activating a second CoA for the same company fails with a uniqueness constraint error
- Activating an already ACTIVE CoA fails with an invalid status transition error
- Archiving a DRAFT CoA fails with an invalid status transition error (only ACTIVE CoA can be archived)
- Reactivating an ARCHIVED CoA is not permitted (one-way transition from ACTIVE to ARCHIVED)
- Only DRAFT CoA records can be deleted; ACTIVE and ARCHIVED records are preserved
- Deleting a DRAFT CoA cascade-deletes all child Account and AccountGroup records; since the CoA is DRAFT, all child accounts are guaranteed to be in DRAFT status with no posted transactions
- GL accounts can be created under a CoA in DRAFT or ACTIVE status
- Only accounts under an ACTIVE CoA can receive journal postings from downstream modules
- All CoA lifecycle operations (create, update, activate, deactivate/archive, delete) emit audit events via the audit module recording the acting user, timestamp, and relevant field values

### Relationships

- **References Company**: Each CoA references a Company from the organization module via companyId
- **References Currency**: CoA persists the base currency inherited from the parent Company at creation time via baseCurrencyId (foreign key to Currency from the primitives module)
- **Referenced By Accounts**: GL accounts belong to a CoA (one-to-many)
- **Referenced By AccountGroups**: Account groups belong to a CoA (one-to-many)
- **Referenced By Downstream Modules**: The general-ledger module requires an ACTIVE CoA before journal postings are permitted
- **Template Provider (external dependency)**: CoA creation optionally accepts a templateId resolved by an external template provider. Templates are immutable snapshots containing pre-defined account groups and GL accounts. Template storage, versioning, and catalog management are outside the scope of this module
