Capstone Defense
Capstone Pitch
GharSetu — Localized PG & Room Rental Platform with ONDC Connectivity. Akshit Thakur · B.Tech CSE Cybersecurity · Shoolini University · May 2026.
GharSetu
Apna kamra, apne sheher mein.
A Localized PG and Room Rental Platform for University Students,
with ONDC Connectivity
Capstone Defense · May 2026
Akshit Thakur · B.Tech CSE (Cybersecurity)
Yogananda School of AI, Computers and Data Sciences
Shoolini University, Solan, Himachal Pradesh
Apna kamra. Apna sheher. Apna ONDC.
The Problem
Why a localized rental platform, why now
Akshit Thakur · GharSetu Capstone · 2026
2 / 22
Scattered supply.
Listings live across WhatsApp groups, paper notices on hostel walls, and brokers. No single search.
No honest reviews.
Today's reviews are written by people who never paid rent there. Renters who actually lived in the room have no place to speak.
Deposit and quality fraud.
Promised amenities vanish on move-in day. Deposits get withheld. Day-scholar and out-of-town students absorb the loss.
From the founder
“Ye chiz bohot pareshan kerte hh day scholar students ko, islie maine ye topic socha.”
— Akshit Thakur, idea.md
The Insight
Three words that scope every product decision
Akshit Thakur · GharSetu Capstone · 2026
3 / 22
Localized
One radius. One campus. One city. The defaults are tuned for the place the student actually lives.
Federated
ONDC means one listing reaches every buyer-app on the network. The owner lists once, gets discovered everywhere.
Verified
Reviews carry a renter badge if the writer actually paid rent or the owner marked them. Outsiders can still speak; readers can still tell.
Every feature ships only if it serves Localized + Federated + Verified.
Vision
What a student should feel on day one
Akshit Thakur · GharSetu Capstone · 2026
4 / 22
Search a room near your campus in 30 seconds.
Trust because the reviews are from people who actually paid rent.
Pay safely on the platform.
List once, reach every ONDC buyer-app in the country.
Built for a slow phone, a flaky 2G connection, and a small-town budget.
Users and Roles
Three personas, one shared trust loop
Akshit Thakur · GharSetu Capstone · 2026
5 / 22
S
Student
Search by city, budget, gender pref.
Request a visit or reserve a room.
Pay rent on the platform.
Leave feedback (verified badge).
Verify identity via DigiLocker.
O
Owner
Create / edit / pause listings.
Receive booking inbox.
Accept or decline visit requests.
Mark a tenant as renter manually.
Track captured payments.
A
Admin
Live SIEM dashboard (audit log).
Filter by actor / action / entity.
Spot abuse, rate-limit hits, errors.
Inspect ONDC message timeline.
Read-only by design.
What's Been Built (MLP)
End-to-end, deployable, tested
Akshit Thakur · GharSetu Capstone · 2026
6 / 22
36
HTTP routes
10
DB tables
9
ONDC actions
2
languages
10/10
smoke tests pass
Surface
• Server-rendered EJS pages, mobile first.
• Search with city, budget, gender, amenities.
• Listings CRUD with image upload (sharp WebP).
• Bookings: visit + reserve, owner inbox.
• Razorpay rent payments (real-shape sim).
• DigiLocker KYC (real-shape sim).
• Verified-renter feedback engine.
Platform
• ONDC Beckn 1.2 endpoints (search→support).
• Bilingual EN + HI, RTL-ready, locale picker.
• WCAG 2.2 AAA: skip-link, focus, ARIA, contrast.
• Service worker shell + last 20 listings cache.
• Pino structured logs to stdout.
• Admin SIEM dashboard with live SSE feed.
• Cloud Run deploy via one shell script.
Live Demo
What you'd see on screen
Akshit Thakur · GharSetu Capstone · 2026
7 / 22
Home /
Hero, search bar, featured listings near Solan. 12KB HTML, 25KB CSS.
Search /search
Filters left, list + map toggle right. JSON API at /api/search.
Listing /listings/:id
Photos, map, amenities, verified-renter feedback first.
Book /bookings
Visit or reserve. Owner gets it in their dashboard inbox.
Pay /pay/:id
Razorpay-style order created. Webhook flips status to captured.
Admin /admin
Live audit feed, filter by action / actor, ONDC traffic visible.
Seeded credentials student@gharsetu.local / Student@2026! owner@gharsetu.local / Owner@2026! admin@gharsetu.local / Admin@2026!
System Architecture
One container, one process, zero idle cost
Akshit Thakur · GharSetu Capstone · 2026
8 / 22
Browser
(mobile, 2G ok)
EJS + 0 framework JS
Cloud Run (asia-south1)
Fastify 5 + Node 22 LTS
EJS SSR
zod validation
JWT cookie auth
pino JSON logs
SQLite
/tmp/gharsetu.db
ephemeral, seeded on cold start
/tmp/uploads
sharp → WebP @ q=78
ONDC peers (BAP / BPP)
POST /ondc/v1/search...support → ACK + async on_*
Razorpay (sim)
Order create + webhook HMAC-SHA256 → payment.captured
DigiLocker (sim)
OAuth 2.0 PKCE flow → callback → kyc_verified=1
Data Model
Ten tables. The trust badge is the centrepiece
Akshit Thakur · GharSetu Capstone · 2026
9 / 22
users
id, email, role, kyc_verified, kyc_method
listings
id, owner_id, city, lat, lng, rent_monthly, status
listing_images
id, listing_id, url, position
bookings
id, listing_id, student_id, type, status
payments
id, listing_id, payer_id, rzp_order_id, status
renter_records
id, listing_id, student_id, source, active
feedback
id, listing_id, author_id, rating, is_verified_renter
audit_log
id, actor_id, action, entity, payload
ondc_messages
id, txn_id, message_id, action, direction
sessions
jti, user_id, revoked, expires_at
Trust flow
payments
renter_records
feedback
Owner UI
POST /owner/listings/:lid/renters source = owner_marked
renter_records is the single source of truth for the verified-renter badge.
The Verified-Renter Trust Mechanism
Outsiders may speak. Readers can tell who actually lived there.
Akshit Thakur · GharSetu Capstone · 2026
10 / 22
is_verified_renter = EXISTS (
SELECT 1 FROM renter_records r
WHERE r.listing_id = :listing_id
AND r.student_id = :author_id
AND r.active = 1
AND r.source IN ('platform_payment', 'owner_marked')
)
Path A · platform_payment
Razorpay webhook HMAC-verifies, marks payment captured, auto-inserts a renter_record. The student gets the badge automatically.
Path B · owner_marked
Owner taps Mark Renter for a tenant who paid offline. Same renter_record is written. Same badge surfaces on review.
Why this matters
Outsider reviews still count for visibility, but the reader sees a coloured badge next to verified ones. No moderation team needed.
ONDC Beckn Simulation
Nine inbound actions, async on_* callbacks, full message log
Akshit Thakur · GharSetu Capstone · 2026
11 / 22
Buyer App
GharSetu /ondc/v1/search
ondc_messages
search { context, message.intent }
200 ACK
INSERT direction='in'
INSERT direction='out' (on_search)
POST {bap_uri}/on_search { catalog }
Implemented inbound endpoints (each replies on_*)
search
select
init
confirm
status
cancel
update
rating
support
GET /ondc/v1/lookup — subscriber metadata for the registry
Production swap: subscribe with the ONDC registry, sign every request with Ed25519 + SHA-512, route via the Gateway. Schemas already match.
Razorpay Payment Simulation
Real-shape Orders API + HMAC-verified webhook
Akshit Thakur · GharSetu Capstone · 2026
12 / 22
// POST /pay/order --> Razorpay Orders API shape
{
id: "order_01HXY...",
entity: "order",
amount: 500000, // paise
currency: "INR",
status: "created",
receipt: "bk_<bookingId>",
notes: { listing_id, payer_id, payee_id }
}
// POST /pay/webhook --> HMAC-SHA256 verify
const expected = createHmac("sha256",
config.RZP.WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
if (!timingSafeEqual(
Buffer.from(expected),
Buffer.from(req.headers["x-razorpay-signature"])))
return reply.code(400).send();
// captured --> insert renter_record (source=platform_payment)
payment.captured
payments.status = captured
renter_records inserted
verified badge unlocked
Production swap: real Razorpay keys + real x-razorpay-signature header. Code path is identical.
DigiLocker KYC Simulation
OAuth 2.0 PKCE flow, sanitized payload only
Akshit Thakur · GharSetu Capstone · 2026
13 / 22
Student
GharSetu /verify
DigiLocker (sim)
POST /verify/digilocker/init
302 redirect (state, code_challenge S256)
consent screen + confirm
GET /verify/digilocker/callback?code=SIM_...
verify state, exchange code, fetch eAadhaar (sim)
store sanitized payload → kyc_verified=1
redirect to /student/dashboard + flash 'verified'
Sanitized payload stored
{ method: 'digilocker_simulated', verified_at, aadhaar_last4: '1234', name_on_id, dob_year }
Production swap: real CLIENT_ID / CLIENT_SECRET + PKCE verifier persistence. kyc_verified drives the trust badge across the app.
Performance for Slow Phones
Designed against a 2G connection on a budget Android
Akshit Thakur · GharSetu Capstone · 2026
14 / 22
12 KB
Home HTML
gzipped
25 KB
Critical CSS
single file
0 KB
JS framework
vanilla only
78
WebP quality
via sharp
~5 s
Cloud Run cold
min=0 always
Engineering decisions that earned those numbers
• Server-rendered EJS — the page is interactive before any JS parses.
• Leaflet + OSM tiles loaded only on map pages, lazy from CDN with SRI.
• Sharp re-encodes uploads to WebP at quality 78. Listing page weighs in well under 200 KB.
• Service worker caches the app shell + last 20 listings. Repeat search works offline.
• Cloud Run gzips by default. min-instances=0 = zero rupees idle.
• No client bundler, no dependency tree to ship. The browser pays only for what it uses.
Accessibility (WCAG 2.2 AAA)
Equal usability for blind, deaf, motor, low-vision, cognitive, ADHD users
Akshit Thakur · GharSetu Capstone · 2026
15 / 22
Vision
• Contrast ≥ 7:1 every text element.
• Visible focus ring ≥ 3:1 via :focus-visible.
• Skip-to-content as first focusable.
• ARIA labels on icon-only buttons.
• <html lang> set per request.
Motion / cognition
• prefers-reduced-motion respected.
• forced-colors mode supported.
• No autoplay, no time-pressured forms.
• Form errors via aria-describedby.
• Plain language in EN + HI.
Locale and direction
• Bilingual EN + HI from launch.
• Locale picker in nav, cookie + query param.
• RTL-ready: dir attribute per locale.
• Mangal / Nirmala UI fallback for Devanagari.
• Tested on NVDA / Firefox + VoiceOver / Safari.
Goal: works on a slow phone, on a small-town network, for everyone.
Security
Defence in depth, no exceptions, every layer hostile to the layer above
Akshit Thakur · GharSetu Capstone · 2026
16 / 22
bcrypt cost 12 + password ≥ 10 chars
Password hashing tuned for 2026 hardware.
JWT HS256 in HttpOnly Secure SameSite=Lax cookie
Server-side sessions table allows revocation.
CSRF double-submit token (gs_csrf)
@fastify/csrf-protection on every state-changing POST.
Parameterised SQL only, zero string concat
better-sqlite3 prepared statements throughout.
zod validation at every request boundary
Body, query, params parsed before any handler runs.
audit_log on every mutation
actor, ip, ua, sanitized payload — visible in /admin.
Rate limit 200 req / minute / IP
via @fastify/rate-limit, /healthz allow-listed.
Secrets in Google Secret Manager
Cloud Run mounts JWT_SECRET, RZP_*, DIGILOCKER_*, ADMIN_PASSWORD.
HSTS, X-Content-Type-Options, Referrer-Policy
Set globally. HTTPS by default on Cloud Run.
PII never in logs or URLs
Stack traces visible only to admin.
Observability
Verbose for the admin, silent for the user
Akshit Thakur · GharSetu Capstone · 2026
17 / 22
// pino structured log line
{ "level":30, "time":1714660800000, "reqId":"01HX...",
"method":"POST", "url":"/bookings", "status":302, "ms":42,
"user_id":"01HX...", "ip":"203.0.113.4", "ua":"Mozilla/5.0..." }
Every request
ULID req-id, method, url, status, ms, user, ip, ua.
Every mutation
audit_log row: actor, action, entity, payload (sanitized).
/admin SIEM
Filterable timeline + Server-Sent Events live feed.
Probes
/healthz returns ok shape. /readyz checks DB + uploads dir.
User sees friendly error + correlation ID. Super-admin sees stack, request, payload, and the audit trail — same correlation ID joins them.
Cloud Logging picks pino JSON automatically; alert policy on 5xx ratio.
Cloud Run Deployment
One container, one shell command, asia-south1 region
Akshit Thakur · GharSetu Capstone · 2026
18 / 22
$ ./deploy.sh PROJECT_ID
enabling APIs...
creating Artifact Registry repo gharsetu-images
ensuring 5 secrets in Secret Manager
granting roles/secretmanager.secretAccessor
submitting cloudbuild.yaml...
Service URL: https://gharsetu-...run.app
# cloudbuild.yaml steps
1. docker build --tag :$SHORT_SHA :latest
2. push :$SHORT_SHA to Artifact Registry
3. push :latest
4. gcloud run deploy gharsetu
--region asia-south1
--memory 512Mi --cpu 1
--min-instances 0 --max-instances 10
~631 MB
image size
~5 s
cold start
₹0
idle cost
80
concurrency
5
secrets mounted
Re-deploy after a code change is the same one command. Idempotent end to end.
JWT_SECRET, RZP_KEY_SECRET, RZP_WEBHOOK_SECRET, DIGILOCKER_CLIENT_SECRET, ADMIN_PASSWORD — all from Secret Manager, never in image.
Testing
npm test — 10 smoke checks, all green
Akshit Thakur · GharSetu Capstone · 2026
19 / 22
✓
GET /healthz returns ok
✓
GET / serves the home page
✓
GET /search lists Solan listings
✓
GET /api/search?city=Solan returns JSON
✓
Signup + login issues a session cookie
✓
Authenticated student can POST /bookings
✓
POST /pay/order returns an order_id
✓
POST /ondc/v1/search returns ACK
✓
GET /admin without admin cookie is blocked
✓
GET /healthz body shape is { ok: true }
10 / 10 passed — every prod bug becomes a regression test here.
Server is spawned per run on an ephemeral port + ephemeral SQLite + ephemeral uploads dir.
npm run lint = tsc --noEmit (strict) npm run build = full transpile, runs in <2s.
What's Next
After the capstone, before a real launch
Akshit Thakur · GharSetu Capstone · 2026
20 / 22
Production ONDC subscription
Register with the ONDC registry, generate Ed25519 + X25519 keys, sign every request.
Cloud SQL for PostgreSQL
Move off ephemeral SQLite. Schema is portable; swap better-sqlite3 for pg.
Mobile app
PWA first (the SW is already wired); evaluate React Native for native push.
Owner WhatsApp notifications
Booking and payment events delivered where owners actually read.
Photo verification
Owner-uploaded shots geo-checked and timestamp-checked before publish.
Neighbourhood chat
Per-area channels for current renters — keeps the trust loop alive after move-in.
Payment escrow
Hold the first month + deposit until the renter checks in. Fraud-proofs the deposit.
Learnings
What this capstone taught me
Akshit Thakur · GharSetu Capstone · 2026
21 / 22
Engineering
• Strict-mode TypeScript across server + lib.
• Native-cloud first: Cloud Run, Secret Manager, Artifact Registry, Cloud Logging.
• Protocol design: Beckn / ONDC contract rather than ad-hoc API.
• WCAG 2.2 AAA as a build constraint, not an afterthought.
• Observability: structured logs + audit trail + SIEM dashboard.
Process
• Spec-first: SPEC.md drove every contract and table.
• Agent-coordinated parallel workstreams kept progress unblocked.
• Ephemeral-first MVP: no infra to manage during the build.
• Deploy script idempotent from day one — re-run is the workflow.
• Smoke suite as the safety net while iterating fast.
Personal
• Shipping > perfection. A working slow phone trumps a beautiful demo.
• Reading other people's APIs (Razorpay, ONDC, DigiLocker) is half the job.
• Real users are not me: i18n + accessibility from day zero.
• Document why, not what — README is the artefact reviewers actually read.
• A capstone is an opening move, not a closing one.
Thank you.
Questions, please.
Akshit Thakur
B.Tech CSE (Cybersecurity) · Shoolini University, Solan
github.com/akshit-thakur · akshit.thakur@shoolini.edu.in
GharSetu
Apna kamra, apne sheher mein.
Akshit Thakur · GharSetu Capstone · 2026
← → navigate · F fullscreen · Esc exit