Proposly
Internal quoting and proposal tool for agencies. Reps build quotes from a product catalog, managers approve discounts, and clients accept branded proposals via a public link — all role-gated with real-time notifications and full audit trails.









The problem
Agencies that sell services through proposals typically rely on spreadsheets, PDFs, and email threads. There's no audit trail, no approval flow for discounts, no way for a client to accept inline, and managers have zero visibility into the pipeline. I wanted to build a tool that handles the full quote lifecycle — from draft to accepted — with proper role separation.
What I built
I built a role-gated proposal platform on Next.js 16 and Supabase with three user roles (admin, manager, rep), a quote versioning system, a discount approval workflow, and a public proposal page clients can accept without logging in.
- Quote builder with drag-to-reorder
Product search combobox, inline client creation, editable line items with dnd-kit reordering, auto-calculated discount/tax/totals, and margin summary visible only to internal users.
- Versioning and activity log
Every quote tracks numbered versions (V1, V2…). Only one version is active at a time. An immutable activity log records every event — created, sent, opened, accepted, rejected — with actor names and timestamps.
- Discount approval workflow
When a rep's discount exceeds the company threshold, the quote routes to managers for approval. Margin breakdown shows cost, revenue, and profit percentage with color-coded health indicators.
- Public proposal page
Clients receive a branded link (/p/{token}) — no login required. They see the proposal with company logo and accent color, then accept, reject, or ask a question. Open tracking fires on first view.
- Manager analytics
Date-range filtered dashboard with win rate, average quote value, time to close, and revenue charts built with Recharts. Managers see all reps' quotes; reps see only their own.
- Real-time notifications
Supabase Realtime subscription powers a notification bell with unread badge. Approval requests, decisions, quote opens, and client responses all trigger instant in-app notifications.
- 16-table schema with RLS
Company-isolated row-level security across all tables. Anon policies scope public proposal access. Deactivated users are blocked at the database level. 48-case security audit passed.
The result
The platform handles the full quote lifecycle — reps draft and send proposals, managers review discounts with margin visibility, and clients accept via a branded public page. Every action is audit-logged, role-gated, and company-isolated at the database level.