arek-e-docsnap 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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +314 -0
  3. package/dist/bin/cli.d.ts +14 -0
  4. package/dist/bin/cli.d.ts.map +1 -0
  5. package/dist/cli/App.d.ts +15 -0
  6. package/dist/cli/App.d.ts.map +1 -0
  7. package/dist/cli/screens/ClassificationScreen.d.ts +13 -0
  8. package/dist/cli/screens/ClassificationScreen.d.ts.map +1 -0
  9. package/dist/cli/screens/CompleteScreen.d.ts +13 -0
  10. package/dist/cli/screens/CompleteScreen.d.ts.map +1 -0
  11. package/dist/cli/screens/PartnerSetupScreen.d.ts +8 -0
  12. package/dist/cli/screens/PartnerSetupScreen.d.ts.map +1 -0
  13. package/dist/cli/screens/SettlementPreviewScreen.d.ts +13 -0
  14. package/dist/cli/screens/SettlementPreviewScreen.d.ts.map +1 -0
  15. package/dist/cli/screens/TransactionReviewScreen.d.ts +13 -0
  16. package/dist/cli/screens/TransactionReviewScreen.d.ts.map +1 -0
  17. package/dist/cli/state.d.ts +79 -0
  18. package/dist/cli/state.d.ts.map +1 -0
  19. package/dist/cli.js +33723 -0
  20. package/dist/domain/errors.d.ts +70 -0
  21. package/dist/domain/errors.d.ts.map +1 -0
  22. package/dist/domain/models.d.ts +289 -0
  23. package/dist/domain/models.d.ts.map +1 -0
  24. package/dist/domain/settlement.d.ts +30 -0
  25. package/dist/domain/settlement.d.ts.map +1 -0
  26. package/dist/index.d.ts +18 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +312 -0
  29. package/dist/layers/config.d.ts +14 -0
  30. package/dist/layers/config.d.ts.map +1 -0
  31. package/dist/layers/filesystem.d.ts +16 -0
  32. package/dist/layers/filesystem.d.ts.map +1 -0
  33. package/dist/layers/logger.d.ts +16 -0
  34. package/dist/layers/logger.d.ts.map +1 -0
  35. package/dist/pdf.worker.mjs +28 -0
  36. package/dist/services/export.d.ts +56 -0
  37. package/dist/services/export.d.ts.map +1 -0
  38. package/dist/services/ocr-tesseract.d.ts +2 -0
  39. package/dist/services/ocr-tesseract.d.ts.map +1 -0
  40. package/dist/services/ocr.d.ts +32 -0
  41. package/dist/services/ocr.d.ts.map +1 -0
  42. package/dist/utils/compression.d.ts +31 -0
  43. package/dist/utils/compression.d.ts.map +1 -0
  44. package/dist/utils/console.d.ts +27 -0
  45. package/dist/utils/console.d.ts.map +1 -0
  46. package/dist/utils/progress.d.ts +30 -0
  47. package/dist/utils/progress.d.ts.map +1 -0
  48. package/dist/utils/transaction-parser.d.ts +41 -0
  49. package/dist/utils/transaction-parser.d.ts.map +1 -0
  50. package/package.json +95 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 arek-e
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,314 @@
1
+ # arek-e-docsnap 📸
2
+
3
+ [![npm version](https://img.shields.io/npm/v/arek-e-docsnap.svg)](https://www.npmjs.com/package/arek-e-docsnap)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Bun](https://img.shields.io/badge/Built%20with-Bun-000000.svg)](https://bun.sh)
6
+ [![Effect-TS](https://img.shields.io/badge/Powered%20by-Effect--TS-212121.svg)](https://effect.website)
7
+
8
+ Parse invoices and receipts, classify expenses, split costs between partners, and settle up automatically.
9
+
10
+ ## What It Does
11
+
12
+ Transform this 👇
13
+
14
+ ```
15
+ [Receipt PDF image: Mixed groceries, utilities, personal items]
16
+ ```
17
+
18
+ Into this 👇
19
+
20
+ ```
21
+ | Item | Amount | Buyer | Shared? |
22
+ |------------|--------|-------|---------|
23
+ | Milk | 50 SEK | Alex | Yes |
24
+ | Utilities | 800 SEK| Karin | Yes |
25
+ | Shampoo | 150 SEK| Karin | No |
26
+
27
+ 💰 SETTLEMENT:
28
+ ✓ Karin owes Alex: 425 SEK
29
+ ```
30
+
31
+ ## Features
32
+
33
+ - 📄 **OCR Magic**: Extract text from receipts/invoices automatically (Tesseract.js)
34
+ - 👥 **Multi-Partner Tracking**: Split expenses between 2+ people
35
+ - 🏷️ **Smart Classification**: Categorize expenses (groceries, utilities, shared, personal)
36
+ - 💸 **Automatic Settlement**: Calculates who owes whom
37
+ - ⌨️ **Interactive CLI**: Fast keyboard-driven interface (Ink TUI)
38
+ - 📊 **Excel Export**: Share formatted spreadsheets
39
+ - 🌍 **Multi-Language**: Works with any language invoice
40
+ - 🇸🇪 **Swedish-Ready**: Built-in support for Swedish formats
41
+ - 🛡️ **Type-Safe**: Built with Effect-TS and TypeScript
42
+ - ⚡ **Fast**: Built with Bun (3-5x faster dev)
43
+
44
+ ## Installation
45
+
46
+ ### Quick Start
47
+
48
+ ```bash
49
+ npm install -g arek-e-docsnap
50
+ docsnap receipt.pdf
51
+ ```
52
+
53
+ ### Or use with npx
54
+
55
+ ```bash
56
+ npx arek-e-docsnap receipt.pdf
57
+ ```
58
+
59
+ ### Or install locally in your project
60
+
61
+ ```bash
62
+ npm install arek-e-docsnap
63
+ npx docsnap receipt.pdf
64
+ ```
65
+
66
+ ## Quick Start Example
67
+
68
+ ```bash
69
+ # 1. Process a receipt/invoice PDF
70
+ docsnap invoice.pdf
71
+
72
+ # 2. Define partners (interactive TUI)
73
+ # → Add partners: Alice, Bob, etc.
74
+
75
+ # 3. Review extracted transactions
76
+ # → Verify OCR results
77
+
78
+ # 4. Classify each transaction
79
+ # → Assign to partners
80
+ # → Mark shared vs personal
81
+ # → Categorize (groceries, utilities, etc.)
82
+
83
+ # 5. Preview settlement
84
+ # → See who owes whom
85
+
86
+ # 6. Export to Excel
87
+ # → Press 'e' to export
88
+ # → File saved: invoice-report.xlsx
89
+ ```
90
+
91
+ ## CLI Usage
92
+
93
+ ```bash
94
+ # Basic usage (interactive mode)
95
+ docsnap receipt.pdf
96
+
97
+ # Custom output filename
98
+ docsnap receipt.pdf -o report.xlsx
99
+
100
+ # Export to CSV
101
+ docsnap receipt.pdf -o data.csv
102
+
103
+ # Export to JSON
104
+ docsnap receipt.pdf -o data.json
105
+
106
+ # Show help
107
+ docsnap --help
108
+
109
+ # Show version
110
+ docsnap --version
111
+ ```
112
+
113
+ ## TUI Keybindings
114
+
115
+ ### Partner Setup Screen
116
+ - `Enter` - Add partner
117
+ - `Backspace` - Remove character
118
+ - `Tab` - Continue to next screen
119
+
120
+ ### Transaction Review Screen
121
+ - `↑/↓` - Scroll through transactions
122
+ - `Enter` - Continue to classification
123
+
124
+ ### Classification Screen
125
+ - `↑/↓` - Select options
126
+ - `Enter` - Confirm selection
127
+ - `Tab` - Move to next field
128
+ - `Shift+Tab` - Previous field
129
+
130
+ ### Settlement Preview Screen
131
+ - `Enter` - Continue to complete
132
+ - `q` - Quit
133
+
134
+ ### Complete Screen
135
+ - `e` - Export to Excel/CSV/JSON
136
+ - `q` - Quit
137
+
138
+ ## Configuration
139
+
140
+ Future versions will support `~/.docsnap/config.json` for:
141
+ - Default partners
142
+ - Default categories
143
+ - Auto-classification rules
144
+ - Export preferences
145
+
146
+ *Currently Phase 1 MVP - configuration via TUI only*
147
+
148
+ ## API (For Developers)
149
+
150
+ ```typescript
151
+ import { Effect } from "effect";
152
+ import { processPdfToTransactions } from "arek-e-docsnap";
153
+ import { calculateSettlement } from "arek-e-docsnap";
154
+ import { exportExpenses } from "arek-e-docsnap";
155
+ import { LoggerLive } from "arek-e-docsnap";
156
+
157
+ // Step 1: Extract transactions from PDF
158
+ const pdfBuffer = readFileSync("invoice.pdf");
159
+ const extractProgram = processPdfToTransactions(pdfBuffer, {
160
+ defaultCurrency: "SEK",
161
+ minConfidence: 0.5,
162
+ });
163
+
164
+ const result = await Effect.runPromise(
165
+ Effect.provide(extractProgram, LoggerLive)
166
+ );
167
+
168
+ // Step 2: Create partners and classify items
169
+ const partners = [
170
+ { id: "alice", name: "Alice" },
171
+ { id: "bob", name: "Bob" },
172
+ ];
173
+
174
+ const items = result.transactions.map((tx, idx) => ({
175
+ id: `item-${idx}`,
176
+ date: new Date(),
177
+ description: tx.description,
178
+ amount: 10000, // in cents
179
+ currency: "SEK",
180
+ category: "Groceries",
181
+ confidence: 0.9,
182
+ partner: "alice",
183
+ isShared: true,
184
+ }));
185
+
186
+ // Step 3: Calculate settlement
187
+ const { settlements } = calculateSettlement(items, partners);
188
+
189
+ // Step 4: Export to Excel
190
+ const exportProgram = exportExpenses(
191
+ { format: "xlsx", outputPath: "report.xlsx" },
192
+ { items, partners, settlements, currency: "SEK" }
193
+ );
194
+
195
+ await Effect.runPromise(Effect.provide(exportProgram, LoggerLive));
196
+ ```
197
+
198
+ ## Troubleshooting
199
+
200
+ ### "No transactions found in PDF"
201
+
202
+ - Ensure PDF contains readable text (not just images)
203
+ - Try scanning at higher resolution
204
+ - Check PDF is not password-protected
205
+
206
+ ### Poor OCR accuracy
207
+
208
+ - Use clear, high-contrast scans
209
+ - Avoid handwritten receipts
210
+ - Try `--min-confidence 0.3` for more lenient parsing
211
+
212
+ ### Export fails
213
+
214
+ - Check you have write permissions in output directory
215
+ - Ensure output filename is valid
216
+ - Try different format: `-o report.csv` instead of `.xlsx`
217
+
218
+ ## Development
219
+
220
+ ```bash
221
+ # Install dependencies (with Bun)
222
+ bun install
223
+
224
+ # Start development
225
+ bun run dev
226
+
227
+ # Run tests
228
+ bun run test
229
+
230
+ # Format & lint with Biome
231
+ bun run format
232
+ bun run lint
233
+
234
+ # Type-check
235
+ bun run type-check
236
+
237
+ # Build for production
238
+ bun run build
239
+ ```
240
+
241
+ ## Performance
242
+
243
+ - **Single Receipt**: 3-8 seconds
244
+ - **Multi-page Invoice**: 8-15 seconds
245
+ - **Memory**: ~500 MB peak
246
+ - **OCR Accuracy**: 90-95% for clear prints
247
+
248
+ ## Roadmap
249
+
250
+ ### v0.2.0 (Weeks 8-10)
251
+
252
+ - Rule-based auto-classification
253
+ - Batch processing (multiple receipts)
254
+ - Configuration file support
255
+
256
+ ### v0.3.0 (Weeks 11-13)
257
+
258
+ - Web dashboard (React)
259
+ - Receipt photo capture
260
+ - OCR model fine-tuning
261
+
262
+ ### v1.0.0 (Production Ready)
263
+
264
+ - Stable API
265
+ - Comprehensive documentation
266
+ - Splitwise/Venmo integration (experimental)
267
+
268
+ ## Contributing
269
+
270
+ Contributions welcome! See [CONTRIBUTING.md](./docs/CONTRIBUTING.md) for guidelines.
271
+
272
+ - **Found a bug?** [Open an issue](https://github.com/arek-e/docsnap/issues)
273
+ - **Have an idea?** [Discuss in Discussions](https://github.com/arek-e/docsnap/discussions)
274
+ - **Want to code?** Fork and submit a PR!
275
+
276
+ ## Examples
277
+
278
+ See `examples/` directory for usage patterns:
279
+
280
+ - `amex-statement-parser.ts` - Specialized Amex parser
281
+ - `amex-ingestion-pipeline.ts` - Full Amex parsing workflow
282
+ - `README.md` - Examples documentation
283
+
284
+ ## Architecture
285
+
286
+ See [ARCHITECTURE.md](./docs/ARCHITECTURE.md) for technical deep-dive on:
287
+
288
+ - Effect-TS error handling (railway pattern)
289
+ - OCR optimization strategies
290
+ - Swedish language support
291
+ - Extensibility points
292
+
293
+ ## License
294
+
295
+ MIT - See [LICENSE](./LICENSE)
296
+
297
+ ## Support
298
+
299
+ - 📧 Issues: [github.com/arek-e/docsnap/issues](https://github.com/arek-e/docsnap/issues)
300
+ - 💬 Discussions: [github.com/arek-e/docsnap/discussions](https://github.com/arek-e/docsnap/discussions)
301
+ - 📝 Documentation: See `docs/` folder
302
+
303
+ ## Made with ❤️
304
+
305
+ Built with:
306
+ - [Effect-TS](https://effect.website) - Functional programming
307
+ - [Bun](https://bun.sh) - Fast TypeScript runtime
308
+ - [Ink](https://github.com/vadimdemedes/ink) - React for CLI
309
+ - [Tesseract.js](https://tesseract.projectnaptha.com/) - OCR
310
+ - [Biome](https://biomejs.dev) - Fast formatter & linter
311
+
312
+ ---
313
+
314
+ **Status**: ✅ Phase 5 Complete - MVP Ready for v0.1.0!
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI Entry Point for arek-e-docsnap
4
+ *
5
+ * Phase 5: Full workflow integration
6
+ *
7
+ * Usage:
8
+ * docsnap <pdf-file> # Interactive mode
9
+ * docsnap <pdf-file> --output report.xlsx # With custom output
10
+ * docsnap --help # Show help
11
+ * docsnap --version # Show version
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * TUI Application Entry Point
3
+ *
4
+ * Phase 3: Main Ink application with screen routing
5
+ */
6
+ import { AppState } from './state.js';
7
+ import { RawTransaction } from '../domain/models.js';
8
+ interface AppProps {
9
+ transactions: RawTransaction[];
10
+ onComplete?: (state: AppState) => void;
11
+ onExit?: () => void;
12
+ }
13
+ export declare function App({ transactions, onComplete, onExit }: AppProps): import("react/jsx-runtime").JSX.Element;
14
+ export default App;
15
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/cli/App.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,QAAQ,EAAuC,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AASrD,UAAU,QAAQ;IAChB,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,GAAG,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,QAAQ,2CA0DjE;AAED,eAAe,GAAG,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Classification Screen
3
+ *
4
+ * Phase 3.3-3.4: Classify each transaction
5
+ */
6
+ import { AppState, Action } from '../state.js';
7
+ interface Props {
8
+ state: AppState;
9
+ dispatch: (action: Action) => void;
10
+ }
11
+ export declare function ClassificationScreen({ state, dispatch }: Props): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=ClassificationScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClassificationScreen.d.ts","sourceRoot":"","sources":["../../../src/cli/screens/ClassificationScreen.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE/C,UAAU,KAAK;IACb,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAID,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAoJ9D"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Complete Screen
3
+ *
4
+ * Phase 3-4: Final screen with export options
5
+ */
6
+ import { AppState } from '../state.js';
7
+ interface Props {
8
+ state: AppState;
9
+ onExit?: () => void;
10
+ }
11
+ export declare function CompleteScreen({ state, onExit }: Props): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=CompleteScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompleteScreen.d.ts","sourceRoot":"","sources":["../../../src/cli/screens/CompleteScreen.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AASvC,UAAU,KAAK;IACb,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,2CAgJtD"}
@@ -0,0 +1,8 @@
1
+ import { AppState, Action } from '../state.js';
2
+ interface Props {
3
+ state: AppState;
4
+ dispatch: (action: Action) => void;
5
+ }
6
+ export declare function PartnerSetupScreen({ state, dispatch }: Props): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=PartnerSetupScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PartnerSetupScreen.d.ts","sourceRoot":"","sources":["../../../src/cli/screens/PartnerSetupScreen.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG/C,UAAU,KAAK;IACb,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAuG5D"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Settlement Preview Screen
3
+ *
4
+ * Phase 3.5: Show settlement calculations
5
+ */
6
+ import { AppState, Action } from '../state.js';
7
+ interface Props {
8
+ state: AppState;
9
+ dispatch: (action: Action) => void;
10
+ }
11
+ export declare function SettlementPreviewScreen({ state, dispatch }: Props): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=SettlementPreviewScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettlementPreviewScreen.d.ts","sourceRoot":"","sources":["../../../src/cli/screens/SettlementPreviewScreen.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAM/C,UAAU,KAAK;IACb,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,uBAAuB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAsHjE"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Transaction Review Screen
3
+ *
4
+ * Phase 3: Show all extracted transactions before classification
5
+ */
6
+ import { AppState, Action } from '../state.js';
7
+ interface Props {
8
+ state: AppState;
9
+ dispatch: (action: Action) => void;
10
+ }
11
+ export declare function TransactionReviewScreen({ state, dispatch }: Props): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=TransactionReviewScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactionReviewScreen.d.ts","sourceRoot":"","sources":["../../../src/cli/screens/TransactionReviewScreen.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE/C,UAAU,KAAK;IACb,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,uBAAuB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAkDjE"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * TUI Application State
3
+ *
4
+ * Phase 3: State management for the TUI classifier
5
+ * Uses a simple state machine pattern
6
+ */
7
+ import { Partner, RawTransaction, ExpenseItem } from '../domain/models';
8
+ /**
9
+ * Application screens/steps
10
+ */
11
+ export type Screen = 'partner-setup' | 'transaction-review' | 'classification' | 'settlement-preview' | 'complete';
12
+ /**
13
+ * Classification state for a transaction
14
+ */
15
+ export interface TransactionClassification {
16
+ transaction: RawTransaction;
17
+ partnerId?: string;
18
+ category?: string;
19
+ isShared: boolean;
20
+ }
21
+ /**
22
+ * Global application state
23
+ */
24
+ export interface AppState {
25
+ currentScreen: Screen;
26
+ partners: Partner[];
27
+ transactions: RawTransaction[];
28
+ classifications: Map<string, TransactionClassification>;
29
+ currentTransactionIndex: number;
30
+ categories: string[];
31
+ currency: 'SEK' | 'EUR' | 'USD' | 'CHF';
32
+ expenseItems?: ExpenseItem[];
33
+ }
34
+ /**
35
+ * Actions to modify state
36
+ */
37
+ export type Action = {
38
+ type: 'ADD_PARTNER';
39
+ partner: Partner;
40
+ } | {
41
+ type: 'REMOVE_PARTNER';
42
+ partnerId: string;
43
+ } | {
44
+ type: 'SET_PARTNERS';
45
+ partners: Partner[];
46
+ } | {
47
+ type: 'NEXT_SCREEN';
48
+ } | {
49
+ type: 'PREVIOUS_SCREEN';
50
+ } | {
51
+ type: 'GO_TO_SCREEN';
52
+ screen: Screen;
53
+ } | {
54
+ type: 'CLASSIFY_TRANSACTION';
55
+ transactionId: string;
56
+ classification: Partial<TransactionClassification>;
57
+ } | {
58
+ type: 'NEXT_TRANSACTION';
59
+ } | {
60
+ type: 'PREVIOUS_TRANSACTION';
61
+ } | {
62
+ type: 'SET_TRANSACTIONS';
63
+ transactions: RawTransaction[];
64
+ } | {
65
+ type: 'ADD_CATEGORY';
66
+ category: string;
67
+ } | {
68
+ type: 'SET_EXPENSE_ITEMS';
69
+ items: ExpenseItem[];
70
+ };
71
+ /**
72
+ * Create initial application state
73
+ */
74
+ export declare function createInitialState(): AppState;
75
+ /**
76
+ * State reducer (pure function)
77
+ */
78
+ export declare function reducer(state: AppState, action: Action): AppState;
79
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/cli/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,MAAM,GACd,eAAe,GACf,oBAAoB,GACpB,gBAAgB,GAChB,oBAAoB,GACpB,UAAU,CAAC;AAEf;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,cAAc,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IAEvB,aAAa,EAAE,MAAM,CAAC;IAGtB,QAAQ,EAAE,OAAO,EAAE,CAAC;IAGpB,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IAGxD,uBAAuB,EAAE,MAAM,CAAC;IAGhC,UAAU,EAAE,MAAM,EAAE,CAAC;IAGrB,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IAGxC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,MAAM,MAAM,GACd;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAA;CAAE,GAC3G;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,YAAY,EAAE,cAAc,EAAE,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAExD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,QAAQ,CAmB7C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CA6GjE"}