DEV Community

Cover image for MailTriage: a local inbox desk a freelancer would pay for
Gavindu achintha
Gavindu achintha

Posted on

MailTriage: a local inbox desk a freelancer would pay for

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

MailTriage is a local triage desk for freelancers. You connect Gmail, the app sorts client mail by what actually needs you, and a local model drafts a reply in your voice. You edit it. Nothing is sent until you save it to Gmail Drafts yourself.

Categories: urgent, waiting on a client, invoice, new lead, low priority. Each message also gets a priority score, a one-line summary, and a suggested action.

Who would pay: a freelancer whose inbox is invoices, “just circling back”, real deadlines, and new leads — and who will not paste client names and rates into a hosted chatbot.

The problem: cloud copilots want the whole thread. MailTriage keeps inference on the laptop (Ollama + Gemma 3). Gmail tokens stay in a signed cookie. Postgres only stores writing-style examples and the last triage per message, not the inbox.

Gmail  --read only-->  MailTriage  --local Gemma-->  draft
                            |
                       Postgres
                  (style + last triage)
Enter fullscreen mode Exit fullscreen mode

Demo

Code

This is a Next.js project bootstrapped with create-next-app.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.

This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more…




How I Built It

Open-source AI is the core, not a plugin:

  • Local inference: Ollama on 127.0.0.1
  • Open-weight model: Gemma 3 (OLLAMA_MODEL=gemma3)
  • The model does the whole job: category, priority, summary, suggested action, and the draft. Style examples you save (past replies) are loaded from Postgres and sent with the prompt so the next draft sounds like you.

The rest of the stack is a desk around that call:

  • Next.js 16 — inbox list, retractable sidebar, draft panel, settings
  • Gmail API — read-only inbox, save to Drafts (never auto-send)
  • PostgreSQL + pg — no ORM. Tables are mailtriage_users, mailtriage_style_examples, mailtriage_analyses so they do not collide with an existing users table. Queries are plain SELECT / INSERT / UPDATE / DELETE. Saving an analysis is an update, then an insert if nothing matched.

The Next.js pool is one pg.Pool on globalThis so hot reload does not leak connections. If DATABASE_URL changes, the pool is rebuilt.

Why Does Open Innovation Matter?

A freelancer will not pay for a tool that uploads their clients to a hosted model. Rates, NDAs, and “can you invoice this week” do not belong in someone else’s cache.

A closed mail API would have been easier to demo (paste a key, ship a URL) and worse to sell. Open-weight Gemma on Ollama is what makes the side hustle honest:

  • Privacy — the thread is inferred on the same machine that already has the inbox
  • Cost — no per-token bill for “sorry for the delay,” so the product can be a one-time or cheap local tool
  • Control — swap the model with OLLAMA_MODEL instead of rebuilding around one vendor’s price and terms

The open pieces are why someone would pay this instead of pasting the email into ChatGPT.

My Agent Session

Building MailTriage: local Gemma triage, Postgres, Week 2 post
You

Analyze the UI. It looks like the usual LLM dashboard. Make it professional for freelancers, keep it consistent, no fancy gradients.

Agent

Replaced the indigo/serif LLM look with warm stone neutrals, a single muted teal accent, IBM Plex Sans/Mono wired correctly, and a calmer inbox/sidebar/draft panel. No gradients.

You

Add a settings option and make the sidebar retractable.

Agent

Desktop sidebar collapses to an icon rail (saved on the device). Settings dialog covers theme, writing style, local model status, and Gmail disconnect.

You

Add an avatar in the header. The application name is MailTriage.

Agent

Header shows initials from the Gmail address and a menu (settings, disconnect). Renamed InboxGuard to MailTriage in the UI, metadata, landing copy, and model prompt.

You

Add a database. Using Postgres. Keep it simple, no ORM.

Agent

Added pg Pool + raw SQL. Tables: users, style examples, analyses. Gmail tokens stay in the cookie. Inbox still comes from Gmail.

You

Keep the db query simple. I need the full query including creating the tables.

Agent

Flattened to SELECT/INSERT/UPDATE/DELETE. Save path is UPDATE then INSERT. Gave the full CREATE TABLE script.

You

CREATE TABLE users skipped (already exists). style_examples failed: column email referenced in foreign key does not exist.

Agent

They were on postgres.public. An existing users table had no email column. Renamed tables to mailtriage_users, mailtriage_style_examples, mailtriage_analyses.

You

password authentication failed for user postgres

Agent

A direct pg client connected. Next.js was still using a pool created with the old DATABASE_URL. Pool now rebuilds when the URL changes and prefers [REDACTED]. Restart the dev server after env changes.

You

Create the markdown file. Add aesthetics. This is for Hacktoberfest Week 2. Put it on DEV too. Here is the official submission template.

Agent

Wrote README.md for the Side Hustle pitch. Drafted a DEV post on the linked account with the Week 2 template, repo embed, and Best Use of Gemma. Left it unpublished for review.

Build log from this session: UI pass, retractable sidebar and settings, MailTriage rename, Postgres without an ORM, the users table collision, and the stale connection-pool password bug.

Prize Categories

Best Use of Gemma — triage and drafts run on Gemma 3 through Ollama. No hosted LLM.

Top comments (0)