A campus-scoped survey platform built for trustworthy research.
CampusVerify is a final-year project that helps university students run honest, verified surveys without paying for panels. This page documents the problem we tackled, the system we built, and the design decisions we made — at the level of detail an academic evaluator needs.
Student research is broken in two ways.
Data quality. Free survey tools allow anyone to respond. A dissertation about engineering students at a Ghanaian university can end up answered by bots, click-farms, or strangers from another continent — invalidating the dataset.
Access & cost. Paid panels are unaffordable for undergraduates, and social-media recruiting depends on the researcher's personal network. Students with smaller networks systematically get less data.
A credit-powered feed of verified classmates.
CampusVerify gates participation on a verified academic email (.edu, .edu.gh, .ac.uk, etc.). The email's domain defines a student's campus, and surveys are scoped to that campus by default. Researchers can also opt-in to a wider public audience for general-interest studies.
Instead of money, the platform runs on a credit economy: you earn one credit for each quality response you give, and spend credits to publish your own surveys. This aligns incentives — every researcher is also a respondent.
Five concerns drove every design decision.
Identity verification
Sign-up requires an academic email and confirmation link. We never auto-sign-in; the email must be verified before the account is usable.
Campus scoping
Email domain maps to a university. Default audience for any survey is "only your campus", protecting both relevance and respondent privacy.
Credit economy
Publishing costs credits; answering earns them. This funds the platform without real money and discourages low-effort surveys.
Defense-in-depth security
Row-level security on every table, role checks via a security-definer function, and database triggers that protect sensitive columns even from the owner.
Offline-first
Campus Wi-Fi and mobile data are unreliable. Surveys cache locally so respondents can answer without a connection and sync automatically when back online.
Report builder
Survey owners get a configurable report — cover page, executive summary, per-question analysis, owner commentary — exported as a clean PDF document.
A modern serverless stack chosen for cost and reliability.
- Frontend: React 19 + TanStack Start (file-based routing, server functions, SSR) on Vite 7, styled with Tailwind CSS v4 and shadcn/ui primitives.
- Backend: Postgres + Supabase Auth for identity. Business logic runs as TanStack server functions secured by an authentication middleware; webhooks live as server routes.
- Data layer: Row-Level Security on every table. A
has_role()security-definer function avoids RLS recursion. Triggers protect sensitive columns (credits, user types, survey rules) from direct modification. - Offline: A service worker caches survey payloads; responses queue in IndexedDB and replay on reconnect.
- Hosting: Edge runtime (Cloudflare Workers) — cold-start free, geographically close to Ghanaian users.
Trust is enforced in the database, not just the UI.
Every table in the public schema has RLS enabled. Roles are stored in a separate user_roles table — never on the profile — and checked via has_role(user_id, role), a SECURITY DEFINER function that prevents privilege-escalation attacks common in naive Supabase apps.
Sensitive columns (a user's credit balance, a survey's published flag, a profile's verification status) cannot be edited via the API even by the row's owner. Database triggers reject any attempt; only internal server logic can update them. A "speed-trap" trigger flags suspiciously fast responses as fraud, while still honouring genuine offline-sync timing.
Realtime broadcasts are restricted to a safe column allow-list so sensitive fields (email hash, flagging metadata, raw identifiers) are never wired to the websocket.
Built to be evaluated, audited, and extended.
- Migrations as source of truth. Every schema change ships as a numbered SQL migration in
supabase/migrations/. - Type-safe routing. TanStack Router generates route types at build time; broken links fail the build, not production.
- Semantic design tokens. No raw colours in components — every shade is a token defined in
src/styles.css, giving consistent light/dark behaviour. - PWA installable. The app ships a manifest and icons; students can install it to their home screen.
How to assess CampusVerify in 10 minutes.
- Create an account from the home page using any academic email; confirm the verification link.
- Open the feed — it shows surveys scoped to your campus, with credit rewards and remaining slots.
- Answer one survey to earn credits and observe the offline indicator (try toggling airplane mode mid-answer).
- Publish your own survey; spend credits, then open the Analytics view to see live results.
- Build a report from the analytics page and export the PDF — this is the artefact a researcher would submit.
Try it the way a student would.
The best evaluation is hands-on. Create a free account, run a survey, and read the generated report — the full loop takes about ten minutes.