Commit Graph

12 Commits

Author SHA1 Message Date
Víctor Falcón 8056ede636
feat(ai): suggest automation rules during onboarding (#523)
Suggests transaction categorization rules during onboarding.

After a sync or import, it groups the uncategorized transactions, asks
Gemini (via laravel/ai) to map the common merchants to categories, and
shows the results for review. The user edits or drops any and creates
the ones they want. During onboarding the accepted rules also categorize
existing transactions right away.

Off by default: it needs the `AiRuleSuggestions` Pennant flag and a
per-user AI consent. The model and thresholds are config-driven.
`ai:suggest-rules {user}` prints what a user would get.

The settings-page surface and monthly regeneration are a follow-up.
2026-06-13 22:51:15 +02:00
Víctor Falcón e526f861b2
fix(automation-rules): hint amount sign for expenses vs income (#524)
## Problem

A user reported automation rules not applying. The rule matched a
description **and** `Valor es igual a 21,99`, but never fired.

Root cause: the matching engine evaluates the **signed** transaction
amount (`amount / 100`), and expenses are stored negative. So an expense
of `-21,99` is compared as `-21.99 == 21.99` → false. The rule editor
showed a plain number input with no hint about the sign convention, so
entering a positive `21,99` to match an expense silently builds a rule
that can never match.

This is a common trap — likely affecting many users with amount-based
rules.

## Change

Add a small helper note under the numeric `amount`/`Valor` value input:

> Usa un valor negativo para gastos (ej. -21,99) y un valor positivo
para ingresos.

- Renders only for the numeric `amount` field; text conditions are
unaffected.
- No change to how rules are stored or evaluated — existing rules keep
working.
- Added the Spanish translation key (`es.json` is CI-enforced).

## Testing

- `bun run format` and `eslint` clean on the component.
- `LocalizationTest` passes (translation key resolves, no missing keys).

## Follow-up (not in this PR)

The hint guides new rules but doesn't retroactively fix rules already
saved wrong. A future enhancement could warn when saving a
positive-value amount condition, since most finance rules target
expenses.
2026-06-12 19:04:43 +02:00
Víctor Falcón faccbc3c5a
refactor(js): use InputError for inline form errors (#483)
## What

15 hand-rolled `{errors.x && <p className="text-sm
text-red-500">...</p>}` blocks across 6 components (label/category
create+edit dialogs, automation-rule form, rule builder) replaced with
the existing `InputError` component.

Bonus: `InputError` uses `text-red-600 dark:text-red-400` — the inline
copies had **no dark-mode variant** (CLAUDE.md requires dark-mode
support).

## Stats

- **-63 / +21 lines**

## Checks

- `bun run test` — 154 passed
- `bun run lint` / `format` — clean (1 pre-existing warning)
- `tsc --noEmit` — 59 pre-existing errors, none new

Part of duplication-removal series (#475–#482).
2026-06-03 19:01:21 +02:00
Víctor Falcón 9317238c49
feat(i18n): add localization test and fix missing Spanish translations (#174)
## 🚪 Why?

### Problem
Untranslated strings were silently reaching production. Several UI
components rendered raw English literals without going through \`__()\`,
and 15+ strings used via \`__()\` had no entry in \`lang/es.json\`,
causing Spanish-locale users to see untranslated text. There was also no
automated safeguard to catch new regressions.

## 🔑 What?

### Changes
- Add \`tests/Feature/LocalizationTest.php\` with two test groups that
run in CI:
1. **PHP translation files** — verifies every key in \`lang/en/*.php\`
exists in the matching \`lang/es/*.php\` file
2. **Spanish JSON translations** — scans all \`.ts\`/\`.tsx\` files for
static \`__()\` calls and asserts each key exists in \`lang/es.json\`
- Wrap previously unwrapped literals in \`__()\` in `header.tsx`
(Github, Discord, Dashboard, Log in, Register), \`appearance.tsx\`
(Chart color scheme heading and color scheme labels), and
\`rule-builder.tsx\` (field config labels and operator labels at render
site)
- Add 15 missing Spanish translations to \`lang/es.json\`: Discord,
Chart color scheme, Choose the color palette for your charts, Blue,
Colorful, Neutral, Pink, Account Name, Bank Name, contains, equals,
greater than, is empty, is not empty, less than

##  Verification

### Tests
- New test: `tests/Feature/LocalizationTest.php` — 2 tests, 4
assertions, all passing
- Runs automatically in CI via the existing `./vendor/bin/pest` job (no
CI config changes needed)

### Manual Verification
- `php artisan test --compact tests/Feature/LocalizationTest.php` →
`Tests: 2 passed (4 assertions)`
2026-03-01 12:32:39 +00:00
Víctor Falcón b1f01e4a8f
feat(automation-rules): simplify smart rules UI, fix re-evaluation, and localize amounts (#161)
## Why

**Problem:** Bulk re-evaluation of transactions against smart rules was
broken because the code required an encryption key that no longer exists
in the app. Additionally, the rule builder UI had unnecessary complexity
(priority field, labels/tags, date/category/notes conditions) that added
cognitive load without value. Currency amounts were also always
formatted with US conventions regardless of the user's locale.

## What

**Automation rules – re-evaluation fix:**
- Remove encryption key requirement from `evaluateRules`,
`evaluateRulesForTransactions`, `evaluateRulesForNewTransaction`, and
`prepareTransactionData` (accept `CryptoKey | null`)
- Drop `isKeySet` guards from single-transaction and bulk re-evaluate
handlers in `transaction-list.tsx` and `transaction-actions-menu.tsx`
- Simplify `use-re-evaluate-all-transactions.tsx` to pass `null` as key
directly

**Automation rules – UI cleanup:**
- Hide priority field from create/edit dialogs (still sends `priority:
0` / `rule.priority` to satisfy backend validation)
- Remove labels/tags from create/edit dialogs, actions column, and table
display
- Remove `date`, `category`, and `notes` from rule condition field
options in `rule-builder-utils.ts`
- Add `opacity-30` to disabled X button when only one condition/group
remains

**Amount localization:**
- Replace hardcoded `'en-US'` with `useLocale()` in `AmountDisplay` so
symbol position and number format follow the user's locale (e.g.
`89.705,00 €` in Spanish)

## Verification

- 38/38 `AutomationRuleTest` + `AutomationRuleEvaluationTest` tests pass
- Re-evaluation works without an encryption key set
- Spanish locale users see `89.705,00 €` instead of `€89,705.00`
2026-02-28 13:24:57 +00:00
Víctor Falcón 70b603e901
feat: Spanish localization (#74)
## Pending
- [x] Translate landing page
- [x] Dashboard
- [x] Accounts list page
- [x] Account page
- [x] Cashflow
- [x] Budgets
- [x] Transactions
- [x] Settings

## Screenshots
<img width="1210" height="969" alt="image"
src="https://github.com/user-attachments/assets/c7935e5c-488d-4941-8f19-8834e5668257"
/>
<img width="1211" height="972" alt="image"
src="https://github.com/user-attachments/assets/e94e1daf-233a-4a49-aa65-5678c772d178"
/>
2026-02-08 11:58:08 +01:00
Víctor Falcón 0d76913e5d
test: Fix and improve Browser test suite (#62) 2026-01-19 10:04:25 +01:00
Víctor Falcón fe5a55b1be
Automated rules labels (#30)
![Uploading image.png…]()
2025-12-15 12:11:55 +01:00
Víctor Falcón 2fefb64710 Fix CI: Update bun.lock and fix linting errors 2025-12-01 15:16:06 +01:00
Víctor Falcón 3cc225deb0 Y3:0 2025-11-26 12:01:49 +01:00
Víctor Falcón e937a8647d feat(automation): Add re-evaluate all transactions functionality 2025-11-14 14:18:43 +01:00
Víctor Falcón b866e6152e UI for Automated rules 2025-11-11 16:50:03 +00:00