Viollet
Viollet is a side project I designed and built end to end. It connects Gmail, ingests bank transaction notifications, categorizes spending with AI, and surfaces budgets and insights without asking for online banking credentials.
- Role
- Solo builder, from architecture through production
- Year
- 2026
- Read time
- 12 min read
- TypeScript
- Next.js
- Turso
- Drizzle
- Clerk
- AI SDK
- Gmail API
- Google Pub/Sub
- Webhooks
- Vercel
Sample session
A simulated Viollet session with the public demo's signed-in user. It shows the dashboard, expenses, budgets, and inbox.
1. Context
Most personal finance apps still depend on manual logging or direct bank integrations that are hard to ship, expensive to maintain, and often unavailable for regional banks.
In the Dominican Republic, many people already receive credit, debit, and transfer alerts by email. The product opportunity was to meet users where their data already lives: turn those notifications into structured transactions, categories, and spending views with zero manual entry.
2. Constraints
Viollet is a solo side project, so scope had to stay focused on one reliable ingestion path instead of building a full open-banking platform on day one.
Financial data raised the bar for security and trust: no bank passwords, read-only Gmail access with explicit user consent, and a codebase that stays private while the product is still in public beta.
- No bank credential collection, only email notifications the user already receives
- Gmail restricted scopes require Google verification and ongoing security review
- Bank notification formats vary across 15+ Dominican institutions and differ by card vs. account
- Storage uses Turso with Drizzle, not a generic SQLite label
3. My responsibility
I owned the product from problem framing through production: system boundaries, data model, Gmail/OAuth flow, webhook ingestion, AI-assisted categorization, dashboard UX, and deployment.
That included choosing what to automate first (email-based capture and categorization), what to defer (direct bank APIs), and how to explain trade-offs clearly on the public site so users understand access and revocation.
4. Architecture
The runtime has three cooperating paths: the signed-in Next.js app on Vercel (Clerk for sessions), asynchronous mail ingestion (Gmail watch plus a Pub/Sub push into a webhook route), and Drizzle on Turso for the ledger.
A supported notification is cleaned, extracted with the AI SDK into a typed object (through the Vercel AI Gateway in production), categorized, and stored. The dashboard and the assistant read those rows for budgets, trends, and answers.
Each node, in turn, shows how Gmail, Pub/Sub, Next.js, Clerk, Vercel, the AI SDK, and Turso split the work.
5. Decisions and trade-offs
Clerk for authentication
Clerk reduced time-to-ship for session management and let me focus engineering time on Gmail sync and ingestion reliability. The trade-off is coupling auth to a hosted provider, acceptable for a beta where speed and security defaults matter.
- 01Email notifications instead of bank APIs
- 02Turso + Drizzle for the data layer
- 03AI-assisted categorization alongside parsing rules
- 04Clerk for authentication
- Email notifications instead of bank APIs. Bank APIs and aggregators would expand coverage faster in theory, but they add partnership overhead and uneven regional support. Email alerts are already delivered to users and let Viollet ship a working beta without storing banking credentials.
- Turso + Drizzle for the data layer. A managed libSQL edge database keeps operational overhead low for a solo builder while Drizzle gives typed schema migrations and queries. The trade-off is designing ingestion to be idempotent and webhook-safe rather than relying on a single monolithic worker.
- AI-assisted categorization alongside parsing rules. Pure rules break when banks change templates or wording. The AI SDK helps classify ambiguous merchants and categories, with parsing constraints to keep outputs structured. The trade-off is monitoring quality and keeping prompts focused on financial metadata, not general inbox content.
- Clerk for authentication. Clerk reduced time-to-ship for session management and let me focus engineering time on Gmail sync and ingestion reliability. The trade-off is coupling auth to a hosted provider, acceptable for a beta where speed and security defaults matter.
6. Impact
Viollet is live at viollet.app as a free public beta. Users connect Gmail, select authorized financial senders, and get automated expense tracking from notifications. This replaces manual logging for the supported flow.
Public product scope today includes support for 15+ Dominican banks and cards (with evaluation for additional institutions that send email alerts), plus budgets, spending trends, and proactive insights derived from categorized transactions.
- Gmail → categorized spend automation with zero manual entry for connected accounts
- No online banking usernames or passwords collected
- Users can revoke Gmail access from Google or inside the product workflow
7. Assistant
The in-app assistant does not guess someone's finances. Each reply is grounded in tools over that person's rows: spend breakdowns, a financial overview, transactions, budgets, savings goals, and a few settings writes.
The panel below replays three answers from the same sample ledger as the landing demo. It shows the tool the production assistant would call. It does not contact a live model.
8. Operational quality
Because the product handles financial metadata, the implementation treats transport and storage carefully: encrypted data in transit and at rest, read-only Gmail scopes scoped to user-selected senders, and clear copy on the public site about Google's verification process for restricted permissions.
Ingestion is built for reliability at the webhook boundary: validate push deliveries, make writes idempotent where possible, and keep the parsing/categorization path isolated so a bad template does not corrupt unrelated user data.
- Google app verification completed; restricted Gmail scopes follow Google's security assessment cycle
- Public FAQ documents access, revocation, and data use without advertising resale
- Webhook + Pub/Sub path decouples mail delivery from request/response UI latency
9. Proof
Explore the live public beta at viollet.app. The source repository stays private during beta; this case study and the deployed product are the public evidence. I also wrote about expense tracking in the Dominican Republic on the Viollet blog.
viollet.app