Dashboard

Ledgerly

A finance dashboard for small agencies that turns invoices, time tracking and bank feeds into one live cash-flow view.

Placeholder preview of the Ledgerly interface

Project data

Role
Lead full-stack developer
Type
Dashboard
Stack
  • Next.js
  • TypeScript
  • PostgreSQL
  • tRPC
  • Playwright
Duration
5 months
Year
2026
Status
Live

The challenge

Cash flow nobody could see

The agencies we interviewed kept invoices, timesheets and bank exports in three different tools. Month-end reporting took two days of spreadsheet work and was outdated the moment it was finished.

The new product had to import all three sources, reconcile them automatically and stay fast on the low-end laptops most account managers use.

How it was built

Development process

Six phases from the first conversation to the release. The bar shows how the time was split.

6 weeks in total

  1. Research

    Interviews with agency owners and a look at their month-end spreadsheets showed where the two days went.

    2 days · Usage-data review

  2. Architecture

    Data model, rendering strategy and API contracts were agreed before the first screen was drawn.

    1 week · ADR, data model

  3. Interface

    A component inventory and responsive layouts, built entirely from design tokens.

    1 week · Token set, component inventory

  4. Build

    Features went live in small slices behind flags, with typed boundaries between client and server.

    13 days · Feature slices

  5. Testing

    Unit, end-to-end and accessibility checks ran on every pull request.

    3 days · Test suite in CI

  6. Deployment

    Every branch got a preview environment; the production rollout was a single click.

    2 days · Preview and release pipeline

  7. Result

    Month-end reporting dropped from two days to under an hour for the pilot agencies.

Screens

Outcome

The results

Placeholder preview of the Ledgerly interface

What changed after launch

Month-end reporting dropped from two days to under an hour for the pilot agencies.

  • Next.js
  • TypeScript
  • PostgreSQL
  • tRPC
  • Playwright

Key figures

Lighthouse
98
Load time
−60%
Active users
2k

Under the hood

Server-first, client where it counts

Every report is rendered on the server from materialised views, so the first paint never waits for client JavaScript. Only the filters, the date range picker and the inline editors hydrate.

The reconciliation engine runs as a queue worker. It scores candidate matches by amount, date distance and reference similarity, and only asks a human when two candidates score within five points of each other.

  • Next.js
  • TypeScript
  • PostgreSQL
  • tRPC
  • Playwright
Match scoring (simplified)
export function score(tx: Tx, inv: Invoice) {
  const amount = tx.amount === inv.total ? 50 : 0;
  const days = Math.abs(daysBetween(tx.date, inv.due));
  const date = Math.max(0, 30 - days);
  const ref = similarity(tx.reference, inv.number) * 20;
  return amount + date + ref;
}

Architecture

Layer by layer

Streaming UI

React Server Components render every report; client islands handle filters and inline edits with optimistic updates.

Placeholder screen 1 of Ledgerly

Next project

Want something similar? Let’s talk.

Let’s talk

Tell me about your project. I usually reply within two working days.