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.
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/dist/bin/cli.d.ts +14 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/cli/App.d.ts +15 -0
- package/dist/cli/App.d.ts.map +1 -0
- package/dist/cli/screens/ClassificationScreen.d.ts +13 -0
- package/dist/cli/screens/ClassificationScreen.d.ts.map +1 -0
- package/dist/cli/screens/CompleteScreen.d.ts +13 -0
- package/dist/cli/screens/CompleteScreen.d.ts.map +1 -0
- package/dist/cli/screens/PartnerSetupScreen.d.ts +8 -0
- package/dist/cli/screens/PartnerSetupScreen.d.ts.map +1 -0
- package/dist/cli/screens/SettlementPreviewScreen.d.ts +13 -0
- package/dist/cli/screens/SettlementPreviewScreen.d.ts.map +1 -0
- package/dist/cli/screens/TransactionReviewScreen.d.ts +13 -0
- package/dist/cli/screens/TransactionReviewScreen.d.ts.map +1 -0
- package/dist/cli/state.d.ts +79 -0
- package/dist/cli/state.d.ts.map +1 -0
- package/dist/cli.js +33723 -0
- package/dist/domain/errors.d.ts +70 -0
- package/dist/domain/errors.d.ts.map +1 -0
- package/dist/domain/models.d.ts +289 -0
- package/dist/domain/models.d.ts.map +1 -0
- package/dist/domain/settlement.d.ts +30 -0
- package/dist/domain/settlement.d.ts.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +312 -0
- package/dist/layers/config.d.ts +14 -0
- package/dist/layers/config.d.ts.map +1 -0
- package/dist/layers/filesystem.d.ts +16 -0
- package/dist/layers/filesystem.d.ts.map +1 -0
- package/dist/layers/logger.d.ts +16 -0
- package/dist/layers/logger.d.ts.map +1 -0
- package/dist/pdf.worker.mjs +28 -0
- package/dist/services/export.d.ts +56 -0
- package/dist/services/export.d.ts.map +1 -0
- package/dist/services/ocr-tesseract.d.ts +2 -0
- package/dist/services/ocr-tesseract.d.ts.map +1 -0
- package/dist/services/ocr.d.ts +32 -0
- package/dist/services/ocr.d.ts.map +1 -0
- package/dist/utils/compression.d.ts +31 -0
- package/dist/utils/compression.d.ts.map +1 -0
- package/dist/utils/console.d.ts +27 -0
- package/dist/utils/console.d.ts.map +1 -0
- package/dist/utils/progress.d.ts +30 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/transaction-parser.d.ts +41 -0
- package/dist/utils/transaction-parser.d.ts.map +1 -0
- 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
|
+
[](https://www.npmjs.com/package/arek-e-docsnap)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://bun.sh)
|
|
6
|
+
[](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"}
|