Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기A project for ZZPers in NL
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Bookkeeping Admin is a local-first bookkeeping tool for independent professionals and small service businesses in the Netherlands. It covers billing profiles, invoices, expenses, receipts, and quarterly BTW/VAT summaries without requiring a subscription product or a hosted backend.README 전문 보기 ↗Bookkeeping Admin is a local-first bookkeeping tool for independent professionals and small service businesses in the Netherlands. It covers billing profiles, invoices, expenses, receipts, and quarterly BTW/VAT summaries without requiring a subscription product or a hosted backend.
I started this project after beginning independent consulting work in the Netherlands and realizing that my bookkeeping workflow felt more complicated than it should. Existing tools were often capable products, but they did not match the experience I wanted: some felt too advanced, some too limited, some visually uninspiring, and many required an ongoing subscription.
I wanted something simpler, more focused, and more aligned with my own way of working. I also wanted to use the project to demonstrate a practical AI-assisted delivery workflow: as a PM, I used OpenAI and Codex to shape requirements, iterate on UX details, and ship a working product that I can continue improving.
This is intentionally not a full accounting platform.
The current version is designed around a narrower idea:
That tradeoff keeps the product lightweight, inexpensive to run, and well scoped as a portfolio project.
Home: quick access to the main flowsInvoices: build invoices from saved profiles, calculate VAT from hours and rate, export a one-page PDF, and manage everything in a sortable table with paid/overdue statusProfiles: reusable sender and client billing details, including a letterheadExpenses: log costs, VAT rates and receipts, filtered by yearVAT Summary: net BTW per quarter, with each quarter markable as filed and paid so the headline shows what is still owedFinance: import a bank CSV from one or more accounts and see where the money comes from and goes, what is a fixed commitment versus flexible spending, and where the year lands. Money moved between your own accounts is never counted as either, and the figures reconcile against the balance your bank printed — parsed in the browser, never uploadedBelastingdienst: the whole tax year — receivables, VAT, an income tax estimate with every step shown, and a projection to 31 DecemberLanguage: full NL/EN switch; English shows Dutch tax terms alongside, since those are the words on the actual formsTheme: light and dark, following your system by default with a manual overrideSettings: passphrase and recovery code, auto-lock, bank accounts, backup and restore, AI importEncryption: set a passphrase and everything in the browser is encrypted at rest — see docs/SECURITY.mdLocal persistence: everything stored in browser localStorageBackup & restore: export all data to JSON, and merge or replace it backSetting a passphrase encrypts everything stored in the browser. A random data key encrypts the records, and that key is wrapped separately by your passphrase and by a recovery code, so either opens the vault and neither can be derived from the other. Nothing stores the passphrase, the recovery code or the data key — which is why there is no password reset, and cannot be one.
The design, its parameters, and an honest account of what it does not protect against are in docs/SECURITY.md.
It is opt-in: the app is fully usable without a passphrase, because switching it on is irreversible in the way that matters. Lose both the passphrase and the recovery code and the data is gone.
All data lives in this browser's localStorage and nowhere else. That keeps the app
private and backend-free, but it also means clearing site data, switching browsers or
using a different browser profile will lose everything.
An optional public/seed/backfill.json (gitignored) is applied once on first load, so a
prepared set of books can be loaded without hand entry. It holds real bookkeeping data
and must never be committed.
Bank statements are parsed in the browser and stored locally like everything else;
nothing is uploaded. The free-text notification field is dropped on import because it
carries partial card numbers. *.csv is gitignored so an export cannot be committed
by accident.
The AI import panel currently keeps its API key in localStorage. That is acceptable on
a personal machine and not acceptable hosted — moving extraction behind a server
route is a prerequisite for launch.
BTW figures do not model reverse-charge (BTW verlegd), the small business scheme
(KOR) or intra-EU supplies, and the income tax estimate ships with editable default
rates that should be checked against belastingdienst.nl. Neither is tax advice.
All figures below are fictional demo data, not real bookkeeping.
Quick access to the main flows, with backup and AI-assisted import below.
Saved invoices as a sortable table: select rows to download their PDFs in bulk, mark paid inline, and read the column totals in the closing row.
Import a bank statement and the year is laid out: where money comes from and where it goes, what is a fixed commitment versus flexible spending, and where 31 December lands. Clicking any figure opens the transactions behind it. What the rules cannot place is grouped by merchant, so one decision files every transaction from it.
The screenshot predates the income panel added later.
The tax year in one view — receivables, net VAT per quarter, and a projection to 31 December with the income tax estimate broken down step by step. Shown in dark mode; the app follows your system setting and can be overridden.
.
├── app/
│ ├── belastingdienst/page.tsx Tax year overview, charts, income tax estimate
│ ├── btw-summary/page.tsx Quarterly VAT, with settled-quarter tracking
│ ├── clients/page.tsx Billing profile management
│ ├── expenses/page.tsx Expense and receipt tracking
│ ├── finance/page.tsx Bank import, income and spending, year projection
│ ├── invoices/page.tsx Invoice builder, preview and PDF export
│ ├── settings/page.tsx Passphrase, backups, AI import
│ ├── components/
│ │ ├── AiImportPanel.tsx AI-assisted import (preview; provider not wired)
│ │ ├── BackupPanel.tsx Export / restore bookkeeping data
│ │ ├── ConfirmDelete.tsx Confirmation that can be switched off for good
│ │ ├── InvoiceTable.tsx Sortable invoice table with row actions
│ │ ├── NavTabs.tsx Navigation and language control
│ │ ├── SeedLoader.tsx One-time local backfill from /seed
│ │ ├── ThemeToggle.tsx Light / dark / system
│ │ ├── TransactionDrawer.tsx Paged list behind a figure
│ │ ├── VaultGate.tsx Lock screen, setup, recovery code, auto-lock
│ │ ├── VaultSettings.tsx Change passphrase, reissue code, turn off
│ │ └── charts.tsx Inline SVG donut, bars and projection
│ ├── not-found.tsx 404
│ ├── layout.tsx Shared app shell
│ ├── page.tsx Home
│ └── globals.css Design tokens for light and dark
├── docs/
│ ├── OPEN-ITEMS.md Engineering debt and blockers
│ └── SECURITY.md How the encryption works, and what it does not do
├── lib/
│ ├── ai-import.ts Extraction contract and provider seam
│ ├── backup.ts Backup export, validation and restore
│ ├── bank.ts Bank CSV parsing, dedupe and merge
│ ├── billing.ts Shared billing types and money helpers
│ ├── categories.ts Spending categories and the rules that assign them
│ ├── crypto.ts Vault cryptography
│ ├── crypto.test.ts Tests for it
│ ├── finance.ts Spending aggregation, recurrence, projection
│ ├── i18n.ts NL/EN dictionary
│ ├── local-storage.ts Storage hook, vault-aware
│ ├── tax.ts ZZP income tax estimate and BTW deadlines
│ └── vault.ts In-memory vault, migration, lock/unlock
├── public/ Static assets
└── README.md
| Layer | Technology | Purpose |
|---|---|---|
| App framework | Next.js 16 | App shell, routing, build tooling |
| UI | React 19 | Client-side UI and stateful forms |
| Language | TypeScript | Type safety across app logic |
| Styling | Tailwind CSS 4 | Layout and visual styling |
| Persistence | localStorage | Local-first data storage in the browser |
| Encryption | WebCrypto | AES-GCM and PBKDF2 from the platform; no dependency handles keys |
| Tests | node:test | Built in; Node runs the TypeScript directly, no test framework |
| Charts | inline SVG | No charting dependency; colours validated for contrast and colourblind separation |
| Tooling | ESLint | Basic code quality checks |
This project is also a practical exploration of AI-assisted product development.
I used AI assistants (initially OpenAI and Codex, more recently Claude Code) to:
The goal was not just to generate code, but to use AI as part of a real product delivery workflow: moving from a personal problem to a working, testable product.
This version does not use a backend database. Data is stored locally in the browser/device running the app.
That means:
For this stage of the project, that is a deliberate product choice rather than a missing feature.
Install dependencies and start the development server:
npm install
npm run dev
Open http://localhost:3000 in your browser.
Available scripts:
npm run dev
npm run lint
npm run build
npm run start
npm test # the vault crypto tests
The simplest deployment path is Vercel. The app works well as a public demo because it does not depend on a backend database in its current form.
1. Sync, encrypted end to end. The vault is local, so laptop and phone are still separate islands and moving between them means exporting and restoring a file by hand. The encrypted blob is already the right shape to sync; what is missing is somewhere to put it and an account identity to put it under. The server would hold ciphertext it cannot read, which is the only version of sync consistent with how this app treats data. Needs a decision on storage, and it is the first thing here to require a service account.
2. AI import. Extraction moves behind a server route so the API key never sits in the browser, closing the standing security gap. That unlocks categorising the long tail of small local merchants no rule list can cover, and PDF statements. Second because an AI feature on an app with no accounts is the roof before the walls.
3. Then: MT940/CAMT imports, matching bank transactions against invoices so unpaid work reconciles itself, the business/private flag that pushes a deductible cost straight into the tax picture, and multiple line items per invoice.
The lock and setup screens are functional rather than designed, there is no passphrase strength hint, and errors are plain red text. Listed here rather than quietly left, because they are the first thing anyone else would meet.
Invoices and BTW are one corner of a freelancer's finances. The same local-first, privacy-conscious foundation extends naturally to the rest of it, as separate tabs over a shared ledger:
eigenwoningforfait, mortgage
interest deduction).Two principles should survive that expansion. Nothing is invented — an estimate is always shown with the arithmetic behind it, as the income tax breakdown already is. And anything sensitive stays on the user's machine unless they explicitly choose otherwise; a hosted version needs a real backend and auth story before it holds anyone's bank data.
Encryption landed first, deliberately: it means a backend can be added later without the server ever being able to read what it stores. What is still missing is the storage itself and an account identity — see "Next" above.
This project demonstrates:
Bookkeeping Admin is an active portfolio and learning project. The current version is usable as a local-first bookkeeping tool and will continue to evolve through iterative improvements.
Small improvements and documentation updates are committed as the product evolves.