Skip to content

Rediant case study

Personal finance SaaS that connects to European bank accounts via Open Banking, automates transaction management, and provides budgeting and analytics. Built solo from side project to production.

Solo founder & engineer — Personal. Stack: Next.js, React, Supabase, Stripe, Upstash Redis, Resend, Vercel, Tailwind CSS. Tasks: Architecture, Backend development, Frontend development, Infrastructure, DevOps. ## Origin I wanted a financial tool that actually made sense for how I manage money, not a read-only bank dashboard or a spreadsheet with formulas. Something that could pull in real bank transactions, let me categorize and budget them my way, track recurring costs, and give me honest numbers about where my money goes. Nothing I found did all of that well, especially in Europe where Open Banking is available but barely used by consumer apps. So I built Rediant, a personal finance SaaS that connects directly to European bank accounts, automates transaction management, and provides a complete budgeting and analytics layer on top. ## The Product Rediant handles the full lifecycle of personal finance management: bank syncing via Open Banking to pull in transactions automatically, transaction management with manual entry, bulk CSV import, advanced filtering, tagging, and global search. Categories with monthly budgets support per-month overrides for irregular months. Recurring transaction templates generate drafts on schedule with auto-interval detection from history. Savings goals track progress with account-based or fixed contributions. An interactive dashboard provides spending analytics built with Recharts, and transaction rules automatically categorize, tag, or rename matching transactions as they arrive. ## Bank Sync: Rediant Connect The hardest part of building a finance app isn't the UI or the math. It's getting real transaction data in reliably. Rediant Connect is a custom orchestration layer wrapping an Open Banking API. Rather than coupling the app directly to the banking provider, I built an abstraction with its own API client, institution caching, and connection lifecycle management. Users select their bank from a country-filtered institution list covering 10+ European countries, with an in-memory cache to avoid redundant API calls. A requisition is created and the user is redirected to their bank's OAuth consent screen. On callback, the app parses the authorization result and sets up the account link. Transactions flow in, get stored as synced transactions with raw data preserved, and link to the user's manual transaction records. Bank connections expire, banks go offline, and OAuth flows get interrupted. Rediant handles all of this with a reactivation flow for renewing expired connections without losing the account link, an onboarding-specific callback that redirects first-time bank connections to the dashboard, timeout protection that guards against serverless function limits, and a custom hook with React Query integration and prefetch-on-hover. ## Authentication & Security Authentication runs on **Supabase Auth** with multiple layers added on top. Full TOTP-based 2FA with authenticator app support features a 6-digit segmented input with auto-submit, keyboard navigation, and paste support. JWT Authentication Assurance Levels gate sensitive operations. Every authenticated request goes through a cached user lookup, which checks the cache layer before hitting the database: user data cached by session token with TTL-based expiry, session tracking for multi-device invalidation, atomic cache writes, and graceful fallback if the cache is unavailable. The Next.js middleware handles public route allowlisting, cached MFA enforcement, cached subscription gating, API-aware JSON responses for 401/403, and authenticated user redirection away from auth pages. A sliding window rate limiter protects sensitive endpoints with configurable request limits and progressive lockout after repeated failed login attempts. ## Billing & Subscriptions The **Stripe** billing system handles the full subscription lifecycle: checkout with conditional free trial (eligibility tracked to prevent abuse), monthly and annual plans, and promotion code support. Webhook events handle subscription creation, updates, deletions, and trial ending notifications with automated email and in-app alerts. GDPR-compliant customer management was one of the trickier parts. When a user deletes their account, the billing provider still needs to retain certain records for tax and audit purposes. The solution uses one-way email hashing for privacy-compliant customer matching, anonymization on deletion that preserves only business-critical metadata, and reactivation support that finds anonymized customers by email hash and restores subscription data. Cache invalidation fires after every subscription state change. ## Automated Background Jobs Scheduled cron triggers run two background jobs. **Monthly financial summaries** process users in batches, calculating total spent, total income, net change, top categories, and month-over-month percentage change, with deduplication and combined in-app plus email notifications respecting per-user preferences. **Budget warnings** scan all categories with budgets set and send exactly one warning per category per month via deduplication through notification metadata. ## Email System Transactional email templates built with **React Email** and delivered via **Resend** covering the full lifecycle from onboarding to account management. Cross-client dark mode uses a layered approach: CSS media queries for standard clients, platform-specific selectors for Apple Mail and Outlook, and dual-rendered buttons and logos with CSS display toggling. Images are served through Cloudflare Images CDN with variant-based optimization. ## Notifications A unified notification handler serves as the single entry point, creating an in-app notification record, optionally sending an email based on type and user preferences, and supporting elevated privileges for background job contexts. Notification templates each return a structured object with title, content, and email component. A notifications context wraps the entire app for real-time state. ## Database **Supabase PostgreSQL** with Row Level Security enforced on every table. The schema covers accounts, transactions, categories, recurring transactions, tags, budget overrides, subscriptions, and bank connections. Stored functions handle critical operations, keeping complex logic in the database rather than the application layer. Monthly budget overrides use a separate table allowing per-month adjustments without changing the category default. Raw bank data is stored in a structured format, preserving the original response while the app normalizes it into queryable fields. ## Frontend The app wraps authenticated routes in a multi-layer provider stack handling theme, global context, notifications, dialogs, command menu, keyboard shortcuts, and data fetching. **TanStack React Query** handles all server state with tuned stale times and invalidation per resource type. **TanStack React Table** powers the transaction table with filtering, sorting, pagination, and column visibility. **React Hook Form + Zod** provides type-safe validation from schema to submission. The UI is built on Radix UI primitives with shadcn/ui patterns, styled with **Tailwind CSS**. Animations use both Framer Motion (page transitions, layout animations) and GSAP (marketing site). A command menu provides global search and keyboard-driven navigation, drag-and-drop via `@dnd-kit` handles reordering goals and categories, and an emoji picker lets users customize category icons. A 4-step CSV import flow guides users through file upload, column mapping (supporting separate income/expense columns or a single amount column), table preview, and batch submission, with auto-matching of existing categories and recurring transactions. ## Savings Goals The goals feature includes a contribution validation algorithm that prevents double-counting when multiple goals draw from the same bank account. Priority-based allocation ensures higher-priority goals get funded first, with chronological tiebreaking when priorities are equal. Archived goals bypass balance consumption and always show 100%, while "reached but not yet archived" goals still consume their share. Each contribution returns validation status, actual amount, and shortfall so the UI can show exactly how much funding is missing. ## Key Decisions - **Caching session and status data.** Caching user sessions, MFA status, and subscription state eliminated redundant database calls on every request, keeping middleware fast without sacrificing security checks. - **Abstracting the banking provider behind Rediant Connect.** Building a dedicated orchestration layer with its own caching, timeout handling, and lifecycle management meant the app never couples directly to a third-party banking API. - **Middleware-level subscription gating.** Checking subscription status in middleware instead of per-page keeps the codebase clean and makes it impossible to accidentally expose a premium feature. - **Unified notification system.** A single notification handler that manages both in-app and email notifications means every new notification type is a template, not a new code path. - **Database-level business logic.** Keeping critical operations in database stored functions ensures consistency regardless of which client or background job triggers them. ## Challenges - Building a secure and scalable authentication system and secure database storage for sensitive data. - Designing a contribution validation system for savings goals that correctly handles shared accounts, priority ordering, and archived state. - Managing bank connection lifecycle: expired tokens, interrupted OAuth flows, reactivation without data loss, and timeout protection. - Implementing GDPR-compliant customer management with anonymization, hashing, and reactivation support. - Coordinating background job execution windows with deduplication and per-user preference checks across batched processing.
Works

Works

Explore selected projects with timelines, stack choices, and delivery outcomes. This view includes company and freelance examples in a horizontal timeline display.

Project List

Timeline (From 2024)

Projects
202420252026
  1. Triqai

    Today
  2. Rediant

  3. Through the Frames

  4. Hytura

  5. Knitted

  6. Bysidde

Loading workspace

Taxi the dog desktop wallpaper icon