A student notes-sharing and study-community platform: upload notes, sell premium ones, browse a marketplace, build a profile — built as a real full-stack app (React + Express + PostgreSQL/Prisma + Firebase Auth).
This is a scoped first build, not the entire original spec (that spec covers an entire company's worth of product — chat, gamification, AI tools, admin analytics, three payment providers, and more). What's here is fully working; what isn't is stubbed with a clear extension point. See "What's built" below.
apps/
api/ Express + TypeScript + Prisma + PostgreSQL, Socket.io scaffold
web/ React + TypeScript + Vite + Tailwind + Framer Motion + React Query + Zustand
- Node.js 20+
- A PostgreSQL database (local, Railway, or Supabase)
- A Firebase project with Email/Password (and optionally Google/GitHub/Facebook) sign-in enabled
npm install --workspacesCopy apps/api/.env.example to apps/api/.env and fill in:
DATABASE_URL— your Postgres connection stringFIREBASE_PROJECT_ID,FIREBASE_CLIENT_EMAIL,FIREBASE_PRIVATE_KEY— from Firebase Console → Project Settings → Service Accounts → Generate new private key. Paste the values from the downloaded JSON (keep the\ns in the private key as-is).SUPABASE_URL,SUPABASE_SERVICE_ROLE_KEY— only needed once you want real file uploads to work (Project Settings → API in your Supabase project). Create anotesstorage bucket first.
Copy apps/web/.env.example to apps/web/.env and fill in the VITE_FIREBASE_*
values from Firebase Console → Project Settings → General → Your apps → SDK setup.
npm run prisma:migrate # creates tables from prisma/schema.prisma
npm run seed # optional: adds a demo creator + 3 sample notesnpm run dev:api # http://localhost:4000
npm run dev:web # http://localhost:5173Visit http://localhost:5173, register an account (email/password or a social
provider you've enabled in Firebase), and you're in.
- Landing page — hero, live stats pulled from the DB, feature/testimonial sections
- Auth — Firebase email/password + Google/GitHub/Facebook, synced to a
Postgres
Userrow on first login (POST /api/auth/sync) - Notes — upload (direct-to-Supabase-Storage), free/premium, search, filter by subject/price/premium, sort, ratings, bookmarks
- Marketplace — filterable/sortable premium notes grid
- Purchases — wallet-based checkout with automatic 10% platform commission and seller payout, ready for Stripe/eSewa/Khalti webhooks to plug into
- Profile & Settings — bio, school, country, subjects, stats
- Dashboard — sidebar nav, my notes, purchased notes
- Full Prisma schema — users, notes, purchases, wallets, ratings, bookmarks, posts/comments, follows/friendships, study groups, notifications — so the rest of the spec has a data model to build against without a breaking migration
| Feature | Status | Where to start |
|---|---|---|
| Real-time chat | Socket.io wired up, no persistence/UI | apps/api/src/index.ts (io.on("connection")), add a Message model + /api/messages routes |
| Stripe / eSewa / Khalti checkout | Purchase record created as PENDING, no live charge |
apps/api/src/routes/purchases.routes.ts — add provider SDK calls + webhook handlers that flip status to COMPLETED |
| Study groups, friends, community feed UI | Backend routes/schema exist for posts/comments/groups; no frontend pages yet | apps/web/src/pages/ComingSoon.tsx marks where these mount in the router |
| Gamification (XP, badges, leaderboards) | xp/level/streakDays fields exist on User, nothing awards them yet |
add an XP-award step to note upload/purchase/rating routes |
| Admin dashboard | Role.ADMIN + requireAdmin middleware exist, no routes/UI |
new apps/api/src/routes/admin.routes.ts |
| AI features (summarizer, flashcards, quiz gen) | Not started | would call an LLM API from a new route, e.g. /api/notes/:id/summarize |
| Email verification, password reset | Firebase Auth supports both out of the box — just call sendEmailVerification / sendPasswordResetEmail client-side |
apps/web/src/pages/Login.tsx / Register.tsx |
Helmet, CORS (locked to CLIENT_ORIGIN), rate limiting, and Zod validation on
every write route are already in place. File uploads go straight to Supabase
Storage via signed URLs rather than through this server. Virus/malware
scanning of uploaded files is not implemented — add it at the Supabase Storage
webhook or via a scanning service before trusting user-uploaded files in production.