@mulmoclaude/accounting-plugin 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/server/accountNormalize.d.ts +3 -0
  2. package/dist/server/accountNormalize.d.ts.map +1 -0
  3. package/dist/server/atomic.d.ts +13 -0
  4. package/dist/server/atomic.d.ts.map +1 -0
  5. package/dist/server/context.d.ts +39 -0
  6. package/dist/server/context.d.ts.map +1 -0
  7. package/dist/server/defaultAccounts.d.ts +3 -0
  8. package/dist/server/defaultAccounts.d.ts.map +1 -0
  9. package/dist/server/eventPublisher.d.ts +14 -0
  10. package/dist/server/eventPublisher.d.ts.map +1 -0
  11. package/dist/server/http.d.ts +3 -0
  12. package/dist/server/http.d.ts.map +1 -0
  13. package/dist/server/index.d.ts +6 -0
  14. package/dist/server/index.d.ts.map +1 -0
  15. package/dist/server/io.d.ts +67 -0
  16. package/dist/server/io.d.ts.map +1 -0
  17. package/dist/server/journal.d.ts +74 -0
  18. package/dist/server/journal.d.ts.map +1 -0
  19. package/dist/server/openingBalances.d.ts +30 -0
  20. package/dist/server/openingBalances.d.ts.map +1 -0
  21. package/dist/server/report.d.ts +98 -0
  22. package/dist/server/report.d.ts.map +1 -0
  23. package/dist/server/router.d.ts +7 -0
  24. package/dist/server/router.d.ts.map +1 -0
  25. package/dist/server/service.d.ts +148 -0
  26. package/dist/server/service.d.ts.map +1 -0
  27. package/dist/server/snapshotCache.d.ts +52 -0
  28. package/dist/server/snapshotCache.d.ts.map +1 -0
  29. package/dist/server/timeSeries.d.ts +47 -0
  30. package/dist/server/timeSeries.d.ts.map +1 -0
  31. package/dist/server/types.d.ts +134 -0
  32. package/dist/server/types.d.ts.map +1 -0
  33. package/dist/server.cjs +2101 -0
  34. package/dist/server.cjs.map +1 -0
  35. package/dist/server.js +2074 -0
  36. package/dist/server.js.map +1 -0
  37. package/dist/shared/actions.d.ts +19 -0
  38. package/dist/shared/actions.d.ts.map +1 -0
  39. package/dist/shared/channels.d.ts +46 -0
  40. package/dist/shared/channels.d.ts.map +1 -0
  41. package/dist/shared/countries.d.ts +51 -0
  42. package/dist/shared/countries.d.ts.map +1 -0
  43. package/dist/shared/currencies.d.ts +34 -0
  44. package/dist/shared/currencies.d.ts.map +1 -0
  45. package/dist/shared/dates.d.ts +15 -0
  46. package/dist/shared/dates.d.ts.map +1 -0
  47. package/dist/shared/errors.d.ts +2 -0
  48. package/dist/shared/errors.d.ts.map +1 -0
  49. package/dist/shared/fiscalYear.d.ts +22 -0
  50. package/dist/shared/fiscalYear.d.ts.map +1 -0
  51. package/dist/shared/index.d.ts +9 -0
  52. package/dist/shared/index.d.ts.map +1 -0
  53. package/dist/shared/timeSeriesEnums.d.ts +5 -0
  54. package/dist/shared/timeSeriesEnums.d.ts.map +1 -0
  55. package/dist/shared.cjs +466 -0
  56. package/dist/shared.cjs.map +1 -0
  57. package/dist/shared.js +432 -0
  58. package/dist/shared.js.map +1 -0
  59. package/dist/style.css +1255 -0
  60. package/dist/vue/Preview.vue.d.ts +8 -0
  61. package/dist/vue/Preview.vue.d.ts.map +1 -0
  62. package/dist/vue/View.vue.d.ts +30 -0
  63. package/dist/vue/View.vue.d.ts.map +1 -0
  64. package/dist/vue/api.d.ts +269 -0
  65. package/dist/vue/api.d.ts.map +1 -0
  66. package/dist/vue/components/AccountEditor.vue.d.ts +19 -0
  67. package/dist/vue/components/AccountEditor.vue.d.ts.map +1 -0
  68. package/dist/vue/components/AccountRow.vue.d.ts +14 -0
  69. package/dist/vue/components/AccountRow.vue.d.ts.map +1 -0
  70. package/dist/vue/components/AccountsList.vue.d.ts +15 -0
  71. package/dist/vue/components/AccountsList.vue.d.ts.map +1 -0
  72. package/dist/vue/components/AccountsModal.vue.d.ts +15 -0
  73. package/dist/vue/components/AccountsModal.vue.d.ts.map +1 -0
  74. package/dist/vue/components/BalanceSheet.vue.d.ts +13 -0
  75. package/dist/vue/components/BalanceSheet.vue.d.ts.map +1 -0
  76. package/dist/vue/components/BookSettings.vue.d.ts +18 -0
  77. package/dist/vue/components/BookSettings.vue.d.ts.map +1 -0
  78. package/dist/vue/components/BookSwitcher.vue.d.ts +17 -0
  79. package/dist/vue/components/BookSwitcher.vue.d.ts.map +1 -0
  80. package/dist/vue/components/DateRangePicker.vue.d.ts +19 -0
  81. package/dist/vue/components/DateRangePicker.vue.d.ts.map +1 -0
  82. package/dist/vue/components/JournalEntryForm.vue.d.ts +19 -0
  83. package/dist/vue/components/JournalEntryForm.vue.d.ts.map +1 -0
  84. package/dist/vue/components/JournalList.vue.d.ts +30 -0
  85. package/dist/vue/components/JournalList.vue.d.ts.map +1 -0
  86. package/dist/vue/components/Ledger.vue.d.ts +21 -0
  87. package/dist/vue/components/Ledger.vue.d.ts.map +1 -0
  88. package/dist/vue/components/NewBookForm.vue.d.ts +20 -0
  89. package/dist/vue/components/NewBookForm.vue.d.ts.map +1 -0
  90. package/dist/vue/components/OpeningBalancesForm.vue.d.ts +15 -0
  91. package/dist/vue/components/OpeningBalancesForm.vue.d.ts.map +1 -0
  92. package/dist/vue/components/ProfitLoss.vue.d.ts +19 -0
  93. package/dist/vue/components/ProfitLoss.vue.d.ts.map +1 -0
  94. package/dist/vue/components/accountDraft.d.ts +8 -0
  95. package/dist/vue/components/accountDraft.d.ts.map +1 -0
  96. package/dist/vue/components/accountNumbering.d.ts +20 -0
  97. package/dist/vue/components/accountNumbering.d.ts.map +1 -0
  98. package/dist/vue/components/accountValidation.d.ts +34 -0
  99. package/dist/vue/components/accountValidation.d.ts.map +1 -0
  100. package/dist/vue/components/useLatestRequest.d.ts +10 -0
  101. package/dist/vue/components/useLatestRequest.d.ts.map +1 -0
  102. package/dist/vue/hostContext.d.ts +31 -0
  103. package/dist/vue/hostContext.d.ts.map +1 -0
  104. package/dist/vue/index.d.ts +7 -0
  105. package/dist/vue/index.d.ts.map +1 -0
  106. package/dist/vue/useAccountingChannel.d.ts +13 -0
  107. package/dist/vue/useAccountingChannel.d.ts.map +1 -0
  108. package/dist/vue.cjs +3641 -0
  109. package/dist/vue.cjs.map +1 -0
  110. package/dist/vue.js +3638 -0
  111. package/dist/vue.js.map +1 -0
  112. package/package.json +74 -0
@@ -0,0 +1,3 @@
1
+ import type { Account } from "./types.js";
2
+ export declare function normalizeStoredAccount(input: Account, existing?: Account): Account;
3
+ //# sourceMappingURL=accountNormalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accountNormalize.d.ts","sourceRoot":"","sources":["../../src/server/accountNormalize.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAMlF"}
@@ -0,0 +1,13 @@
1
+ export interface WriteAtomicOptions {
2
+ /** Adds a unique suffix to the tmp filename so concurrent writers to
3
+ * the same destination don't collide at the OS layer. */
4
+ uniqueTmp?: boolean;
5
+ }
6
+ /** True for a `not found` filesystem error. */
7
+ export declare function isEnoent(err: unknown): boolean;
8
+ /** Atomic write: tmp alongside destination, then rename. */
9
+ export declare function writeFileAtomic(filePath: string, content: string, opts?: WriteAtomicOptions): Promise<void>;
10
+ /** Atomic JSON write (2-space indent), the only serialization shape the
11
+ * accounting io layer needs. */
12
+ export declare function writeJsonAtomic(filePath: string, data: unknown, opts?: WriteAtomicOptions): Promise<void>;
13
+ //# sourceMappingURL=atomic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomic.d.ts","sourceRoot":"","sources":["../../src/server/atomic.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,kBAAkB;IACjC;8DAC0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE9C;AAED,4DAA4D;AAC5D,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUrH;AAED;iCACiC;AACjC,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnH"}
@@ -0,0 +1,39 @@
1
+ /** Minimal pub/sub shape — structurally compatible with the host's
2
+ * `IPubSub`. The eventPublisher holds its own instance (set via
3
+ * `initAccountingEventPublisher`); this type is the contract. */
4
+ export interface IPubSub {
5
+ publish: (channel: string, payload: unknown) => void;
6
+ }
7
+ /** Logger shape — mirrors the host server logger
8
+ * `log.{level}(namespace, message, data?)`. `data` uses
9
+ * `Record<string, unknown>` (not `object`) so the host's `Logger`
10
+ * is structurally assignable when injected. */
11
+ export interface AccountingLogger {
12
+ error: (namespace: string, message: string, data?: Record<string, unknown>) => void;
13
+ warn: (namespace: string, message: string, data?: Record<string, unknown>) => void;
14
+ info: (namespace: string, message: string, data?: Record<string, unknown>) => void;
15
+ debug: (namespace: string, message: string, data?: Record<string, unknown>) => void;
16
+ }
17
+ export interface AccountingServerDeps {
18
+ /** Absolute path to the workspace root (where `data/` lives). Used as
19
+ * the default when a service/io call doesn't pass an explicit root. */
20
+ workspaceRoot: string;
21
+ logger: AccountingLogger;
22
+ }
23
+ /** Called once by the host before the accounting router is mounted. */
24
+ export declare function configureAccountingServer(context: AccountingServerDeps): void;
25
+ /** Default workspace root for io calls that don't pass one explicitly.
26
+ * Throws if the host never configured the server — a real wiring bug
27
+ * (unit tests always pass an explicit root, so they never hit this). */
28
+ export declare function defaultWorkspaceRoot(): string;
29
+ /** Logger proxy — forwards to the injected logger, console fallback
30
+ * before configuration. Lets call sites keep `log.warn("accounting", …)`. */
31
+ export declare const log: AccountingLogger;
32
+ /** Workspace-relative directories this plugin owns. Mirrors the host
33
+ * META's `workspaceDirs` (kept in sync by value; the host META stays
34
+ * the codegen-discoverable source for the aggregator merge). */
35
+ export declare const ACCOUNTING_DIRS: {
36
+ readonly accounting: "data/accounting";
37
+ readonly accountingBooks: "data/accounting/books";
38
+ };
39
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAcA;;kEAEkE;AAClE,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD;AAED;;;gDAGgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACpF,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACnF,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACnF,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACrF;AAED,MAAM,WAAW,oBAAoB;IACnC;4EACwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAID,uEAAuE;AACvE,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAE7E;AAED;;yEAEyE;AACzE,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AASD;8EAC8E;AAC9E,eAAO,MAAM,GAAG,EAAE,gBAKjB,CAAC;AAEF;;iEAEiE;AACjE,eAAO,MAAM,eAAe;;;CAGlB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Account } from "./types.js";
2
+ export declare const DEFAULT_ACCOUNTS: readonly Account[];
3
+ //# sourceMappingURL=defaultAccounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultAccounts.d.ts","sourceRoot":"","sources":["../../src/server/defaultAccounts.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,gBAAgB,EAAE,SAAS,OAAO,EAsE9C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type BookChannelPayload as AccountingBookChannelPayload } from "../shared";
2
+ import { type IPubSub } from "./context.js";
3
+ export declare function initAccountingEventPublisher(instance: IPubSub): void;
4
+ /** Per-book change notification. `period` should be the entry's
5
+ * YYYY-MM bucket (or the earliest invalidated month for snapshot
6
+ * events). */
7
+ export declare function publishBookChange(bookId: string, payload: AccountingBookChannelPayload): void;
8
+ /** Fired when the *list* of books changes (createBook, deleteBook).
9
+ * Payload is intentionally empty — subscribers refetch from
10
+ * /api/accounting. */
11
+ export declare function publishBooksChanged(): void;
12
+ /** Test-only — drop the module singleton so each test starts clean. */
13
+ export declare function _resetAccountingEventPublisherForTesting(): void;
14
+ //# sourceMappingURL=eventPublisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventPublisher.d.ts","sourceRoot":"","sources":["../../src/server/eventPublisher.ts"],"names":[],"mappings":"AASA,OAAO,EAAkE,KAAK,kBAAkB,IAAI,4BAA4B,EAAE,MAAM,WAAW,CAAC;AACpJ,OAAO,EAAO,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAKjD,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAEpE;AAgBD;;eAEe;AACf,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,4BAA4B,GAAG,IAAI,CAE7F;AAED;;uBAEuB;AACvB,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,uEAAuE;AACvE,wBAAgB,wCAAwC,IAAI,IAAI,CAE/D"}
@@ -0,0 +1,3 @@
1
+ import type { Request, Response } from "express";
2
+ export declare function asyncHandler<TReq = Request, TRes = Response>(namespace: string, fallbackMessage: string, handler: (req: TReq, res: TRes) => Promise<void>): (req: TReq, res: TRes) => Promise<void>;
3
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/server/http.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAIjD,wBAAgB,YAAY,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,GAAG,QAAQ,EAC1D,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/C,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAazC"}
@@ -0,0 +1,6 @@
1
+ export { createAccountingRouter } from "./router.js";
2
+ export { configureAccountingServer } from "./context.js";
3
+ export type { AccountingServerDeps, AccountingLogger, IPubSub } from "./context.js";
4
+ export { initAccountingEventPublisher } from "./eventPublisher.js";
5
+ export { isValidCalendarDate } from "./journal.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAInE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,67 @@
1
+ import type { AccountingConfig, Account, JournalEntry, MonthSnapshot } from "./types.js";
2
+ export declare function isSafeBookId(bookId: string): boolean;
3
+ export declare function bookRoot(bookId: string, workspaceRoot?: string): string;
4
+ export declare function readConfig(workspaceRoot?: string): Promise<AccountingConfig | null>;
5
+ export declare function writeConfig(config: AccountingConfig, workspaceRoot?: string): Promise<void>;
6
+ export declare function readAccounts(bookId: string, workspaceRoot?: string): Promise<Account[]>;
7
+ export declare function writeAccounts(bookId: string, accounts: Account[], workspaceRoot?: string): Promise<void>;
8
+ /** Convert a YYYY-MM-DD date string to its YYYY-MM month bucket. The
9
+ * month bucket dictates which JSONL file the entry lives in. */
10
+ export declare function periodFromDate(date: string): string;
11
+ /** Append one entry to the appropriate month's JSONL.
12
+ *
13
+ * Uses POSIX append-only semantics (`fs.appendFile` → `O_APPEND`).
14
+ * Two concurrent callers landing in the same month file are
15
+ * serialised by the kernel — neither overwrites the other, which
16
+ * is the bug the previous read-modify-write implementation had.
17
+ *
18
+ * Crash mid-write: an entry shorter than `PIPE_BUF` (≥ 512 bytes
19
+ * on every supported platform) writes atomically; a single
20
+ * serialised `JournalEntry` is comfortably under that. If the
21
+ * process is killed during the syscall the worst case is a torn
22
+ * trailing line, which `readJournalMonth` already tolerates by
23
+ * skipping unparseable lines and surfacing a `skipped` count to
24
+ * the caller. */
25
+ export declare function appendJournal(bookId: string, entry: JournalEntry, workspaceRoot?: string): Promise<void>;
26
+ /** Append a batch of entries: same-period entries are concatenated
27
+ * into one `appendFile` call so the whole same-period chunk hits
28
+ * the kernel as a single `O_APPEND` write — small chunks (under
29
+ * `PIPE_BUF`, ≥ 512 bytes on every supported platform) are
30
+ * guaranteed atomic by POSIX, and `O_APPEND` serialises with any
31
+ * concurrent appender (a parallel `appendJournal` / `addEntries`
32
+ * call can never overwrite our write or vice versa). Cross-period
33
+ * batches loop one append per period; each is independently
34
+ * concurrency-safe but their union is not transactional across
35
+ * files (out of scope for the append-only JSONL design). */
36
+ export declare function appendJournalBatch(bookId: string, entries: readonly JournalEntry[], workspaceRoot?: string): Promise<void>;
37
+ /** Read a single month's JSONL. Malformed lines are skipped (logged
38
+ * by the caller; this layer just returns the parseable subset) so
39
+ * one bad line doesn't lock the user out of their book. */
40
+ export declare function readJournalMonth(bookId: string, period: string, workspaceRoot?: string): Promise<{
41
+ entries: JournalEntry[];
42
+ skipped: number;
43
+ }>;
44
+ /** List the YYYY-MM periods that have a journal file on disk, sorted
45
+ * ascending. Useful for full-history scans (rebuilding snapshots
46
+ * from scratch). */
47
+ export declare function listJournalPeriods(bookId: string, workspaceRoot?: string): Promise<string[]>;
48
+ export declare function readSnapshot(bookId: string, period: string, workspaceRoot?: string): Promise<MonthSnapshot | null>;
49
+ export declare function writeSnapshot(bookId: string, snapshot: MonthSnapshot, workspaceRoot?: string): Promise<void>;
50
+ /** Drop snapshot files for all periods >= `fromPeriod`. The next
51
+ * read regenerates them. Idempotent: missing files are silently
52
+ * ignored. */
53
+ export declare function invalidateSnapshotsFrom(bookId: string, fromPeriod: string, workspaceRoot?: string): Promise<{
54
+ removed: string[];
55
+ }>;
56
+ /** Drop ALL snapshots for a book — used by `rebuildSnapshots()`
57
+ * with no `from`. Equivalent to `invalidateSnapshotsFrom("0000-00")`
58
+ * but reads more clearly at call sites. */
59
+ export declare function invalidateAllSnapshots(bookId: string, workspaceRoot?: string): Promise<{
60
+ removed: string[];
61
+ }>;
62
+ export declare function bookExists(bookId: string, workspaceRoot?: string): Promise<boolean>;
63
+ export declare function ensureBookDir(bookId: string, workspaceRoot?: string): Promise<void>;
64
+ /** Recursively delete a book's directory. Used by `deleteBook` after
65
+ * the config has been updated to drop the entry. */
66
+ export declare function removeBookDir(bookId: string, workspaceRoot?: string): Promise<void>;
67
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/server/io.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import type { Account, JournalEntry, JournalLine } from "./types.js";
2
+ /** Defensive cap on `JournalLine.taxRegistrationId`. Real-world IDs
3
+ * are short (JP T-numbers are 14 chars, EU VAT IDs ≤ 14, GSTIN is
4
+ * 15, ABN is 11). 32 covers every documented format with comfortable
5
+ * margin while still rejecting accidental paste-bombs. Validation
6
+ * applies to the *trimmed* value so a string of pure whitespace
7
+ * doesn't trip the limit (it normalises to absent). */
8
+ export declare const MAX_TAX_REGISTRATION_ID_LENGTH = 32;
9
+ export interface ValidationError {
10
+ field: string;
11
+ message: string;
12
+ }
13
+ export interface ValidationResult {
14
+ ok: boolean;
15
+ errors: ValidationError[];
16
+ }
17
+ /** Build today's `YYYY-MM-DD` from the host's local timezone.
18
+ * Centralised here so server-side defaults (the void-date on
19
+ * `voidEntry`, the today() stamp on opening replacements, etc.)
20
+ * agree with the client-side `localDateString()` from
21
+ * `src/plugins/accounting/dates.ts`. `toISOString().slice(0, 10)`
22
+ * would emit a UTC date instead — which silently flips into
23
+ * tomorrow / yesterday in negative-offset timezones. */
24
+ export declare function localDateString(now?: Date): string;
25
+ /** Validate that `date` is both shaped as YYYY-MM-DD AND represents
26
+ * a real calendar day. The bare regex accepts impossible values
27
+ * like 2026-02-31 or 2026-13-01 which would then poison
28
+ * `periodFromDate`, sort orders, and snapshot keys. We reparse
29
+ * through the Date constructor and roundtrip-format to catch
30
+ * silent normalisation (e.g. "2026-02-30" → Mar 02). */
31
+ export declare function isValidCalendarDate(date: string): boolean;
32
+ /** Returns Σ debit − Σ credit. Used by callers that need the actual
33
+ * imbalance value (e.g. the OpeningBalancesForm shows live diff). */
34
+ export declare function netBalance(lines: readonly JournalLine[]): number;
35
+ export declare function validateEntry(input: {
36
+ date: string;
37
+ lines: readonly JournalLine[];
38
+ accounts: readonly Account[];
39
+ }): ValidationResult;
40
+ /** Build a JournalEntry — validation is the caller's responsibility
41
+ * (it should have called `validateEntry` first). The id is a fresh
42
+ * UUID; createdAt is the wall clock at the moment of creation.
43
+ * Lines are normalized so optional string fields don't persist as
44
+ * empty strings. */
45
+ export declare function makeEntry(input: {
46
+ date: string;
47
+ lines: readonly JournalLine[];
48
+ memo?: string;
49
+ kind?: JournalEntry["kind"];
50
+ replacesEntryId?: string;
51
+ }): JournalEntry;
52
+ /** Build the human-readable memo that goes on the voiding entry.
53
+ * Format: `void of '<original memo>' on <original date>` (or the
54
+ * no-memo fallback when the original carried no memo). The reason
55
+ * the user typed is appended after a colon when present. */
56
+ export declare function voidMemo(target: JournalEntry, reason: string | undefined): string;
57
+ /** Build the reversing pair for a voided entry. The `void` entry
58
+ * swaps debit / credit on every line so the net effect is zero;
59
+ * the `void-marker` is a zero-line entry that exists purely to
60
+ * carry the `voidedEntryId` reference and the user's reason. The
61
+ * marker keeps `listEntries` queries simple — filtering by
62
+ * `kind: "void-marker"` surfaces every voided id without scanning
63
+ * for matching pairs. */
64
+ export declare function makeVoidEntries(target: JournalEntry, reason: string | undefined, voidDate: string): {
65
+ reverse: JournalEntry;
66
+ marker: JournalEntry;
67
+ };
68
+ /** Returns the set of entry ids that have been voided — built from
69
+ * every `void-marker` entry's `voidedEntryId`. Reports use this to
70
+ * exclude original-and-reverse pairs from the activity listing
71
+ * (the netting is automatic in B/S aggregates because the reverse
72
+ * entry has equal-and-opposite lines). */
73
+ export declare function voidedIdSet(entries: readonly JournalEntry[]): Set<string>;
74
+ //# sourceMappingURL=journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/server/journal.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AASrE;;;;;wDAKwD;AACxD,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAYD;;;;;;yDAMyD;AACzD,wBAAgB,eAAe,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAK9D;AAED;;;;;yDAKyD;AACzD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKzD;AAED;sEACsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAOhE;AA4CD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAAG,gBAAgB,CAgBpI;AAED;;;;qBAIqB;AACrB,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,YAAY,CAWf;AAcD;;;6DAG6D;AAC7D,wBAAgB,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAIjF;AAED;;;;;;0BAM0B;AAC1B,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAoCnJ;AAED;;;;2CAI2C;AAC3C,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAMzE"}
@@ -0,0 +1,30 @@
1
+ import type { Account, JournalEntry, JournalLine } from "./types.js";
2
+ export interface OpeningValidationError {
3
+ field: string;
4
+ message: string;
5
+ }
6
+ export interface OpeningValidationResult {
7
+ ok: boolean;
8
+ errors: OpeningValidationError[];
9
+ }
10
+ /** Find the existing opening entry for a book, if any. Multiple
11
+ * openings shouldn't coexist (the route enforces void-then-append),
12
+ * but if they do the most recent by `createdAt` wins so callers
13
+ * always see one canonical opening. */
14
+ export declare function findActiveOpening(entries: readonly JournalEntry[]): JournalEntry | null;
15
+ interface OpeningValidationInput {
16
+ asOfDate: string;
17
+ lines: readonly JournalLine[];
18
+ accounts: readonly Account[];
19
+ existingEntries: readonly JournalEntry[];
20
+ }
21
+ /** Validate inputs for `setOpeningBalances`. Caller passes the full
22
+ * list of journal entries in the book so we can check the
23
+ * "asOfDate must precede every other entry" rule. An opening with
24
+ * zero lines is accepted as a no-op marker — it satisfies the
25
+ * "book has an opening" gate the UI uses without committing the
26
+ * user to specific balances on day one (they can replace it
27
+ * later). */
28
+ export declare function validateOpening(input: OpeningValidationInput): OpeningValidationResult;
29
+ export {};
30
+ //# sourceMappingURL=openingBalances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openingBalances.d.ts","sourceRoot":"","sources":["../../src/server/openingBalances.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMrE,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,sBAAsB,EAAE,CAAC;CAClC;AAED;;;wCAGwC;AACxC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,GAAG,IAAI,CASvF;AAED,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,eAAe,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAwCD;;;;;;cAMc;AACd,wBAAgB,eAAe,CAAC,KAAK,EAAE,sBAAsB,GAAG,uBAAuB,CAgBtF"}
@@ -0,0 +1,98 @@
1
+ import type { Account, AccountBalance, AccountType, JournalEntry } from "./types.js";
2
+ /** Returns net (debit − credit) per account across the supplied
3
+ * entries. Voids work by having an original + reverse pair that
4
+ * cancel mathematically — both are included in aggregation (their
5
+ * contributions sum to zero). The `void-marker` entries carry no
6
+ * lines, so excluding them is just a formality.
7
+ *
8
+ * Why not "exclude original via voidedIdSet"? Because then the
9
+ * reverse half would remain unmatched, and the net would be the
10
+ * original's amount with the wrong sign. Letting the math cancel
11
+ * naturally is simpler and impossible to get wrong. */
12
+ export declare function aggregateBalances(entries: readonly JournalEntry[]): AccountBalance[];
13
+ export interface BalanceSheetSection {
14
+ type: AccountType;
15
+ rows: {
16
+ accountCode: string;
17
+ accountName: string;
18
+ balance: number;
19
+ }[];
20
+ total: number;
21
+ }
22
+ export interface BalanceSheet {
23
+ asOf: string;
24
+ sections: BalanceSheetSection[];
25
+ /** Σ assets − Σ (liabilities + equity). Should be 0 (the
26
+ * accounting equation); a non-zero here indicates either a
27
+ * rounding artefact or a data problem. */
28
+ imbalance: number;
29
+ }
30
+ /** Sentinel `accountCode` for the synthetic "Current period
31
+ * earnings" row added to the Equity section by `buildBalanceSheet`.
32
+ * The View detects this code and substitutes a localised label
33
+ * for the fixed English fallback. */
34
+ export declare const CURRENT_EARNINGS_ACCOUNT_CODE = "_currentEarnings";
35
+ export declare function buildBalanceSheet(input: {
36
+ accounts: readonly Account[];
37
+ balances: readonly AccountBalance[];
38
+ asOf: string;
39
+ }): BalanceSheet;
40
+ export interface ProfitLoss {
41
+ from: string;
42
+ to: string;
43
+ income: {
44
+ rows: {
45
+ accountCode: string;
46
+ accountName: string;
47
+ amount: number;
48
+ }[];
49
+ total: number;
50
+ };
51
+ expense: {
52
+ rows: {
53
+ accountCode: string;
54
+ accountName: string;
55
+ amount: number;
56
+ }[];
57
+ total: number;
58
+ };
59
+ netIncome: number;
60
+ }
61
+ export declare function buildProfitLoss(input: {
62
+ accounts: readonly Account[];
63
+ entries: readonly JournalEntry[];
64
+ from: string;
65
+ to: string;
66
+ }): ProfitLoss;
67
+ export interface LedgerRow {
68
+ entryId: string;
69
+ date: string;
70
+ kind: JournalEntry["kind"];
71
+ memo?: string;
72
+ debit: number;
73
+ credit: number;
74
+ /** Running netDebit balance for this account, in entry order. */
75
+ runningBalance: number;
76
+ /** Counterparty tax-registration ID copied from the source
77
+ * journal line (T-number / VAT ID / GSTIN / ABN). Surfaced as a
78
+ * Ledger column when the active account is in the input-tax
79
+ * band (14xx — see `isTaxAccountCode` in
80
+ * src/plugins/accounting/components/accountNumbering.ts).
81
+ * Carried per row even on non-tax accounts so a future view
82
+ * that wants to show it elsewhere doesn't need a server change. */
83
+ taxRegistrationId?: string;
84
+ }
85
+ export interface Ledger {
86
+ accountCode: string;
87
+ accountName: string;
88
+ rows: LedgerRow[];
89
+ /** Closing netDebit balance — the sum at the bottom of `rows`. */
90
+ closingBalance: number;
91
+ }
92
+ export declare function buildLedger(input: {
93
+ account: Account;
94
+ entries: readonly JournalEntry[];
95
+ from?: string;
96
+ to?: string;
97
+ }): Ledger;
98
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/server/report.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIrF;;;;;;;;;wDASwD;AACxD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,cAAc,EAAE,CAcpF;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC;;+CAE2C;IAC3C,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD;;;sCAGsC;AACtC,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAgBhE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CA4B1I;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE;QAAE,IAAI,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAChG,OAAO,EAAE;QAAE,IAAI,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACjG,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CA2B/I;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;wEAMoE;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;CACxB;AAkDD,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgB7H"}
@@ -0,0 +1,7 @@
1
+ import { Router } from "express";
2
+ /** Build the accounting Express router. The host injects its workspace
3
+ * root + logger via `configureAccountingServer(...)` and pub/sub via
4
+ * `initAccountingEventPublisher(...)`, then mounts the returned router
5
+ * with `app.use(...)`. */
6
+ export declare function createAccountingRouter(): Router;
7
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAsUpD;;;2BAG2B;AAC3B,wBAAgB,sBAAsB,IAAI,MAAM,CAsC/C"}
@@ -0,0 +1,148 @@
1
+ import { aggregateBalances, buildBalanceSheet, buildLedger, buildProfitLoss } from "./report.js";
2
+ import { type TimeSeriesGranularity, type TimeSeriesMetric, type TimeSeriesPoint } from "./timeSeries.js";
3
+ import { balancesAtEndOf } from "./snapshotCache.js";
4
+ import type { Account, BookSummary, JournalEntry, JournalLine, ReportPeriod } from "./types.js";
5
+ export declare class AccountingError extends Error {
6
+ status: number;
7
+ details?: unknown | undefined;
8
+ constructor(status: number, message: string, details?: unknown | undefined);
9
+ }
10
+ export declare function listBooks(workspaceRoot?: string): Promise<{
11
+ books: BookSummary[];
12
+ }>;
13
+ export declare function createBook(input: {
14
+ id?: string;
15
+ name: string;
16
+ currency?: string;
17
+ country?: string;
18
+ fiscalYearEnd?: string;
19
+ }, workspaceRoot?: string): Promise<{
20
+ book: BookSummary;
21
+ }>;
22
+ export declare function updateBook(input: {
23
+ bookId: string;
24
+ name?: string;
25
+ country?: string;
26
+ fiscalYearEnd?: string;
27
+ }, workspaceRoot?: string): Promise<{
28
+ book: BookSummary;
29
+ }>;
30
+ export declare function deleteBook(input: {
31
+ bookId: string;
32
+ confirm: boolean;
33
+ }, workspaceRoot?: string): Promise<{
34
+ deletedBookId: string;
35
+ deletedBookName: string;
36
+ }>;
37
+ export declare function listAccounts(input: {
38
+ bookId?: string;
39
+ }, workspaceRoot?: string): Promise<{
40
+ bookId: string;
41
+ accounts: Account[];
42
+ }>;
43
+ export declare function upsertAccount(input: {
44
+ bookId?: string;
45
+ account: Account;
46
+ }, workspaceRoot?: string): Promise<{
47
+ bookId: string;
48
+ account: Account;
49
+ accounts: Account[];
50
+ }>;
51
+ export interface AddEntriesItem {
52
+ date: string;
53
+ lines: JournalLine[];
54
+ memo?: string;
55
+ replacesEntryId?: string;
56
+ }
57
+ export declare function addEntries(input: {
58
+ bookId?: string;
59
+ entries: AddEntriesItem[];
60
+ }, workspaceRoot?: string): Promise<{
61
+ bookId: string;
62
+ entries: JournalEntry[];
63
+ }>;
64
+ export declare function voidEntry(input: {
65
+ bookId?: string;
66
+ entryId: string;
67
+ reason?: string;
68
+ voidDate?: string;
69
+ }, workspaceRoot?: string): Promise<{
70
+ bookId: string;
71
+ reverseEntry: JournalEntry;
72
+ markerEntry: JournalEntry;
73
+ }>;
74
+ interface ListEntriesInput {
75
+ bookId?: string;
76
+ from?: string;
77
+ to?: string;
78
+ accountCode?: string;
79
+ }
80
+ export declare function listEntries(input: ListEntriesInput, workspaceRoot?: string): Promise<{
81
+ bookId: string;
82
+ entries: JournalEntry[];
83
+ voidedEntryIds: string[];
84
+ }>;
85
+ export declare function getOpeningBalances(input: {
86
+ bookId?: string;
87
+ }, workspaceRoot?: string): Promise<{
88
+ bookId: string;
89
+ opening: JournalEntry | null;
90
+ }>;
91
+ export declare function setOpeningBalances(input: {
92
+ bookId?: string;
93
+ asOfDate: string;
94
+ lines: JournalLine[];
95
+ memo?: string;
96
+ }, workspaceRoot?: string): Promise<{
97
+ bookId: string;
98
+ openingEntry: JournalEntry;
99
+ replacedExisting: boolean;
100
+ }>;
101
+ export declare function getBalanceSheetReport(input: {
102
+ bookId?: string;
103
+ period: ReportPeriod;
104
+ }, workspaceRoot?: string): Promise<{
105
+ bookId: string;
106
+ balanceSheet: ReturnType<typeof buildBalanceSheet>;
107
+ }>;
108
+ export declare function getProfitLossReport(input: {
109
+ bookId?: string;
110
+ period: ReportPeriod;
111
+ }, workspaceRoot?: string): Promise<{
112
+ bookId: string;
113
+ profitLoss: ReturnType<typeof buildProfitLoss>;
114
+ }>;
115
+ export declare function getLedgerReport(input: {
116
+ bookId?: string;
117
+ accountCode: string;
118
+ period?: ReportPeriod;
119
+ }, workspaceRoot?: string): Promise<{
120
+ bookId: string;
121
+ ledger: ReturnType<typeof buildLedger>;
122
+ }>;
123
+ export interface TimeSeriesReportInput {
124
+ bookId?: string;
125
+ metric: unknown;
126
+ granularity: unknown;
127
+ from: unknown;
128
+ to: unknown;
129
+ accountCode?: unknown;
130
+ }
131
+ export interface TimeSeriesReport {
132
+ bookId: string;
133
+ metric: TimeSeriesMetric;
134
+ granularity: TimeSeriesGranularity;
135
+ from: string;
136
+ to: string;
137
+ accountCode?: string;
138
+ points: TimeSeriesPoint[];
139
+ }
140
+ export declare function getTimeSeriesReport(input: TimeSeriesReportInput, workspaceRoot?: string): Promise<TimeSeriesReport>;
141
+ export declare function rebuildSnapshots(input: {
142
+ bookId?: string;
143
+ }, workspaceRoot?: string): Promise<{
144
+ bookId: string;
145
+ rebuilt: string[];
146
+ }>;
147
+ export { aggregateBalances, balancesAtEndOf };
148
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { AccountBalance, MonthSnapshot } from "./types.js";
2
+ /** Build a snapshot at end-of-`period` for one book, lazily relying
3
+ * on the previous month's snapshot if it exists. Falls all the way
4
+ * back to the earliest journal month if no upstream snapshot is
5
+ * available. Always writes the result to disk before returning. */
6
+ export declare function getOrBuildSnapshot(bookId: string, period: string, workspaceRoot?: string): Promise<MonthSnapshot>;
7
+ /** Compute closing balances at end-of-`period` from journal alone,
8
+ * bypassing the snapshot cache. Used by the byte-equality
9
+ * invariant test, and as a safety net for "compute without
10
+ * trusting cache" paths. */
11
+ export declare function balancesAtEndOf(bookId: string, period: string, workspaceRoot?: string): Promise<AccountBalance[]>;
12
+ /** Drop snapshots for `fromPeriod` and later. Re-export from
13
+ * accounting-io for callers that conceptually live in the cache
14
+ * layer (so they don't reach into the IO module). */
15
+ export declare function invalidateSnapshotsFrom(bookId: string, fromPeriod: string, workspaceRoot?: string): Promise<{
16
+ removed: string[];
17
+ }>;
18
+ /** Drop all snapshots and rebuild from scratch. Used by the
19
+ * `rebuildSnapshots` admin action. Returns the periods that were
20
+ * rebuilt. */
21
+ export declare function rebuildAllSnapshots(bookId: string, workspaceRoot?: string): Promise<{
22
+ rebuilt: string[];
23
+ }>;
24
+ /** Schedule a background rebuild for `bookId` starting at `fromPeriod`.
25
+ * Multiple calls during an in-flight rebuild coalesce into a single
26
+ * follow-up rebuild that covers the minimum `fromPeriod` seen.
27
+ * Returns immediately — the rebuild runs on its own promise chain. */
28
+ export declare function scheduleRebuild(bookId: string, fromPeriod: string, workspaceRoot?: string): void;
29
+ /** Test/diagnostic: resolves when no rebuild is running or queued for
30
+ * `bookId`. Also called by `deleteBook` after `cancelRebuild` to
31
+ * ensure a previously running rebuild has fully stopped before the
32
+ * caller removes the book's directory on disk. */
33
+ export declare function awaitRebuildIdle(bookId: string): Promise<void>;
34
+ /** Mark the book's in-flight rebuild as cancelled. The runRebuild
35
+ * loop checks before each write and bails out, so a subsequent
36
+ * `removeBookDir` cannot race with a `writeSnapshot` that would
37
+ * re-create the directory tree. Pair with `awaitRebuildIdle(bookId)`
38
+ * to wait for the in-flight rebuild to finish bailing. */
39
+ export declare function cancelRebuild(bookId: string): void;
40
+ /** Test/diagnostic: snapshot of the per-book queue state. Stable
41
+ * enough to assert against; fields may grow over time. */
42
+ export declare function inspectRebuildQueue(bookId: string): {
43
+ running: boolean;
44
+ runningFromPeriod: string | null;
45
+ pendingFromPeriod: string | null;
46
+ coalescedWriteCount: number;
47
+ };
48
+ /** Test-only — drain all in-flight rebuilds, then drop queue state.
49
+ * Awaiting first means a leftover rebuild can't continue writing
50
+ * into the next test's tmp dir after we clear the bookkeeping. */
51
+ export declare function _resetRebuildQueueForTesting(): Promise<void>;
52
+ //# sourceMappingURL=snapshotCache.d.ts.map