157 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
Evgenii Burmakin
25f46de032 fix: repair Docker build (lockfile sync + email type deps) (#103)
The GHCR Docker build was failing on `npm ci` because package-lock.json
was out of sync with package.json (the lock was generated with npm 11 /
Node 24, while the build image node:23-slim ships npm 10.9, which rejects
the inconsistent optional-dependency entries for esbuild/webpack/picomatch).

Regenerating the lock with npm 10.9 unmasked two further pre-existing
build failures, both caused by `next build` running under the Dockerfile's
NODE_ENV=production (which makes `npm ci` omit devDependencies):

- @types/imap and @types/mailparser were in devDependencies, so they were
  absent during the production build and the type-check failed on the
  mailparser/imap-simple imports. Moved them to dependencies, matching the
  existing convention already used for @types/mime-types and @types/sharp.
- vitest.config.ts and the *.test.ts files import the vitest devDependency,
  which next build type-checked and could not resolve. Excluded them from
  tsconfig so the production build does not type-check test files.

Verified by building the image end-to-end (linux/amd64) with node:23-slim:
npm ci, npm run build, and image export all succeed.
2026-06-19 07:40:35 +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
44d8e633cc fix: show LLM choice only in self-hosted mode 2026-04-04 15:39:36 +02:00
Vasily Zubarev
f4996026cf fix: show LLM choice only in self-hosted mode 2026-04-04 14:09:43 +02:00
ekkoitac
861e9f236c fix: prevent path traversal in deleteFile (SEC-75) (#86)
Use UPLOAD_PATH as base and verify resolved path stays within it,
preventing arbitrary file deletion via malicious DB path values.

Co-authored-by: OpenClaw Agent <agent@openclaw.ai>
2026-04-03 23:53:58 +02:00
Vasily Zubarev
27575cc07e chore: README v0.7.0 2026-04-03 23:34:29 +02:00
Vasily Zubarev
bcf92d6e9e chore: add local LLMs to readme 2026-04-03 23:21:02 +02:00
Vasily Zubarev
c8236f134a chore: LLM descriptions 2026-04-03 23:08:37 +02:00
Vasily Zubarev
36e2a81d8c chore: CV 2026-04-03 22:37:26 +02:00
deepakdroi
6e25d89acc fix #78: turnover calculation (#90)
* git commit -m "fix: calculate turnover using only income transactions (#78)"

* fix #78: Refactor turnover calculation for income transactions
2026-04-02 10:16:01 +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
94a94dbb34 chore: add cv to readme 2026-03-23 16:14:15 +01:00
Vasily Zubarev
9cd13ad2ee fix: missing export button v0.6.1 2026-03-12 16:07:55 +01: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
Vasily Zubarev
1aad6aac93 fix: link import 2025-12-16 09:57:29 +01:00
Vasily Zubarev
bd79a42a49 feat: disable saas version 2025-12-16 09:48:06 +01:00
Vasily Zubarev
d2d62fffd1 hotfix: disable nextjs image optim feature 2025-12-08 20:43:47 +01:00
Vasily Zubarev
e85a3b960c fix: next.js vulnerability 2025-12-06 20:18:06 +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
Artem Sushchev
07e05aabe7 fix: show friendly error when duplicate category code exists (handle Prisma P2002) (#49) 2025-09-25 12:14:11 +02:00
Artem Sushchev
24a2cfc729 feat: Accessibility Fixes for Custom Field Forms (#48)
* fix: add IDs and ARIA labels to custom field forms

- Add id propagation to FormInput/FormTextarea based on name prop for proper label association
- Enhance FormSelect with hidden input for form submission, aria-labelledby for labeling, and controlled/uncontrolled state management
- Add aria-label attributes to inline inputs/selects/checkboxes in CrudTable settings editor

These changes improve accessibility for screen readers and ensure custom field forms are fully navigable via keyboard. Also critical for AI browsers like Comet that rely on semantic HTML/ARIA for form parsing and automation.

* fix: add aria-labels to CRUD table action buttons

- Add aria-label to edit buttons: 'Edit [item name]'
- Add aria-label to delete buttons: 'Delete [item name]'
- Add aria-label to save/cancel buttons in edit/add modes
- Add aria-label to 'Add New' button

Fixes unlabeled icon buttons that were inaccessible to screen readers and AI browsers.
2025-09-25 12:13:10 +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
a5a2e3053b fix: video demo in readme 2025-07-23 19:01:20 +02:00
Vasily Zubarev
3294e1a9a5 chore: update readme and landing texts v0.6 v0.6.0 2025-07-23 16:03:42 +02:00
Vasily Zubarev
d0b0c7546e fix: default LLM prompt 2025-07-23 14:30:46 +02:00
Vasily Zubarev
070891515b feat: update landing page with current screenshots 2025-07-23 14:29:13 +02:00
Vasily Zubarev
9305deda86 feat: add more colors to cards 2025-07-23 11:07:51 +02:00
Vasily Zubarev
8897134901 chore: bump package versions + fix linter 2025-07-23 10:34:49 +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
dependabot[bot]
97b4b3b6bf chore(deps): bump better-auth (#29)
Bumps the npm_and_yarn group with 1 update in the / directory: [better-auth](https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth).


Updates `better-auth` from 1.2.5 to 1.2.10
- [Release notes](https://github.com/better-auth/better-auth/releases)
- [Commits](https://github.com/better-auth/better-auth/commits/v1.2.10/packages/better-auth)

---
updated-dependencies:
- dependency-name: better-auth
  dependency-version: 1.2.10
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-21 10:21:35 +02:00
Vasily Zubarev
8f7c4a4d61 fix #30: individual items are not saved
"
2025-07-14 08:59:50 +02:00
vas3k
b32421f114 fix: styles and texts 2025-05-23 21:29:51 +02:00
vas3k
ca7d206b07 fix: errors on saving transactions 2025-05-23 14:59:12 +02:00
vas3k
25c61f0519 feat: split into multiple items 2025-05-23 14:33:40 +02:00
vas3k
289b436236 fix #23: allow empty convertedTotal 2025-05-22 19:42:41 +02:00
vas3k
347cf2a0e8 feat: analyze all button, support for UTF8 filenames 2025-05-22 19:22:30 +02:00
vas3k
feb56fa3ac fix: check db initialisation on getOrCreateCloudUser 2025-05-22 18:26:19 +02:00
vas3k
c0966ab327 fix: always lowercase user email 2025-05-22 17:11:33 +02:00
vas3k
3976db1114 fix: better webhook error handling 2025-05-22 17:04:19 +02:00
vas3k
da16558298 fix: webhook events 2025-05-22 16:37:51 +02:00
vas3k
312587d5b3 fix: longer cookie age 2025-05-21 14:19:19 +02:00