49 Commits

Author SHA1 Message Date
Vasily Zubarev
5a5deb4598 fix: pricing 2026-06-19 10:35:49 +02:00
Vasily Zubarev
f22bab5236 feat: enable saas subscription 2026-06-19 10:33:29 +02:00
Vasily Zubarev
0bed4a6e84 feat: new app - email/smtp listener (#102)
* feat: initial email impl

* feat: IMAP email ingest (builds on the scaffold) (#100)

* chore: add imap-simple, mailparser, vitest

* feat: AES-256-GCM helpers for email credentials

* feat: extract ingestUnsortedFile helper, reuse in upload action

* chore: gitignore .worktrees/

* feat: email-sync types and pure attachment/search filters

* feat: imap-simple + mailparser client wrapper

* feat: email sync orchestration with UID watermark + status persistence

* feat: encrypt email credentials at rest, add UID/addedAt fields

* feat: real IMAP test-connection, scoped sync-now, thin cron entry

* docs: update email app README to match real IMAP/encryption/UID behavior

* fix: nest SINCE search criteria and guard missing addedAt for first-run sync

* fix: show last-sync time and error detail from sync in server card

* fix: skip storage recompute when no attachments ingested

Avoids an ENOENT crash on first sync when the user's uploads dir does not exist yet and nothing was ingested; this was also masking the real per-server error. Adds regression tests for the guard.

* feat: configurable initial-grab window (fetch-since date)

First sync is bounded by a user-chosen 'Fetch emails since' date instead of the server's addedAt; blank = entire mailbox (IMAP ALL). The UID watermark takes over after the first run.

* fix: add missing @langchain/core dependency

@langchain/core is only a peer dep of the @langchain/* packages and was not installed on a clean npm install, breaking the build (e.g. /unsorted via ai/analyze).

* fix: harden email sync — UID dedup guard, locked status write, graceful decrypt, scrypt memo

Addresses review findings: skip messages at/below the UID watermark (defends against the IMAP `n:*` re-fetch quirk); lock the app_data row with SELECT FOR UPDATE so concurrent cron/manual syncs can't clobber each other; return a friendly error when a stored password can't be decrypted (e.g. after BETTER_AUTH_SECRET rotation) and document the coupling; memoize the scrypt-derived key.

* feat: enforce per-server syncInterval on cron; skip non-Buffer attachments

The cron now honors each server's syncInterval (manual Sync Now bypasses the throttle), so the configured interval is no longer ignored. Attachments whose parsed content is not a Buffer are skipped instead of throwing on .length. Adds throttle regression tests.

* refactor: remove dead lastProcessedMessageId field; clarify cron throttle in README

lastProcessedMessageId was superseded by the lastProcessedUid watermark and never read; dropped from the type and form state. README now describes the per-server interval as an app-level throttle (manual Sync Now bypasses).

* feat(email): UI-selectable sync frequency + working cron heartbeat

Replace the per-server sync-interval number input with a dropdown of
presets (15m/30m/hourly/6h/12h/daily). Switch the stored unit from hours
to minutes and update the throttle accordingly.

Make the cron actually run: heartbeat now fires every 5 minutes as the
resolution floor while each mailbox's UI frequency gates real fetches.
Propagate env into cron jobs via /etc/cron.env (cron strips the
environment) and add BETTER_AUTH_SECRET to the email-sync service in the
dev/build compose files so stored passwords can be decrypted.

* fix(email): reset Add Server dialog to provider selection on close

Radix's onOpenChange only toggled isOpen, so closing the dialog via Esc,
overlay click, or the X left the step/selectedProvider state intact.
Reopening then jumped straight to the previous provider's config form
instead of the provider-selection screen. Route every close through
handleClose() to reset the step.

---------

Co-authored-by: Evgenii Burmakin <Freika@users.noreply.github.com>
2026-06-18 23:30:38 +02:00
deepakdroi
a7c4528e03 feat: implement smart transaction deduplication and resolution workflow (#92) (#93)
* feat: add transaction deduplication with side-by-side comparison modal

* feat: implement three-way duplicate resolution logic

- Add Row-Level check (Merchant/Total/Currency/Date) to Transaction model.
- Implement side-by-side comparison modal with Older/Newer/Both options.
- Update AI and CSV workflows to intercept duplicates.

Closes #92

* fix: include currency code and fallback in transaction deduplication check

Closes #92

* refactor(transactions): separate deduplication logic from creation model

- Extracted duplicate checking into a dedicated `findDuplicateTransaction` method in `models/transactions.ts`
- Restored `createTransaction` to a pure, atomic database insertion to remove unexpected side effects
- Updated all server actions (createTransactionAction, saveInvoice, saveFile, saveTransactions) to orchestrate the duplication check before calling the creation model

Addresses reviewer feedback to separate concerns and maintain clean model methods.
2026-04-17 12:05:20 +02:00
Vasily Zubarev
c8236f134a chore: LLM descriptions 2026-04-03 23:08:37 +02:00
MaxP
8bcbf403d5 feat: add OpenAI Compatible LLM provider for local models (#81)
Support Ollama, LM Studio, vLLM, and any OpenAI-compatible API
  via a configurable base URL. Reuses ChatOpenAI with custom baseURL,
  no new dependencies. Local models use direct JSON parsing instead
  of withStructuredOutput since many don't support function calling.

Co-authored-by: FasterOP <7832832+mmplisskin@useres.noreply.github.com>
2026-03-31 10:43:58 +02:00
Vasily Zubarev
bdda4ad720 fix: OTP codes generation 2026-01-25 15:14:08 +01:00
Vasily Zubarev
3d90c50ece Revert "fix: try fixing OTP ids again =/"
This reverts commit 1a987fe75f.
2026-01-25 15:12:58 +01:00
Vasily Zubarev
1a987fe75f fix: try fixing OTP ids again =/ 2026-01-25 14:56:06 +01:00
Artem Sushchev
f7cec371fc fix: remove generateId: false to fix OTP UUID generation errors (#56)
Removes the generateId: false setting from Better Auth config that was causing UUID generation errors when creating OTP verification records.

According to Better Auth documentation, generateId: false should only be used for auto-increment ID schemas. For UUID-based schemas, Better Auth should generate UUIDs using crypto.randomUUID().

This fixes the 'Failed to send the code' error during OTP email verification.
2026-01-12 09:07:05 +01:00
Artem Sushchev
3223d5026b feat: display both net total and turnover in transactions footer (#53)
- Add calcNetTotalPerCurrency function to calculate signed totals (income positive, expenses negative)
- Update transaction list footer to display both net total and turnover
- Use semantic HTML markup (<dl>, <dt>, <dd>) for better accessibility
- Add color coding: green for positive net, red for negative net
- Maintain turnover calculation for total transaction volume

Fixes issue where transaction totals did not respect transaction type (income/expense)
2025-10-22 09:28:19 +02:00
Dmitrii Anfimov
e4e7076f9e feat: visual color picker (#43)
* feat: visual color picker

* feat: use pallete for random colors

* fix: style issues like indentation in code and different color format
2025-08-13 10:22:19 +02:00
Vasily Zubarev
7aa9d25275 fix: use short month names 2025-08-02 22:00:59 +02:00
Vasily Zubarev
280adabc71 fix #37: monthly expense charts
:
2025-08-02 21:28:47 +02:00
Vasily Zubarev
070891515b feat: update landing page with current screenshots 2025-07-23 14:29:13 +02:00
Dmitrii Anfimov
dee915ffd6 feat: more llm provider options (google, mistral) (#28)
* feat: add google provider

* fix: default for google model

* feat: multiple providers

* fix: defaults from env for login form

* fix: add mistral to env files

* chore: delete unused code

* chore: revert database url to original

* fix: render default value for api key from env on server

* fix: type errors during compilation

---------

Co-authored-by: Vasily Zubarev <me@vas3k.ru>
2025-07-22 21:49:54 +02:00
Vasily Zubarev
9903325f17 fix: session expires too fast 2025-07-22 21:28:04 +02:00
vas3k
25c61f0519 feat: split into multiple items 2025-05-23 14:33:40 +02:00
vas3k
347cf2a0e8 feat: analyze all button, support for UTF8 filenames 2025-05-22 19:22:30 +02:00
vas3k
312587d5b3 fix: longer cookie age 2025-05-21 14:19:19 +02:00
vas3k
c352f5eadd fix: restore from backup, restart button for tools, loader for fields 2025-05-20 20:37:26 +02:00
Vasily Zubarev
ee368180f6 fix: wording 2025-05-12 20:25:33 +02:00
Vasily Zubarev
8b5a2e8056 feat: invoice generator 2025-05-07 14:53:13 +02:00
Vasily Zubarev
26991a1520 ci: use local prisma client 2025-05-03 10:23:13 +02:00
Vasily Zubarev
69bc4b3889 fix: ai balance for unlimited plan 2025-05-03 09:48:38 +02:00
Vasily Zubarev
6c3641c469 chore: better configs 2025-05-02 11:47:36 +02:00
Vasily Zubarev
088d596480 feat: activate live pricing 2025-04-24 20:19:57 +02:00
Vasily Zubarev
b4045930e2 feat: activate saas 2025-04-24 19:46:56 +02:00
Vasily Zubarev
fd142762af chore: add support email 2025-04-24 17:02:14 +02:00
Vasily Zubarev
abd5ad8403 feat: stripe integration 2025-04-24 15:27:44 +02:00
Vasily Zubarev
9809e05453 fix: fetch session profile from DB 2025-04-22 14:43:45 +02:00
Vasily Zubarev
73e83221b8 feat: storage and token limiting 2025-04-21 13:50:45 +02:00
Vasily Zubarev
62bad46e58 feat: calculate used storage 2025-04-10 15:14:54 +02:00
Vasily Zubarev
29a4ac4977 fix: currency converter and auth apis 2025-04-09 15:04:48 +02:00
Vasily Zubarev
416c45d08c chore: organize ts types, fix eslint errors 2025-04-09 12:45:56 +02:00
Vasily Zubarev
48cb9c50cb feat: safer backups 2025-04-04 14:52:48 +02:00
Vasily Zubarev
1b1d72b22d feat: add auth and cache to currency route 2025-04-04 14:01:43 +02:00
Vasily Zubarev
1bb6447141 feat: move currency converter to server 2025-04-04 13:49:51 +02:00
Vasily Zubarev
bd6cd2c25c fix: layout improvements 2025-04-04 13:36:03 +02:00
Vasily Zubarev
1d53434f94 fix: small adjustments before v0.5 2025-04-04 11:39:02 +02:00
Vasily Zubarev
bfac59133b fix: set baseURL for production deploy 2025-04-03 17:10:26 +02:00
Vasily Zubarev
d8711b7142 fix: pre-production fixes, add docker-compose.production.yml 2025-04-03 15:43:37 +02:00
Vasily Zubarev
144e67dfa5 fix: resend api key fails build time 2025-04-03 14:59:50 +02:00
Vasily Zubarev
f1a26e511e feat: config.js 2025-04-03 14:36:16 +02:00
Vasily Zubarev
f523b1f8ba BREAKING: postgres + saas 2025-04-03 13:07:54 +02:00
Vasily Zubarev
dc45fc23f4 feat:: more robust backup 2025-03-22 12:50:29 +01:00
Vasily Zubarev
f6dc617eae feat: use structured output, import CSV, bugfixes 2025-03-21 18:42:14 +01:00
Vasily Zubarev
14967e1c85 feat: bugfixes, spedup, bulk actions, 2025-03-17 18:36:25 +01:00
Vasily Zubarev
0b98a2c307 (squash) init
feat: filters, settings, backups

fix: ts compile errors

feat: new dashboard, webp previews and settings

feat: use webp for pdfs

feat: use webp

fix: analyze resets old data

fix: switch to corsproxy

fix: switch to free cors

fix: max upload limit

fix: currency conversion

feat: transaction export

fix: currency conversion

feat: refactor settings actions

feat: new loader

feat: README + LICENSE

doc: update readme

doc: update readme

doc: update readme

doc: update screenshots

ci: bump prisma
2025-03-16 21:29:20 +01:00