Cotizly
A multi-tenant SaaS that turns scattered quote spreadsheets into a single flow — build a quote, walk it through its lifecycle, and convert the approved one into a real order, per company.
Most of the money a small business loses between “here’s your quote” and “here’s your invoice” doesn’t disappear in one big mistake — it leaks. A price lives in one spreadsheet, the client’s details in another, the approved version in an email thread, and the order gets re-keyed by hand into a third place where a digit quietly changes. The quote was right; the order wasn’t; nobody can say where it drifted.
Cotizly closes that gap. It’s a web SaaS that lets a company build quotes, move them through a real lifecycle, and convert the approved ones into orders — all in one place, with the numbers carried across instead of retyped.
What it does
- Per-company workspace. Each company logs in to its own space — its users, its clients, its catalog. Nothing bleeds across tenants.
- Catalog management. Products and categories are managed per company, with images, so a quote is built from real items at real prices, not free text.
- A dynamic quote builder. Pick a client, pull products from the catalog, set quantities — subtotal, tax and total are computed as you go, and the server refuses to save a quote whose numbers don’t add up.
- A quote lifecycle. A quote isn’t just “open” or “closed.” It moves through draft → pending → approved (or rejected / expired), and only along transitions the system actually allows.
- Quote → order conversion. An approved quote becomes an order that stays linked back to the quote it came from — the audit trail the email thread never had.
- Filterable, exportable history. Every quote is searchable, and any one can be exported to PDF or Excel for the client or the records.
- A dashboard. Counts of products, clients and quotes, quotes broken down by status, and the most recent activity — the at-a-glance the spreadsheet couldn’t give.
Under the hood
The interesting part is that Cotizly is a real multi-tenant SaaS, and the isolation is enforced where it counts — on the server.
Tenant isolation as a guard, not a convention. Company scoping isn’t left to
the UI hoping to send the right ID. A dedicated CompanyIsolationGuard compares
the company on the authenticated user against the company in the request — route
and body — and rejects any attempt to read or write another tenant’s data, even
if the IDs are mismatched on purpose. Every service query is additionally scoped
by companyId, so a client, product or quote can only ever be touched by the
company that owns it.
The quote lifecycle is modeled, not implied. Status is a typed enum, and the allowed moves between states live in an explicit transition table on the server. Ask for an illegal jump — say, reviving a rejected quote — and the API tells you exactly which transitions are valid instead of silently corrupting the record.
Writes are transactional and self-checking. Creating or editing a quote runs inside a database transaction: relationships (company, user, client, every product) are validated, items are saved, and the totals are recomputed and reconciled against what the client sent within a tolerance — the server is the source of truth on money, not the browser.
A typed NestJS API. The backend is strict-TypeScript NestJS over TypeORM / PostgreSQL, with JWT access + refresh tokens (Passport), role-based guards (admin / manager / user), and a soft-delete-and-restore model on core entities so nothing is ever truly lost. Redis backs a response cache — with single-flight locking so a cold key doesn’t stampede the database — and the rate limiter. The surface is hardened with Helmet, request-context IDs, global validation and a documented Swagger / OpenAPI spec.
The stack
- Frontend — Angular 19 with Tailwind CSS and Angular Material/CDK, RxJS; client-side PDF (jsPDF) and Excel (SheetJS/xlsx) export. Deployed on Firebase Hosting.
- Backend — NestJS in strict TypeScript, REST documented with Swagger/OpenAPI.
- Data — PostgreSQL via TypeORM; Redis for response caching and rate-limit storage.
- Auth & security — JWT access/refresh with Passport, role-based access control, bcrypt, Helmet, throttling, a per-company isolation guard.
- Ops — multi-stage Docker build with a non-root user and a health check, container-ready for Railway-style deploys.
Worth noting
I built Cotizly solo, end to end — frontend, backend and database. It’s a personal product, currently on pause rather than in active development.
What makes it worth a look isn’t a long feature list — it’s the discipline underneath a fairly small product. Multi-tenant isolation enforced on the server, a quote lifecycle modeled as explicit, validated state transitions, money recomputed server-side rather than trusted from the client, and caching that fails open if Redis isn’t there — these are the decisions that separate a demo from something a business could actually run its quoting on without quietly losing money in the gaps.
Coffee & talk?
Like what you just read? I build products like this end to end — and I'm always up for a conversation. Let's talk about yours, or just trade notes over coffee.