CodeveilStudio

Engineering digital products with design precision.

All work
Case studywebsaas

QResolve

QR-based asset fault reporting, ticketing and a programmatic SEO marketplace for India’s maintenance industry

Visit live project
Feb to Jun 2026
~4 months
Commits
76
Programmatic SEO pages
~108
Supabase Edge Functions
6
QResolve

Overview

QResolve is a two-product platform for India's facility and asset maintenance market. The Directory is a public, SEO-driven listing of verified providers; Relay is a multi-tenant operations console with QR-tagged assets, no-login public fault reporting, ticket triage, AI insights and Razorpay subscription billing. They share one Supabase project and form a deliberate flywheel: the directory generates leads for providers, providers adopt Relay to handle them, measurable ticket throughput earns a "Verified by Relay" badge, and the badge lifts directory ranking.

Two products, one platform

QResolve Directory

qresolve.com

A public, SEO-driven directory of verified maintenance providers across 12 service categories and 8 metros.

Next.js 16 (App Router), React 19, Tailwind v4

QResolve Relay

relay.qresolve.com

A multi-tenant SaaS operations console — QR-tagged assets, no-login public fault reporting, ticket triage, AI insights and Razorpay subscription billing.

Vite + React 18 + TypeScript, Supabase

The challenge

A whole industry running on WhatsApp threads and spreadsheets

India's maintenance market — lifts, HVAC, EV chargers, vending machines, fire safety, CCTV — runs almost entirely on WhatsApp threads, phone calls and spreadsheets. QResolve was scoped to attack three compounding failures at once: a frictionless public reporting surface, an auditable ticket system behind it, and a discovery front end that rewards the operators who actually use the system.

  • Reporting friction — the person who notices a broken lift is almost never a system user, so any flow needing an app install or login simply does not get used
  • No accountability trail — a fault reported over WhatsApp has no ticket ID, no priority and no timestamped resolution, so providers cannot prove SLA performance
  • No discovery layer — facility managers searching for "lift maintenance in Pune" find directory spam, not operators with demonstrable track records

What we built

Two frontends, one Postgres database, and authorization enforced in the database itself

The directory needs server-side rendering for Google; the operations console needs a fast, stateful SPA. Splitting them meant each could use the right tool without compromise, while providers, profile claims, assets and issues stayed in a single Postgres schema — no sync layer, no data drift.

Every operation requiring a secret — Razorpay keys, the Gemini key, service-role database access — lives in a Deno Edge Function, so the browser never holds anything more sensitive than the Supabase anon key and the public Razorpay Key ID. Tenancy isolation is enforced in Postgres RLS policies rather than application code, so a bug in a React component cannot leak another organization's assets.

What we delivered

The public reporting flow

The single most important screen in the platform, and the only one designed for someone who will use it exactly once. No app, no signup, no login — a QR sticker opens a two-step mobile form. The QR URL carries asset name, location and org ID as query params alongside the UUID, so if the database fetch fails on flaky venue Wi-Fi the form still renders with real context instead of a dead end. Asset types define their own fault options, photo evidence uploads to Supabase Storage, and the reporter gets a TKT-XXXXXX receipt. A QR that resolves to nothing redirects to the directory with an unmapped-QR marker, turning a dead scan into a lead.

Asset management and QR printing

Full CRUD over assets with a two-level category and asset-type taxonomy. QR codes render client-side pointing at the public report URL, with three print-ready PDF templates — Classic, Minimal and Bold — laid out at exact A5 dimensions and exported via html2pdf.js.

Issue triage

A tabbed queue (All, Open, In Progress, Resolved) with search and filters, one-tap status transitions that stamp resolution time automatically, and a revenue-impact flag that lets operators separate "the lobby lift is down" from "a light bulb is out" independently of the reporter’s own priority claim.

AI prescriptive insights

An Edge Function verifies the caller’s JWT, pulls up to 50 assets and 90 days of issues, and compresses them into a token-efficient text summary rather than dumping raw JSON — deliberate cost control. Gemini 2.5 Flash returns exactly three insights, each a different type, with impact and confidence ratings. Results cache per organization so the panel populates instantly on revisit.

Subscription billing

Five Edge Functions and a database-driven plan catalog, built on one principle: Razorpay is the source of truth for subscription state and the frontend never writes it. Nine Razorpay event types map onto four internal states, webhook signatures are HMAC-verified against the raw body before anything else runs, and every processed event ID is stored for idempotency so a replayed webhook cannot double-apply.

Downgrade safety

A pre-flight check answers the question most SaaS billing flows skip: what happens to the data you already have when your plan lapses? It surfaces the excess asset count and recommendations before the user confirms cancellation, and RLS policies enforce the same rule in Postgres — a lapsed org loses write access to assets while reads stay intact. They never lose their data.

Programmatic SEO directory

12 service categories across 8 metros plus national coverage generate roughly 108 landing pages, each with dynamically generated titles, descriptions and canonicals. Organization, WebSite, CollectionPage and LocalBusiness structured data, a sitemap that queries Supabase at build time so every provider page is indexed automatically, and GA4 with a typed event wrapper.

Admin console and account tiers

An eight-tab internal dashboard covering users, organizations, taxonomy, assets, issues and claim requests. Admin and user credentials are validated against the intended login path, so a wrong-surface login fails loudly rather than silently downgrading. A per-organization asset-limit override lets the client run sales demos without engineering involvement.

Engineering challenges

The problems that took real work to solve. Tap any one to read how.

Problem

The value proposition depends on strangers filing tickets, but granting anon INSERT on issues naively also grants the SELECT that Supabase’s RETURNING clause needs — which would expose every tenant’s ticket data.

Solution

The issue UUID is generated client-side so the app never reads the row back, and the photo uploads before the insert so its URL is part of the initial payload. Anonymous users can write, but can never read. Exactly the asymmetry the feature needs.

Delivery timeline

  1. Foundation

    Feb 2026

    Supabase schema, enums, RLS policies, auth, org onboarding, initial dashboard and report UI

  2. Multi-tenancy & admin

    Feb–Mar 2026

    Admin dashboard, admin auth separation, moderation, asset-type taxonomy, issue-type flows

  3. QR & print

    Mar 2026

    QR generation, three PDF templates, print pipeline, dynamic template selection

  4. Directory & SEM

    Mar 2026

    Next.js directory, category and city architecture, search, claim-your-profile flow, owner dashboard

  5. Intelligence & polish

    Mar–Apr 2026

    Gemini AI insights, dynamic reports with charts, photo attachments, mobile fixes, domain split

  6. Growth instrumentation

    Apr 2026

    Sitemap, robots, JSON-LD, Open Graph, Meta Pixel, asset edit flows

  7. Commercial features

    Apr 2026

    Account tier management, admin Danger Zone, demo-account tooling

  8. Monetization

    May 2026

    Razorpay subscriptions end to end, webhook pipeline, downgrade validation, subscription-aware RLS

  9. Launch analytics

    Jun 2026

    Google Analytics 4 in production, post-launch UX smoothing

Security posture

Tenant isolation

RLS on every org-scoped table, keyed on an org-membership check

Privilege escalation

Admin checks via a SECURITY DEFINER function against an explicit allowlist — never a client-supplied claim

Anonymous access

Write-only INSERT on issues; no anon SELECT, UPDATE or DELETE anywhere

Secret handling

Razorpay secret, webhook secret, Gemini key and service-role key exist only as Edge Function secrets

Webhook authenticity

HMAC signature verified against the raw body before any parsing or database access

Replay protection

Idempotency guard storing the last processed webhook event ID on the subscription row

Entitlement enforcement

Subscription status checked in RLS policies, not just the UI — a lapsed org cannot write even via direct API calls

Account moderation

Ban status checked at sign-in with immediate sign-out; cascade deletes on user removal

Results

No-login

Fault Reporting

QR scan to filed ticket in two steps, no app install

~108

SEO Landing Pages

12 categories × 8 metros, auto-indexed from the database

9 → 4

Billing States Mapped

Razorpay events reduced to four internal states, idempotently

76

Commits in ~4 Months

Feb to Jun 2026, schema to production payments

Outcomes

  • A production-deployed two-product platform with live payment processing, serving public traffic and paying subscribers.
  • A reporting flow that removes every barrier between noticing a fault and filing it — no app, no login, a two-step form on a phone.
  • Billing infrastructure resilient to the failure modes that actually occur in production: replayed webhooks, out-of-order events, uncharged cancellations, expired plans with excess data.
  • A programmatic SEO surface of roughly 108 landing pages plus unlimited provider pages, fully annotated with structured data and auto-indexed.
  • Operator tooling — tier overrides, moderation, claim approval — that lets the client run sales demos and manage the platform without engineering involvement.
  • Nine internal documentation files covering deployment, integration, testing checklists and go-live runbooks, so the client is not dependent on the build team to operate or extend the system.

Related work

Want something like QResolve?

Share your goals and we will come back with a clear plan and estimate.

Start a project