accounting locking

This commit is contained in:
Priec
2026-07-26 11:58:09 +02:00
parent f0849e8c84
commit 8146bce654
4 changed files with 953 additions and 31 deletions

View File

@@ -3,14 +3,18 @@ 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);
// Permanently lock a balanced journal. This is an explicit action; becoming
// balanced never locks a journal automatically.
rpc LockJournal(LockJournalRequest) 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);
@@ -28,6 +32,22 @@ service Accounting {
// 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 {
@@ -36,6 +56,13 @@ enum JournalSide {
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;
@@ -58,6 +85,11 @@ message PostJournalRequest {
// 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 {
@@ -67,7 +99,12 @@ message JournalLineInput {
string description = 4;
}
message LockJournalRequest {
message CloseJournalRequest {
string profile_name = 1;
int64 journal_id = 2;
}
message ReopenJournalRequest {
string profile_name = 1;
int64 journal_id = 2;
}
@@ -107,8 +144,9 @@ message JournalSummary {
string total_credit = 6;
string balance = 7;
int64 active_line_count = 8;
bool locked = 9;
bool closed = 9;
string created_at = 10;
string accounting_date = 11;
}
message SearchJournalsResponse {
@@ -155,6 +193,7 @@ message UnbalancedJournalSummary {
int64 active_line_count = 9;
string created_at = 10;
string journal_name = 11;
string accounting_date = 12;
}
message ListUnbalancedJournalsResponse {
@@ -196,8 +235,74 @@ message Journal {
string total_credit = 8;
// Informational difference calculated as credits minus debits.
string balance = 9;
bool locked = 10;
string locked_at = 11;
string locked_by_user_id = 12;
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;
}