Skip to content

feat: Add financial position, holdings, and intent tagging UI#94

Merged
nfebe merged 1 commit into
devfrom
feat/issue-233-transaction-intents
Jun 27, 2026
Merged

feat: Add financial position, holdings, and intent tagging UI#94
nfebe merged 1 commit into
devfrom
feat/issue-233-transaction-intents

Conversation

@nfebe

@nfebe nfebe commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

What

  • Financial Position screen (/financial-position, also a Reports tab): net worth, a money in / money out ledger by intent, each row drilling into its transactions. Greyed rows mark cash that moves but doesn't change net worth.
  • Holdings screen (/holdings) and form: list assets with value and a live/manual badge; add crypto via CoinGecko search (auto-priced) or any asset manually. Total net worth = cash + holdings.
  • Intent selector on the transaction form: tag income/expense as loan, debt, investment or gift.
  • Navigation: the dashboard is the default landing, the AI assistant is one entry with a Discussions sub-item, and less-used items move to the footer.
  • Budgets can be created in any supported currency, not only wallet currencies.
  • Assistant landing stat cards use Solar duotone icons (via Iconify) so the large art reads richly.

Why

  • Surfaces the backend intent/position model so users see honest net worth and where money really went.

Notes

  • Consumes the new holdings + position endpoints; sends owner_type/owner_id on holding create.
  • Adds unplugin-icons and @iconify-json/solar (build-time inlined, offline).
  • The chat-first landing toggle persists once the paired webservice PR's config-key fix is deployed.

Tests

  • 400 passing (mapper, Financial Position, holdings, budget currency, transaction form); production build green.

@sourceant

sourceant Bot commented Jun 27, 2026

Copy link
Copy Markdown

Code Review Summary

This PR introduces significant financial tracking features including a new Financial Position view, Holdings management with live crypto pricing, and transaction intent tagging. It also refines navigation and onboarding defaults.

🚀 Key Improvements

  • Added support for live asset pricing via CoinGecko in holdings/index.vue.
  • Implemented a comprehensive 'Financial Position' ledger that distinguishes net-worth-changing cash flow from balance sheet movements.
  • Optimized icon loading using build-time inlining with unplugin-icons.

💡 Minor Suggestions

  • Unify currency formatting logic across the new components.
  • Improve search debounce logic in the Holding form to prevent race conditions.

@sourceant sourceant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. See the overview comment for a summary.

};

const toRow = (txn: ApiTransaction): Row => {
const currency = txn.wallet?.currency || 'XAF';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded fallback currency 'XAF' might result in incorrect data visualization for users with different base currencies if the wallet object is missing.

Suggested change
const currency = txn.wallet?.currency || 'XAF';
const currency = txn.wallet?.currency || props.group?.metric?.split(' ').pop() || 'USD';

@nfebe nfebe force-pushed the feat/issue-233-transaction-intents branch from ddf9b1a to 7cfae35 Compare June 27, 2026 12:53
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 27, 2026

Copy link
Copy Markdown

Deploying trakli-dev with  Cloudflare Pages  Cloudflare Pages

Latest commit: b4013ea
Status: ✅  Deploy successful!
Preview URL: https://ac042af9.trakli-dev.pages.dev
Branch Preview URL: https://feat-issue-233-transaction-i.trakli-dev.pages.dev

View logs

@sourceant sourceant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. See the overview comment for a summary.

Comment on lines +161 to +165
if (q.length < 2) {
results.value = [];
return;
}
searchTimer = setTimeout(async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The search logic does not handle potential race conditions if multiple requests are fired in quick succession. Using an AbortController or checking a timestamp/request ID would ensure the results ref is only updated by the latest triggered search.

Suggested change
if (q.length < 2) {
results.value = [];
return;
}
searchTimer = setTimeout(async () => {
searchTimer = setTimeout(async () => {
try {
const fetchedResults = await holdingsApi.search(q);
if (q === coinQuery.value.trim()) {
results.value = fetchedResults;
}
} catch (e) {
results.value = [];
}
}, 300);

);

const money = (n: number) =>
formatShortAmount(`${Math.round((n || 0) * 100) / 100} ${currency.value}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Math.round(n * 100) / 100 can lead to floating point precision errors (e.g., 1.005 rounding to 1 instead of 1.01). Use toFixed(2) for financial display logic.

Suggested change
formatShortAmount(`${Math.round((n || 0) * 100) / 100} ${currency.value}`);
formatShortAmount(`${(n || 0).toFixed(2)} ${currency.value}`);

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 27, 2026

Copy link
Copy Markdown

Deploying webui with  Cloudflare Pages  Cloudflare Pages

Latest commit: b4013ea
Status: ✅  Deploy successful!
Preview URL: https://89ce987e.webui-9fh.pages.dev
Branch Preview URL: https://feat-issue-233-transaction-i.webui-9fh.pages.dev

View logs

- Add the Financial Position screen: net worth, a money in/out ledger
  by intent, and a drill-down into the underlying transactions.
- Add a Holdings screen and form backed by the holdings API, with live
  crypto pricing and manual assets; holdings feed total net worth.
- Add an intent selector to the transaction form so income and expenses
  can be tagged as loans, debt, investments or gifts.
- Refine navigation: the dashboard is the default landing, the AI
  assistant is one entry with a Discussions sub-item, and less-used
  items move down.
- Let budgets be created in any supported currency, not just the
  currencies of existing wallets.
- Use Solar duotone icons (via Iconify) for the assistant landing
  stat cards so the large art reads richly instead of as thin lines.
@nfebe nfebe force-pushed the feat/issue-233-transaction-intents branch from 7cfae35 to b4013ea Compare June 27, 2026 13:21

@sourceant sourceant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. No specific code suggestions were generated. See the overview comment for a summary.

@nfebe nfebe merged commit 4feaf04 into dev Jun 27, 2026
6 checks passed
@nfebe nfebe deleted the feat/issue-233-transaction-intents branch June 27, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant