CASE STUDY
Wholesale travel · Node.js · Express · React · PostgreSQL · Prisma · JWT
B2B Travel Portal
Built by me
Client details confidential
Production release not claimed
A role-based portal where a wholesale travel operator publishes packages and visa services to partner travel agencies, and each agency quotes its own customers at its own margin.
The problem
Wholesalers sell packages and visa services through partner agencies. Every agency needs its own markup and its own branded quotations, while the wholesaler's cost price and branding must not leak into what the agency's customers receive.
What I implemented
Express/Node.js REST APIs with JWT authentication and role-controlled operations; a React front end; a PostgreSQL schema managed through Prisma; agency-specific markup calculation; white-label PDF quotations; and the package and visa-request workflows.
Roles and data model
Three roles — admin, data-feeder and partner agency — each limited to its own operations. Packages and visa requests carry wholesale values; an agency's markup produces the price it quotes. Quotations store snapshots of price and itinerary at generation time, and records are soft-deleted rather than removed.
Engineering decisions
Historical snapshots, so editing a package later never rewrites a quotation already issued. Soft deletion, to keep past quotations and requests intact. Separate roles for the people who enter data, the people who sell, and the people who administer.
Edge cases and testing
Found and corrected a payment amount-due defect involving wholesale versus marked-up prices. Inspected generated quotation PDFs for unwanted wholesaler branding. Confirmed that historical quotation values are preserved through snapshots. These were hands-on reliability checks; no claim is made here about automated test coverage.
Verified delivery status
Approved for technical discussion. Not claimed: client acceptance, commercial operation, live payment processing, production release. Withheld: customer identities, pricing, contracts, screenshots and the private repository.
Private repository · technical walkthrough on request
FEATURED
2026 · Python · FastAPI · PostgreSQL · MinIO
File Vault
Independent prototype
Public repository
A multi-tenant file-service prototype. A control-plane registry tracks organisations; each organisation gets its own PostgreSQL database and its own MinIO bucket, selected by the organisation slug in the URL. Uploads stream to object storage with SHA-256 hashing, MIME checks and size limits. I verified data separation manually and diagnosed a schema-provisioning problem along the way.
Known limits, stated up front
- No authentication or per-tenant authorization yet. Separate databases isolate stored data, but they do not stop a caller from naming another organisation's slug. This is not a production-secure SaaS.
- No automated tests and no CI; separation was checked by hand.
- The orphan-file cleanup script covers only the default bucket, not every organisation.
- The repository README still describes the earlier single-tenant version.
FastAPIPostgreSQLMinIOMulti-tenancyDocker
GITHUB ↗
Limits checked against the repository, 13 Oct 2026
FEATURED
2026 · Next.js 16 · PostgreSQL 17 · Drizzle ORM · Better Auth
Travel CRM SaaS
In development
Private repository
A multi-tenant CRM for travel agencies and tour operators. The platform foundation is in place: email-verified sign-in, organisations with memberships and role-based access, invitation workflows, an append-only audit log, idempotency and rate-limiting infrastructure, a money library, and PostgreSQL row-level security exercised against a restricted runtime role. The repository defines CI that runs lint, type checks, unit and database-integration tests, and Playwright end-to-end tests.
Scope today
- Quotation, booking and finance modules are planned, not built.
- Not an operating commercial SaaS; no production or customer claims are made.
Next.jsTypeScriptPostgreSQL RLSDrizzleBetter AuthPlaywright
Private repository · code walkthrough on request
FEATURED
2026 · Next.js · TypeScript · Google Apps Script
CareerSpoc Enquiry Workflow
Workflow engineering
Public repository
Enquiry handling for CareerSpoc, an initiative of Lex Foundation. A Next.js contact route validates input (with a honeypot field and per-IP rate limiting) and forwards it to a Google Apps Script endpoint, which logs each enquiry to Google Sheets and sends an admin notification email. A failed notification email cannot fail the sheet write.
Verification status
- Behaviour described from the repository source. Live end-to-end email delivery has not been demonstrated on this page.
Next.jsApps ScriptGoogle SheetsValidation
FEATURED
2025 & 2026 editions · Website · Vercel
ICIEM Conference Website
Public website
Stakeholder delivery
Public website for the International Conference on Innovation, Engineering and Management: information architecture, conference content, and clear guidance and links to the organisers' external registration and paper-submission processes. I built and deployed the site and coordinated updates with the organising team as the event evolved. Registration and submission are handled by those external services, not by the site itself.
WebsiteContent architectureDeployment
SUPPORTING
Event programme · Registration workflow
Varsha Mangal Mahotsav
Supporting example
Delivery status unconfirmed
Registration-workflow engineering for an event programme: duplicate-email checking, certificate identifiers, a live-statistics endpoint and a confirmation-email workflow. Delivery status of the backend is not confirmed for this page, so it is shown as workflow-engineering evidence and not as a live system.