Capstone Defense

Capstone Pitch

GharSetu — Localized PG & Room Rental Platform with ONDC Connectivity. Akshit Thakur · B.Tech CSE Cybersecurity · Shoolini University · May 2026.

Download .pptx Read full report

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

1 / 22 Download .pptx

navigate · F fullscreen · Esc exit