Case study · personal product

InboxIntel

In development

A self-hosted inbox intelligence and cleanup tool — semantic search, AI summaries and inbox-health analytics over your mail.

.NET 10ReactPostgreSQLOllamaClean ArchitectureDocker
inboxintel.local
InboxIntel split view: a persistent message list beside a resizable reading pane with an AI summary

TL;DR

What
Inbox intelligence: split-view reading, semantic search, AI summaries, inbox-health analytics and safe cleanup.
Why
To practise Clean Architecture properly, and make search useful and destructive operations safe by design.
Stack
.NET 10 · PostgreSQL + pgvector · React · Ollama · Docker · Clean Architecture.
Role
Sole architect and developer, front to back.

Problem & context

A busy inbox is hard to search and dangerous to clean up — keyword search misses what you meant, and one wrong bulk filter deletes things you can’t get back. I built InboxIntel to make an inbox actually searchable (by meaning, not just words), understandable at a glance, and safe to tidy — all self-hosted, with a clean, testable backend.

Architecture

A React SPA over an ASP.NET Core API built as Clean Architecture — the dependency rule points inward (Api → Infrastructure → Application → Domain), and controllers hold no business logic. A hosted background worker syncs Gmail into PostgreSQL; a local Ollama model generates embeddings (stored with pgvector) and message summaries, which power hybrid semantic + full-text search.

  • Reading: a persistent list beside a resizable pane with an AI summary — triage without opening a new tab.
  • Search: semantic (pgvector) + full-text, with why-matched highlights and a relevance score.
  • Analytics: an inbox-health grade, emails by category, a 90-day volume trend and top senders.
  • Cleanup: preview-then-confirm on every destructive action; the AI is advisory only.
InboxIntel architecture A React SPA calls an ASP.NET Core API layered as Clean Architecture. A hosted background worker syncs the external Gmail API into PostgreSQL with pgvector, and a local Ollama model produces the embeddings and summaries that power semantic search. /api AI sync React SPA split-view · search ASP.NET Core API Clean Architecture Ollama embeddings · summaries PostgreSQL EF Core · pgvector Sync worker hosted · Polly Gmail API external · OAuth2

Key decisions & trade-offs

  1. 01 Local Ollama embeddings + pgvector for semantic search.

    alt: A hosted embeddings API and a vector database.

    Mail is private, so embeddings stay on my own hardware and live right next to the data in Postgres via pgvector — one datastore, no third party, no per-call cost. The trade-off is running the model myself.

  2. 02 Encrypt OAuth refresh tokens at rest and never log them.

    alt: Store them as plain columns.

    Refresh tokens are long-lived keys to someone’s mailbox. They’re encrypted with the ASP.NET Core Data Protection API (AES), with keys persisted to a mounted volume — the single most important security decision in the app.

  3. 03 Every destructive action is preview-then-confirm.

    alt: Delete immediately on request.

    All cleanup and unsubscribe actions require a server-side preview and an explicit Confirmed flag. The AI layer is advisory only and can never trigger a deletion.

Security & production notes

  • Google-OAuth gated; Gmail scopes are read/modify only — no send scope is ever requested.
  • Embeddings and summaries are generated locally (Ollama); mail never leaves the box for a third-party model.
  • Polly retry/backoff against Gmail rate limits; Serilog structured logging that never records tokens.
  • Clean Architecture keeps the layers testable; integration tests boot the API host and assert authorization.

Screenshots

InboxIntel analytics dashboard: inbox-health grade, emails by category, 90-day volume and top senders
Analytics — an inbox-health grade, categories, volume trend and top senders
InboxIntel search: hybrid semantic and full-text results with why-matched highlights and relevance scores
Search — hybrid semantic + full-text, with why-matched highlights and relevance

Status & what’s next

In active development. Search, summaries and analytics work end to end; next up is tuning the semantic-recall thresholds, expanding the integration-test suite, and working toward connectors beyond Gmail so it becomes a genuinely universal inbox tool.