As a developer, I default to building things — but not every problem needs a custom app. My client work was scattered across a spreadsheet for invoices, a doc for project notes, and a notes app for task lists. None of it talked to each other. Every status update meant updating three places by hand.
The fix wasn't code. It was applying actual database thinking — foreign keys, relations, one-to-many — to a tool I'd been using like a glorified to-do list: Notion.
The problem with flat lists
Most people use Notion databases as flat tables. A "Clients" list. A separate "Projects" list. No connection between them. That's the Notion equivalent of denormalized data — duplicate info everywhere, no single source of truth.
The fix is the same one you'd reach for in Postgres: relations.
Modeling it like a schema
I mapped out four entities, the same way I'd sketch a schema before writing migrations:
Clients (1) ──< Projects (many)
Projects (1) ──< Tasks (many)
Clients (1) ──< Invoices (many)
Projects (1) ──< Invoices (many)
In Notion, this becomes relation properties — each database gets a field that points to rows in another database. Set it up as a two-way relation, and opening a client automatically shows every project, task, and invoice tied to them. No manual lookups, no copy-pasting a client name into three different sheets.
The four databases
Clients — contact info, status (Active/Paused/Past), industry. The "root" entity everything else relates back to.
Projects — relates to Clients. Adds status, deadline, budget, priority. This is where a Kanban view (grouped by Status) actually earns its keep — dragging a card from "In Progress" to "Review" feels like a real workflow, not just checking a box.
Tasks — relates to Projects (which relates to Clients, so you get the chain for free). Due dates, priority, assignee.
Invoices & Payments — relates to both Clients and Projects. This was the one I initially got wrong — I first related it only to Projects, then realized I wanted to filter "everything owed by Client X" without going through the project layer. Two relations, no downside.
Views matter as much as the schema
Once the relations exist, the same underlying data supports wildly different views:
Table — the full spreadsheet-style view, for bulk editing
Board (Kanban) grouped by Status — for daily workflow
Calendar grouped by Deadline — for "what's due this week"
This is the part that took me longest to appreciate: the data model is the hard part. Once it's right, views are nearly free.
Where this ended up
I turned the finished structure into a template — four connected databases, pre-filled with sample data so the relations are visible immediately instead of staring at empty tables. If you want the ready-built version instead of wiring up the relations yourself, I packaged it here: Client & Project Tracker — Notion Template.
Either way — if you're a freelancer or small agency juggling client info across too many tools, the fix probably isn't a new app. It's modeling the relations you already have data for.
Top comments (0)