syntax = "proto3"; package komp_ac.accounting; // Mutable informational journals. A journal may contain only debits, only // credits, or any non-zero balance. Balance is reported but never enforced. // Accounting periods close date ranges inside a profile and freeze account sums // without replacing the live accounts projection. Closed periods can be reopened; // approved periods are final. service Accounting { // Create a journal with its first lines when journal_id is absent, or append // all supplied lines atomically when journal_id identifies an existing one. rpc PostJournal(PostJournalRequest) returns (Journal); // Close a balanced journal. Closed journals can be reopened while their // accounting period is open. rpc CloseJournal(CloseJournalRequest) returns (Journal); rpc ReopenJournal(ReopenJournalRequest) returns (Journal); // Return journal lines and credits-minus-debits informational balance. rpc GetJournal(GetJournalRequest) returns (Journal); // Search profile journals by user-facing name while retaining journal ids // as the stable relationship keys. rpc SearchJournals(SearchJournalsRequest) returns (SearchJournalsResponse); // Return the profile-wide count of balanced and unbalanced journals. rpc GetAccountingStatus(GetAccountingStatusRequest) returns (AccountingStatus); // Return an oldest-first, paginated queue of unbalanced journals. rpc ListUnbalancedJournals(ListUnbalancedJournalsRequest) returns (ListUnbalancedJournalsResponse); // Soft-delete one line while retaining it for audit display. rpc SoftDeleteJournalLine(SoftDeleteJournalLineRequest) returns (Journal); // Create an open accounting period for a profile. Periods may be any length // (month, half-year, year). Overlapping ranges for the same profile are rejected. rpc ConfigureAccountingPeriod(ConfigureAccountingPeriodRequest) returns (AccountingPeriod); // Closing snapshots balances and blocks mutations through the period end. // A closed period may be reopened; approval makes it final. rpc CloseAccountingPeriod(CloseAccountingPeriodRequest) returns (AccountingPeriod); rpc ReopenAccountingPeriod(ReopenAccountingPeriodRequest) returns (AccountingPeriod); rpc ApproveAccountingPeriod(ApproveAccountingPeriodRequest) returns (AccountingPeriod); rpc GetAccountingPeriod(GetAccountingPeriodRequest) returns (AccountingPeriod); rpc ListAccountingPeriods(ListAccountingPeriodsRequest) returns (ListAccountingPeriodsResponse); rpc ListPeriodBalances(ListPeriodBalancesRequest) returns (ListPeriodBalancesResponse); } enum JournalSide { JOURNAL_SIDE_UNSPECIFIED = 0; JOURNAL_SIDE_DEBIT = 1; JOURNAL_SIDE_CREDIT = 2; } enum AccountingPeriodStatus { ACCOUNTING_PERIOD_STATUS_UNSPECIFIED = 0; ACCOUNTING_PERIOD_STATUS_OPEN = 1; ACCOUNTING_PERIOD_STATUS_CLOSED = 2; ACCOUNTING_PERIOD_STATUS_APPROVED = 3; } message PostJournalRequest { string profile_name = 1; // Absent creates a new journal. Present must identify an existing journal; // an unknown id is never treated as a request to create one. optional int64 journal_id = 2; // Required when creating. When appending, empty uses the journal currency; // a supplied value must match it exactly. string currency = 3; // Applied when creating and required to be empty when appending. string description = 4; // At least one line is required. The lines are inserted atomically and the // journal is allowed to remain unbalanced. repeated JournalLineInput lines = 5; // Required, unique within the profile, and at most 10 characters when // creating. Must be empty when appending to an existing journal selected by // journal_id. string journal_name = 6; // Accounting date in YYYY-MM-DD. Empty defaults to the current UTC date when // creating. Must be empty when appending. Rejected when it falls at or before // the latest closed or approved accounting boundary for the profile. string accounting_date = 7; } message JournalLineInput { JournalSide side = 1; string account_code = 2; string amount = 3; string description = 4; } message CloseJournalRequest { string profile_name = 1; int64 journal_id = 2; } message ReopenJournalRequest { string profile_name = 1; int64 journal_id = 2; } message GetJournalRequest { string profile_name = 1; int64 journal_id = 2; // False by default. True is reserved for a future Casbin permission granted // only to superadmin and is rejected until that permission is implemented. bool include_deleted = 3; } message GetAccountingStatusRequest { string profile_name = 1; } message SearchJournalsRequest { string profile_name = 1; // Case-insensitive literal substring. Empty returns all profile journals. string name_query = 2; // Zero uses 50. The maximum is 500. int32 page_size = 3; // Opaque cursor returned by the previous response. string page_token = 4; } message JournalSummary { int64 journal_id = 1; string journal_name = 2; string currency = 3; string description = 4; string total_debit = 5; string total_credit = 6; string balance = 7; int64 active_line_count = 8; bool closed = 9; string created_at = 10; string accounting_date = 11; } message SearchJournalsResponse { repeated JournalSummary journals = 1; int64 total_count = 2; string next_page_token = 3; } message AccountingStatus { bool all_journals_balanced = 1; int64 journal_count = 2; int64 balanced_journal_count = 3; int64 unbalanced_journal_count = 4; string calculated_at = 5; } message ListUnbalancedJournalsRequest { string profile_name = 1; // Zero uses 50. The maximum is 500. int32 page_size = 2; // Opaque cursor returned by the previous response. Empty starts at the // oldest unbalanced journal. string page_token = 3; // Optional ISO 4217 currency filter. Empty includes every currency. string currency = 4; } message UnbalancedJournalSummary { int64 journal_id = 1; string description = 2; string currency = 3; string total_debit = 4; string total_credit = 5; // Signed credits-minus-debits difference. string balance = 6; // Side and positive amount needed to make the journal balance zero. JournalSide missing_side = 7; string missing_amount = 8; int64 active_line_count = 9; string created_at = 10; string journal_name = 11; string accounting_date = 12; } message ListUnbalancedJournalsResponse { repeated UnbalancedJournalSummary journals = 1; int64 total_unbalanced_count = 2; string next_page_token = 3; } message SoftDeleteJournalLineRequest { string profile_name = 1; int64 journal_id = 2; int64 journal_line_id = 3; } message JournalLine { int64 id = 1; int32 line_number = 2; JournalSide side = 3; string account_code = 4; string amount = 5; string description = 6; bool deleted = 7; string created_at = 8; string deleted_at = 9; string source_table_name = 10; int64 source_record_id = 11; int64 source_row_revision = 12; reserved 13; } message Journal { int64 id = 1; string profile_name = 2; string currency = 3; string description = 4; string created_at = 5; repeated JournalLine lines = 6; string total_debit = 7; string total_credit = 8; // Informational difference calculated as credits minus debits. string balance = 9; bool closed = 10; string closed_at = 11; string closed_by_user_id = 12; string journal_name = 13; string accounting_date = 14; } message ConfigureAccountingPeriodRequest { string profile_name = 1; // Inclusive range in YYYY-MM-DD. string period_start = 2; string period_end = 3; // Optional link to the preceding period in a carry chain. optional int64 previous_period_id = 4; } message CloseAccountingPeriodRequest { int64 period_id = 1; } message ReopenAccountingPeriodRequest { int64 period_id = 1; } message ApproveAccountingPeriodRequest { int64 period_id = 1; } message GetAccountingPeriodRequest { int64 period_id = 1; } message ListAccountingPeriodsRequest { string profile_name = 1; } message ListAccountingPeriodsResponse { repeated AccountingPeriod periods = 1; } message AccountingPeriod { int64 id = 1; string profile_name = 2; string period_start = 3; string period_end = 4; AccountingPeriodStatus status = 5; int64 previous_period_id = 6; string closed_at = 7; string closed_by_user_id = 8; string approved_at = 9; string approved_by_user_id = 10; } message ListPeriodBalancesRequest { int64 period_id = 1; } message PeriodBalance { int64 period_id = 1; string account_code = 2; string currency = 3; // Signed nets use debit-positive convention. string opening_balance = 4; string period_debit = 5; string period_credit = 6; string closing_balance = 7; } message ListPeriodBalancesResponse { repeated PeriodBalance balances = 1; }