Siddharth Sanghavi
PROJECT · FULL-STACK WEB

simpleCRM

A lightweight CRM for a student club running outreach to companies for plant tours and sponsorships. Tracks companies, the people at them, every touch, and what you owe them next — built for about five users, entirely on free tiers, with access rules enforced in the database rather than in application code.

ROLESole developer
TYPEFull-stack web app
USERSStudent club
COST$0 / month
01

Why it exists

A club chasing company tours and sponsorships runs the same problem a sales team does — who have we contacted, who replied, what did we promise, what is going cold — but with none of the budget and a membership that turns over every year. Commercial CRMs are priced per seat and assume the team persists.

simpleCRM is sized for that: about five people, free tiers end to end, and documentation written on the assumption that whoever inherits it has never seen the code. The handover problem was treated as a design constraint, not an afterthought.

02

Screens

03

What it does

PIPELINE
Companies move across a draggable board. Each carries an amount and a close date, which feed a weighted funnel — so the number at the top reflects probability, not wishful thinking.
CONTACTS AS A TREE
People are stored with their reporting lines intact rather than as a flat list, so it is obvious who sits above the person who has gone quiet. Deal roles sit on the contact.
MAP & CALENDAR
Geocoded companies on a clustered Leaflet map for planning trips, and a calendar for tours and events.
COLD EMAIL DRAFTS
Drafts generated from templates the club edits itself. The app never sends mail on anyone's behalf — it hands you text.
ACTIVITY FEED
Every action anybody takes lands in one feed, logged by database trigger — so a change made directly in the SQL editor is recorded exactly like one made in the app.
DELETION QUEUE
Deletes are narrower than writes. Any member can edit; only the record's creator or an admin can delete, and company deletions go through an approval queue with a permanent record.
IMPORT / EXPORT
CSV import for companies and contacts, bulk geocoding, and export back out — so the club's data is never trapped in the app.
04

Security model

The interesting constraint was that volunteers would be editing this, so application code could not be the thing standing between a bug and the club's contact list. Authorisation lives in Postgres instead.

ROW-LEVEL SECURITY
Every policy requires a profile row, so access is decided by Postgres. A bug in a page cannot leak data that RLS would not have handed over.
NO SERVICE-ROLE KEY
The app only ever holds the anon key, which grants nothing on its own. There is no credential in the repository that can bypass RLS.
MAGIC LINKS ONLY
No passwords are stored, so there are no passwords to leak. An address must be on an allowlist before a profile exists for it.
THREE ROLES
Viewer reads and writes nothing, member reads and writes, admin also manages people. Reads go through has_access() and writes through is_member() — hidden buttons are only a courtesy.
05

Built with

Next.js 15 React 19 TypeScript Supabase / Postgres Tailwind Leaflet Vercel

App Router with server actions, Supabase for Postgres and magic-link auth, Leaflet with marker clustering for the map, and Papa Parse for CSV import. Free tier throughout — 500 MB of Postgres holds hundreds of thousands of contacts, which the club will not outgrow.