Ryan Amir · Folio

CASE STUDY · PRODUCT · 2026

CardWise — swipe the right card.

A personalized credit-card recommendation surface that ranks your wallet by estimated dollars back for a purchase — category, fees, caps, and valuation stance. Built as a free demo wallet on Next.js. Educational estimates, not financial advice.

Stack Next.js 16 · React 19 · TypeScript · Tailwind · Vercel Role Product + engineering Source Private

Overview

People leave money on the table when the “right card” depends on issuer rules, rotating categories, portal-only rates, foreign-transaction fees, and how you value points. CardWise turns that into one screen: pick a category and amount, see a ranked wallet with explainable dollars-back estimates.

  • Problem. Rewards math is messy across issuers and valuation assumptions.
  • Approach. Deterministic ranking over a maintained card catalog + user inputs — not ML, not “guaranteed savings.”
  • Constraint. Demo wallet first so value is obvious before account friction.

Guided journey

Four steps from intent to an explainable pick.

Choose a spend category (dining, groceries, travel, …). Matching uses each card’s reward rules, with catch-all / 1× fallbacks.

Explainable sample recommendation

Labeled demo inputs — not live bank data.

Top pick estimated

Chase Freedom Unlimited (illustrative)

3× dining = about $3.00 back · valuation stance applied

Figures are educational estimates from catalog rules and assumed cents-per-point. Not financial advice. Actual issuer terms and redemptions vary.

Methodology

Core logic lives in recommend.ts: for each card, resolve the best rule for the category (respecting portal-only / direct travel mode), compute points with remaining elevated-rate caps, convert via cents-per-point, then subtract foreign-transaction fees when applicable. Results sort by estimated dollar value, then lower annual fee as a tie-break.

  1. Apply rotating categories for the current period.
  2. bestRuleForCategory — elevated rule, else catch-all, else 1×.
  3. pointsEarned — split spend above remaining cap onto base multiplier.
  4. Value = (points × cpp) / 100; optional FX fee deduction (~3%).
  5. Surface portal direct-alternative and cap / FX warnings for explainability.

Architecture

Real ship path — Next.js App Router on Vercel; Supabase optional.

  • UI + API routes in one Next.js app; TypeScript end-to-end.
  • Catalog and programs as maintained data modules — not scraped bank APIs.
  • Optional Supabase for persistence when signed in; demo works without auth.
  • Vitest covers ranking edge cases (caps, FX, portal-only).

Decisions

  • Deterministic over ML. Recruiters and users can audit the reason string; no black-box “savings score.”
  • Demo wallet first. Prove ranking in one screen before signup.
  • Valuation stance as a first-class input. Points are not dollars until you say how you redeem.
  • Private source. Product iteration stays private; public proof is the live demo + this case study.

Limitations

  • No bank linking or issuer APIs — catalog is maintained manually.
  • Estimates depend on assumed cents-per-point and published category rules.
  • Not financial advice; issuer terms and redemptions change.
  • Does not model signup bonuses, credit score, or approval odds.

Future

  • Richer wallet sync and spend logging against caps.
  • Merchant-level category hints where unambiguous.
  • Broader catalog coverage and clearer “rule freshness” labeling.