How I Built a Credit Card Management Dashboard (And Why Spreadsheets Were Not Cutting It)
Source: Dev.to
The Situation
I had 17 credit cards open, each serving a specific purpose:
| Card | Purpose |
|---|---|
| 0 % APR balance‑transfer | 4‑month intro period |
| Business card | 3× points on advertising |
| Personal card | Rotating 5 % categories |
| Business inventory card | Purchases for stock |
| … | … |
I tracked everything in a Google Sheet with columns for:
- Card name / issuer
- Credit limit
- Current balance
- APR / promo rate
- Promo expiration date
- Annual‑fee date
- Reward structure
- Notes
Rows were colour‑coded for urgency and conditional formatting was set to flag upcoming deadlines.
It worked for about two years—then it stopped working.
The Breaking Point
I missed a 0 % APR expiration on a card carrying a $12,000 balance.
The promotional rate ended on a Tuesday. I didn’t check the sheet that week, the standard APR kicked in, and I paid interest that could have been avoided.
The spreadsheet had the date and the conditional formatting was correct.
The problem? A spreadsheet doesn’t push notifications like “Hey, you have 7 days left before this rate expires and you still have $12,000 on this card.”
That moment sparked the decision to build something better.
What Went Wrong (Two Years of Spreadsheet‑Based Card Management)
| Issue | Why It Failed |
|---|---|
| No proactive alerts | The sheet only displayed data; it never reminded me. |
| Manual utilization math | Calculating total utilization across 17 cards required updating balances, summing, and dividing every time. |
| No “which card should I use” logic | I knew reward structures in my head, but often used the wrong card at the wrong merchant. |
| Reactive annual‑fee decisions | I only noticed fees on statements, not before they hit. |
| Application tracking mess | I had to manually count applications to stay under Chase’s 5/24 rule. |
| Manual balance entry | Users (including me) didn’t keep data current, breaking the dashboard. |
Core Data Model – Every Card Is an Object
{
"name": "string",
"issuer": "string",
"creditLimit": 0,
"currentBalance": 0,
"standardAPR": 0.0,
"promoRate": {
"rate": 0.0,
"expiration": "YYYY‑MM‑DD"
},
"annualFee": {
"amount": 0,
"date": "YYYY‑MM‑DD"
},
"rewardStructure": {
"baseRate": 0.0,
"categories": {
"groceries": 0.0,
"gas": 0.0,
"...": 0.0
},
"rotating": {
"quarter": "Q1‑2024",
"categories": ["dining", "travel"],
"multiplier": 5,
"cap": 1500
}
},
"applicationDate": "YYYY‑MM‑DD",
"lastStatementDate": "YYYY‑MM‑DD",
"paymentDueDate": "YYYY‑MM‑DD"
}
Key point: Several properties are time‑dependent (promo expiration, rotating categories, annual‑fee dates).
Deadline Engine – The Real‑Time Alert System
Each card generates a set of deadlines with severity levels and suggested actions:
| Deadline | Alert Timing | Example Message |
|---|---|---|
| Promo‑rate expiration | 90 d, 60 d, 30 d, 7 d before | “Your Citi 0 % APR expires in 30 days. Balance: $8,400. Action: Pay off or transfer.” |
| Annual‑fee renewal | 60 d, 30 d before | “Annual fee of $95 on your Amex hits in 30 days. Evaluate keep vs. cancel.” |
| Payment due date | 7 d, 3 d before | “Payment of $1,200 due on 2024‑04‑15. Avoid late fees.” |
| Rotating‑category activation | Start of each quarter | “Q2 bonus: 5 % on groceries (cap $1,500).” |
The alert engine is the feature that actually prevents costly mistakes.
Utilization Calculations (Real‑Time)
- Total utilization = Σ (currentBalance) ÷ Σ (creditLimit)
- Per‑card utilization = currentBalance ÷ creditLimit
- Impact simulation – “If I move $3,000 from Card A (45 % util.) to Card B (12 % util.), what will each utilization be?”
These numbers matter because credit‑score models care about per‑card utilization, not just the aggregate.
Card Selector – “Which Card Gives Me the Best Return?”
Given a spending category (e.g., groceries, gas, dining, online), the selector evaluates:
- Base reward rate per card.
- Current bonus categories (including rotating quarterly bonuses).
- Activation status – has the quarterly bonus been turned on?
- Spending caps – does the purchase exceed the bonus cap?
The result is a lookup function that updates each quarter and respects caps and activation status.
Promo‑Rate Logic – Handling Different Terminology
| Terminology | Expiration Logic |
|---|---|
| “Promotional APR” | Fixed calendar date (e.g., 2024‑07‑01). |
| “Introductory rate” | Fixed calendar date or “X months after account opening.” |
| “0 % for 18 months” | Compute expiration = applicationDate + 18 months. |
The system normalises these variations into a single expiration date for alert scheduling.
Reducing Manual Data Entry
Problem: Manual entry creates a chicken‑and‑egg loop – the dashboard is only useful when data is current, but users are reluctant to keep it up‑to‑date.
Solutions explored:
- API sync with issuers (where available).
- Bank‑level aggregation (e.g., Plaid) for balances.
- Quick‑add widgets (mobile‑friendly) for balance updates.
- Smart defaults (e.g., auto‑populate payment due dates from the last statement).
The goal is to make data entry frictionless.
Notification Engine – The Core Value
All the charts and dashboards are nice, but the real value is the notification that arrives three days before a promo rate expires. Everything else is secondary to that alert engine.
YMYL (Your Money, Your Life) Considerations
Financial content is classified as YMYL by search engines. That means:
- Every number must be accurate.
- Every claim must be defensible.
- No sloppy advice – users rely on this for real money decisions.
Building in fintech therefore demands rigorous data validation and clear sourcing.
StackEasy – What Users Actually Use
| Feature | Why It Matters |
|---|---|
| Portfolio dashboard | Shows all cards, balances, limits, and utilization at a glance. |
| Deadline tracker | Proactive alerts for promo expirations, annual fees, and payment dates. |
| Card selector | Recommends the best card for each spending category. |
| Application log | Tracks velocity across issuers (e.g., staying under 5/24). |
The biggest validation came when users told me they caught a promo expiration they would have missed. That’s the whole point.
Non‑Obvious Lessons for Fintech Builders
- Start with your own pain. I built StackEasy because I needed it.
- Focus on the single‑most‑valuable feature. In my case: the deadline‑alert engine.
- Make data entry frictionless or automate it; otherwise the product dies.
- Normalize terminology (promo APR, intro rate, etc.) early to simplify logic.
- Treat every number as a legal claim – YMYL standards are unforgiving.
- Iterate on alerts first, then layer dashboards and analytics.
TL;DR
- Spreadsheets can store data but cannot push timely alerts.
- A card object model with time‑dependent fields enables automation.
- Deadline alerts (promo expirations, annual fees, payment due dates) are the core value.
- Real‑time utilization and a card‑selector help optimize credit scores and rewards.
- Reducing manual entry and respecting YMYL standards are essential for fintech success.
If you’re building a credit‑card management tool, solve the alert problem first – everything else will follow.
Key Takeaways
- Understand edge cases first – Make sure you’ve identified the edge cases before writing a single line of code.
- Management tools are undervalued – Everyone builds tools to help people find or buy financial products, but almost nobody builds tools to help people manage what they already have.
- Simplicity beats cleverness – A deadline alert that fires on time is worth more than a machine‑learning model that predicts spending patterns.
- Trust is everything – People are entering their financial data. Earn that trust through transparency, security, and never being clever with their information.
If you’re juggling multiple credit cards and your spreadsheet is starting to crack, check out StackEasy. I’m happy to answer questions about the build in the comments.