A public-interest platform connecting citizens, academic institutions, industry, and the Government of Jharkhand to identify, fund, and solve societal challenges together.
Raah (रास्ता — meaning "path" or "way") is built as a serious institutional tool: no growth hacks, no engagement loops. It exists to reduce the friction between a problem a district faces and the expertise that can solve it.
- Citizens and government post validated societal challenges.
- Academic institutions register, verify, and expose their capabilities, research areas, faculty, and infrastructure.
- Industry discovers institutions and challenges relevant to their CSR or R&D mandate.
- A transparent capability score — not a black-box AI rank — surfaces which institutions are best positioned for each challenge.
- Verification is multi-signal: official domain confirmation, document upload, and faculty affiliation via tokenised email.
raah/
├── apps/
│ └── web/ # Next.js 16 web application
│ ├── src/
│ │ ├── app/
│ │ │ ├── (auth)/ # Auth route group (sign-in, register)
│ │ │ │ └── auth/
│ │ │ │ ├── sign-in/
│ │ │ │ └── register/
│ │ │ ├── (site)/ # Public-facing pages
│ │ │ │ ├── page.tsx # Homepage
│ │ │ │ ├── institutions/ # Institution directory + public profiles
│ │ │ │ ├── challenges/ # Challenge browser (stub)
│ │ │ │ ├── projects/ # Projects browser (stub)
│ │ │ │ ├── industry/ # Industry portal (stub)
│ │ │ │ ├── government/ # Government portal (stub)
│ │ │ │ ├── how-it-works/
│ │ │ │ └── about/
│ │ │ ├── auth/
│ │ │ │ └── callback/ # OAuth PKCE callback route
│ │ │ ├── institution/ # Authenticated institution dashboard
│ │ │ │ ├── page.tsx # Dashboard + capability score
│ │ │ │ ├── profile/ # Profile editor
│ │ │ │ ├── verification/ # Verification workflow
│ │ │ │ └── people/ # Faculty management
│ │ │ ├── admin/ # Platform admin review interface
│ │ │ ├── faculty-verify/ # Faculty affiliation token landing
│ │ │ └── onboarding/
│ │ │ └── institution/# Institution registration form
│ │ ├── components/
│ │ │ ├── ui.tsx # All UI primitives (Button, Card, Input…)
│ │ │ ├── mark.tsx # RaahMark, ArcArtifact, PathwayArtifact SVGs
│ │ │ ├── site-nav.tsx # Sticky header + footer
│ │ │ ├── google-button.tsx
│ │ │ └── sign-out-button.tsx
│ │ └── lib/
│ │ ├── supabase/
│ │ │ ├── browser.ts # Client-side Supabase client
│ │ │ ├── server.ts # Server + service-role clients
│ │ │ ├── env.ts # Env var accessors (throws if missing)
│ │ │ └── types.ts # TypeScript types mirroring DB schema
│ │ ├── auth.ts # getSession, requireSession, requireAdmin
│ │ ├── capability.ts # Transparent capability scoring
│ │ ├── design-tokens.ts# Palette constants for mobile app import
│ │ ├── institution.ts # requireInstitutionMembership
│ │ ├── matching.ts # ML matching stub
│ │ ├── slug.ts # slugify, domainFromUrl
│ │ └── validation.ts # Zod schemas
│ ├── proxy.ts # Next.js 16 session-refresh proxy
│ ├── next.config.ts
│ ├── postcss.config.mjs
│ └── tsconfig.json
├── supabase/
│ └── migrations/
│ └── 0001_raah_init.sql # Full schema, RLS, triggers, storage bucket
├── package.json # Monorepo root (pnpm workspaces)
├── pnpm-lock.yaml
└── pnpm-workspace.yaml
| Layer | Choice | Notes |
|---|---|---|
| Framework | Next.js 16.3.2 | App Router, React Server Components, Server Actions |
| UI | React 19 + Tailwind CSS v4 | @import "tailwindcss", CSS custom properties for theming |
| Database | Supabase PostgreSQL | RLS enforced at DB level, not just UI |
| Auth | Supabase Auth | Email/password + Google OAuth (PKCE flow) |
| Storage | Supabase Storage | Private bucket for verification documents; signed URLs via service role |
| Validation | Zod v4 | Server-side only |
| Package manager | pnpm 11 | Monorepo via pnpm-workspace.yaml |
| Language | TypeScript 5 | Strict mode |
| Compiler | React Compiler (babel-plugin-react-compiler) | Enabled in next.config.ts |
The full schema lives in supabase/migrations/0001_raah_init.sql.
Key tables:
profiles— one row per auth user;rolecolumn is informational onlyplatform_admins— separate table; only rows here grant admin privilege (never trustprofiles.role)institutions— registered institutions with verification statusinstitution_members— who administers each institutionfaculty+faculty_verifications— faculty records and token-based affiliation verificationinstitution_verifications+verification_documents— admin review workflow
Row Level Security is enforced on every table. Helper functions is_platform_admin() and is_institution_admin(institution_id) are defined as SECURITY DEFINER so they cannot be bypassed by client code.
Copy apps/web/.env.example to apps/web/.env.local and fill in the values:
NEXT_PUBLIC_SUPABASE_URL= # Supabase project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY= # Public anon key
SUPABASE_SERVICE_ROLE_KEY= # Server-only. Never expose to the client.
NEXT_PUBLIC_APP_URL=http://localhost:3000
ML_SERVICE_URL= # Future matching service (optional, stub)
SUPABASE_SERVICE_ROLE_KEY is used exclusively in Server Actions and Route Handlers via createSupabaseServiceRoleClient(). It is never imported from any client component.
- Node.js 20+
- pnpm 11 (
npm i -g pnpmor it is auto-downloaded viadevEngines) - A Supabase project (free tier is fine for development)
pnpm installApply the migration to your Supabase project. Either:
supabase db pushOr paste the contents of supabase/migrations/0001_raah_init.sql into the Supabase SQL editor.
cp apps/web/.env.example apps/web/.env.local
# then edit .env.local with real valuesIn Supabase dashboard: Authentication → Providers → Google. Enable it and add <NEXT_PUBLIC_APP_URL>/auth/callback to the allowed redirect URLs.
After creating your account, find your user UUID in Supabase Auth and run:
insert into platform_admins (user_id) values ('<your-uuid>');pnpm --filter web devThe app will be at http://localhost:3000.
pnpm --filter web buildThen:
pnpm --filter web startThe build outputs 22 static/server routes. There are no environment-specific code splits — the same build artifact works in any Node.js host (Vercel, Railway, Fly, etc.).
Design tokens are defined as CSS custom properties in apps/web/src/app/globals.css and mirrored as plain TypeScript constants in apps/web/src/lib/design-tokens.ts so a future React Native / Expo app can import them directly without duplicating values.
Palette summary (warm ivory + terracotta + sage):
--background: #faf6ee warm ivory
--accent: #b46a4a terracotta (primary actions)
--accent-2: #6f8a68 sage green (secondary accents)
--foreground: #241f18 near-black
--muted: #6c6151 warm grey
| Module | Routes | Status |
|---|---|---|
| Core platform + institutions | /, /institutions, /institution/*, /admin/*, /auth/* |
Complete |
| Challenges | /challenges/* |
Stub — assign to teammate |
| Projects | /projects/* |
Stub — assign to teammate |
| Industry portal | /industry/* |
Stub — assign to teammate |
| Government portal | /government/* |
Stub — assign to teammate |
| ML matching | lib/matching.ts |
Stub — getInstitutionRecommendations() returns [] |
Stubs are rendered via the shared ModuleStub component in apps/web/src/app/(site)/_stub.tsx.
- RLS policies are the enforcement layer, not UI guards.
- Admin privilege is gated by the
platform_adminstable — no client can promote themselves by writing toprofiles.role. - Verification documents are in a private Supabase Storage bucket. Signed URLs are generated server-side via the service role client and expire after 60 seconds.
- The
nextredirect parameter in/auth/callbackis validated to start with/to prevent open redirect attacks.
MIT. See LICENSE.