Trusted local recommendations from your society WhatsApp group, kept searchable and pinned.
Coverage scope: server-side API guard logic only — component and e2e coverage tracked separately, not yet in CI.
Note
Current phase: Phase 0 — Demand Validation. The live site at vouchlist.lovable.app is a smoke-test landing page, not the finished product. It exists to measure real interest — page visits, CTA clicks, waitlist signups, geographic distribution — before the WhatsApp bot is built. No bot exists yet. No pilot has run. No society has used this. If you are here to see a working bot, it has not been built yet by design.
This GitHub repository is a curated public mirror, not a runnable clone. The authoritative, deployed, and Lovable-synced codebase lives on Lovable's own hosted infrastructure. This repo is a deliberately modified copy published for portfolio and code-review purposes. Cloning it will not produce a fully working local instance — missing backend credentials and environment config are expected and by design, not bugs.
Structured, hyperlocal trust, without leaving the chat you already use.
This repository contains the marketing and waitlist website for VouchList: a WhatsApp-native bot that turns the recommendations neighbours already give each other into a permanent, searchable, pinned list inside the same group.
Owned and built by Vikas Dayashankar Sahani. Contact: vikassahani17@gmail.com.
Click to walk through the full capture and retrieval loop — resident asks, neighbour vouches, VouchList remembers.
In dense residential clusters along the Andheri to Borivali corridor of Mumbai, residents rely on WhatsApp society groups to find trusted local services (electricians, cooks, tutors) and to borrow occasional-use items. Those recommendations are high value but ephemeral. Within days they are buried under unrelated chat volume, they are unsearchable, and they carry no persistent verification signal.
The result is information decay. Residents re-ask questions their group has already answered, and under time pressure they default to unverified providers found through search engines or referral apps, even though a trusted answer already exists in their own chat history.
Three groups feel this most sharply:
- Residents making urgent, low-stakes service decisions under time pressure.
- Newcomers with no chat history, who must cold-ask the group and absorb the social cost.
- Society admins fielding repeat questions and manually re-pinning stale lists.
The blocker to solving this is not the absence of a platform. It is switching cost. Every standalone neighbourhood app asks residents to move their trust somewhere new, and that is where adoption dies.
VouchList makes the opposite bet: keep the channel, fix the failure mode. The bot detects recommendation-style messages, prompts the responder to structure the answer in one tap, and resurfaces it later as a permanent entry scoped to that group. No new app, no behaviour change, no switching cost.
- Cut time-to-decision for residents seeking a locally trusted service or item by making prior recommendations searchable and persistent.
- Increase the share of local requests resolved with existing group knowledge instead of external search or repeated re-asking.
- Reach adoption with zero incremental install friction by operating natively inside WhatsApp.
- Validate a repeatable, low-cost per-society activation motion beyond the pilot corridor.
North Star metric: Resolved Asks. The number of local requests where a resident consulted or received a structured VouchList entry that satisfied the request, rather than re-asking live or leaving the group to search. Engagement volume is deliberately not the goal; retrieval that beats scrolling is.
Payments or invoicing between residents and vendors, an asset-lending marketplace, skill exchange and time banking, cross-society list aggregation, and a standalone destination app. Each is documented as a rejected direction rather than a missing feature.
This is the public website, not the bot. It explains the product, the trust model and the rollout, and it collects waitlist signups from society residents and admins.
| Route | Purpose |
|---|---|
/ |
Product story, conversation demo, waitlist |
/features |
Capability breakdown |
/how-it-works |
The capture and retrieval loop |
/communities |
Who VouchList is built for and pilot scope |
/trust |
Privacy, moderation and data handling |
/faq |
Common questions, mirrored in FAQPage structured data |
Every page also carries site search. Press Ctrl K (or Cmd K), or use the search control in the
header, to jump straight to a section. The index is bundled with the app and ranked locally with a
small typo tolerant matcher (src/lib/fuzzy.ts), so results appear on the first keystroke with no
network request and queries such as "plumbr" or "privcy" still find the right page.
| Layer | Technology | Version |
|---|---|---|
| Framework | TanStack Start (file routing, server functions, SSR) | 1.168 |
| Routing | TanStack Router | 1.170 |
| UI | React | 19.2 |
| Language | TypeScript | 5.8 |
| Build | Vite | 8.1 |
| Styling | Tailwind CSS with OKLCH tokens in src/styles.css |
4.2 |
| Animation | Motion (Framer Motion) | 12.43 |
| Backend | Lovable Cloud (Postgres, row level security) via Supabase JS | 2.110 |
| Validation | Zod | 3.24 |
| Charts | Recharts | 2.15 |
| Unit tests | Vitest | 4.1 |
| Browser tests | Playwright | 1.56 |
| Runtime | Node.js | 20 or newer |
Requires Node.js 20 or newer.
git clone https://github.com/VIKAS9793/vouchlist.git
cd vouchlist
npm install
npm run dev # http://localhost:8080
npm run build # production build
npm run lintEvery push and pull request to main runs .github/workflows/ci.yml: lint, unit tests with
coverage, and a production build. The CI badge above reflects that workflow, and the coverage
badge is regenerated from the Vitest line coverage of src/lib on each successful main build.
Run before publishing. Details in docs/engineering/QUALITY-GATES.md.
npm test # unit tests
npm run test:coverage # unit tests with a coverage report in coverage/
npm run coverage:badge # refresh .github/badges/coverage.svg from that report
npm run qa:all # copy, SEO, link, security-header, dependency, accessibility, smoke and performance checks
npm run qa:copy # grammar, punctuation and formatting of on-page prose
npm run qa:copy:ai # optional AI-assisted grammar review
npm run qa:seo # titles, descriptions, canonicals, headings, JSON-LD, sitemap
npm run qa:links # broken internal links, assets and sitemap entries
npm run qa:security # CSP, HSTS, X-Frame-Options and related response headers
npm run qa:deps # dependency vulnerability scan, fails on high and critical advisories
npm run qa:secrets # .gitignore coverage and hardcoded credential scan
npm run qa:spam # waitlist bot detection and rate limiting guards
npm run qa:a11y # WCAG 2.2 AA audit of every public route (axe-core, desktop and mobile)
npm run qa:a11y:forms # WCAG 2.2 AA audit of the waitlist form, including its error states
npm run qa:e2e # Playwright smoke tests: pages load clean, CTAs work end to end
npm run qa:perf # Lighthouse budgets on a production build: LCP < 2.5s, score > 95
npm run qa:perf:dashboard # audit, then render reports/perf/dashboard.html for triage
npm run qa:perf:report # re-render the dashboard from the last stored reportsCI-enforced (runs on every push/PR): lint, test:coverage, coverage:badge, build.
All qa:* scripts below are manual pre-release gates, not part of the automated CI pipeline.
Run them locally before publishing a significant change; see docs/engineering/QUALITY-GATES.md for what each enforces.
qa:perf stores each run under reports/perf/, and the dashboard turns those runs into a
single page showing the Lighthouse score dial and the LCP bar against budget for every route,
sorted slowest first, with a sparkline of the last twenty runs so regressions are obvious.
Security headers (Content Security Policy, HSTS, X-Frame-Options, X-Content-Type-Options,
Referrer-Policy, Permissions-Policy, COOP and CORP) are defined in
src/lib/security-headers.ts and applied to every response in src/server.ts.
The Content Security Policy uses a fresh per-request nonce instead of 'unsafe-inline': every
inline script and style is stamped with that nonce as the response is streamed, and the QA gate
fails if 'unsafe-inline' ever returns to script-src or style-src.
Dependencies are scanned in the same pass: qa:deps checks every package in bun.lock against
the public npm advisory database and fails on high or critical findings. Accepted risks are
recorded with a reason in scripts/deps-allowlist.json.
Secret hygiene is enforced by qa:secrets. It checks that .gitignore still covers caches,
build output, local env files, certificates and private keys, scans the source tree for
hardcoded credentials (private key blocks, service-role JWTs, provider tokens), and flags any
non publishable variable in .env. Only publishable Lovable Cloud values belong in .env;
every private credential is stored as a project secret and read from the server runtime.
Waitlist signups are spam protected. The browser can no longer write to the waitlist store at
all: submissions go through a server function that revalidates the input, runs bot detection
(hidden honeypot field, minimum fill time, link and disposable-address filters) and applies
rolling rate limits per address and per email, recorded as hashed buckets so no raw address or
email is ever logged. qa:spam exercises those guards, and the Playwright suite submits a real
bot-shaped signup to prove it never reaches the store.
The site ships light and dark themes. It follows the operating system by default, and the theme control in the header lets a visitor pin Light, Dark or System. The choice is stored locally and applied before first paint, so returning visitors never see a flash of the wrong theme. Both themes are contrast-audited by the accessibility gate.
src/routes/ file-based routes, per-route SEO metadata and JSON-LD
src/components/ sections/ (page blocks), site/ (shell), waitlist/, ui/ (shadcn)
src/lib/ breadcrumbs, request origin server function, shared API guard, helpers
scripts/ copy, SEO, link, security, accessibility and performance QA gates
e2e/ Playwright smoke tests (page loads and CTA flows)
public/ robots.txt, logo, static assets
docs/ docs/product/ (PRD, one-pager, GTM, product context) and docs/engineering/ (API guard, quality gates)
- Source: https://github.com/VIKAS9793/vouchlist
- Clone:
git clone https://github.com/VIKAS9793/vouchlist.git - Live site: https://vouchlist.lovable.app
- docs/product/PRODUCT.md: personas, competitive landscape, metrics, rollout, risks
- docs/engineering/QUALITY-GATES.md: what each pre-publish check enforces
- docs/engineering/API-GUARD.md: how to guard a new
/api/public/*endpoint and which options to set for each access level
This is a product management case study and demand-validation project. The waitlist landing page is live to track genuine interest from society residents and admins before any product is built. No bot is currently in development or deployment. The case study documents the full product thinking — problem, personas, metrics, roadmap, and risks — as an independent PM portfolio exercise.
Build process: the website was scaffolded with AI assistance via Lovable, a product-development platform. The author directed all architecture, product, and security decisions; reviewed and edited generated output; wrote the PRD, GTM plan, QA scripts, and security policy; and owns all product direction. The codebase is not hand-typed line by line, nor was it generated without review — the actual division of labor is: AI-assisted scaffolding under continuous human direction.
Last reviewed: July 2026.
Product, content and code direction by Vikas Dayashankar Sahani (LinkedIn, GitHub, portfolio). Copyright 2026, all rights reserved.

