FlowMind
Removing the triage tax that kills productivity systems, with the model as the mechanic rather than a chat box.
- Period
- 2025 — 2026
- Role
- Architect and product owner
- Status
- Live
Defined the product, chose the stack, and drove it through four phases — schema, AI orchestration, payments, deployment. The consequential calls were mine, including replacing Stripe with Paystack for the Nigerian market and catching the incomplete migration when stripe_customer_id was still sitting in the schema afterwards.
The problem
Knowledge workers capture information faster than they can organize it. Notes land in one app, tasks in another, half-formed ideas in a file nobody reopens. The bottleneck is the triage afterwards — deciding what belongs to which project, what actually matters today, and whether last week's intentions matched last week's reality.
Notion, Todoist and Apple Notes are storage layers. They require the user to do the sorting.
Why it mattersManual triage is the tax that kills productivity systems. People abandon them within weeks because maintaining the system costs more than the clarity it returns. Classification, entity extraction and prioritization reasoning are things a language model is genuinely good at, which makes this one of the rarer cases where the model removes work instead of adding a chat box on top of it.
What I built
A unified inbox for unstructured capture, auto-organization that classifies items and extracts entities into projects and priorities, a reasoned daily plan rather than a sorted list, and a weekly summary comparing planned against accomplished.
Three connected surfaces: a marketing site, an authenticated app across dashboard, inbox, today, projects, insights, settings and billing, and the backend powering both.
How it holds together
Capture is the user's only job. Everything right of the inbox is chained model work writing structured results back into a relational model the interface reads directly.
Seven user-scoped Postgres tables behind row-level security, with triggers for derived counts and every table reaching auth.users through profiles.id.
Three endpoint shapes rather than one prompt: a single-pass classification and extraction that writes back with a confidence score; a multi-step daily planner that gathers context from projects and open items, reasons about priorities, then emits a structured plan; and a comparative weekly chain over daily plans against completed items.
Usage metering on profiles ties the free and paid boundary to the actual cost driver — model calls — rather than an arbitrary feature gate, with ai_processing_log recording calls for debugging.
Decisions
- 01
Structured output is the hard boundary, not the prompt
Auto-organize has to return something that maps cleanly onto typed Postgres columns — project assignment, priority, extracted entities, and a confidence float constrained to 0–1. Free-text output does not survive contact with a schema. The real work sits at the join between the chain and the database.
- 02
Multi-step chains inside a serverless timeout
The daily planner gathers context, then reasons, then generates — sequential model calls under a Vercel function limit. Groq's inference speed is what makes it viable at all; maxDuration of 30 is the accommodation rather than the solution.
- 03
Paystack over Stripe, and it was not a client swap
Stripe does not serve the market this is built for. Migrating touched the schema, the subscription status enum — Paystack's non_renewing has no Stripe equivalent — webhook signature verification, and the entire billing interface. It got consolidated into a single authoritative schema file rather than left as an incremental migration.
- 04
A bleeding-edge stack with no settled patterns
Tailwind v4 dropped the config file for a CSS-first @theme directive, Framer Motion renamed to motion with new import paths, and Next 15 split viewport out of the metadata export. Most tutorials and most training data describe the previous versions, so the design system had to be built against documentation rather than convention.
- 05
globals.css as a contract between sessions
The landing page, auth pages and dashboard were built at different times. Keeping the palette, elevation and motion timing identical across three separately-built surfaces meant treating the token file as a real contract rather than a place to put colours.
Stack
- Next.js 15
- React 19
- Server Components
- Turbopack
- Groq
- Mistral
- LangChain
- multi-step chains
- Supabase
- Postgres
- Realtime
- Row-level security
- usage metering
- Paystack
- signed webhooks
- subscription sync
- Tailwind v4
- Motion 12
- DM Sans
- Playfair Display
- Multi-step chains with context gathering and reasoning, not single-shot prompting
- Open-model orchestration rather than defaulting to a single vendor
- Model output constrained to survive a relational schema
- Multi-tenancy enforced at the database
- Usage metering tied to the real cost driver