A mobile app that helps university students share dining points.
- Frontend (mobile): Expo Router (React Native)
- Frontend + API (web): Next.js (
apps/dashboard) - Database: Neon (serverless Postgres) + Drizzle ORM
- Auth: Supabase Auth with Google OAuth
- Hosting: Vercel
- External: GET Tools API (school point system)
- Node.js 20+
- npm or yarn
- Expo CLI
- iOS Simulator (Mac) or Android Emulator
-
Clone the repository
-
Install dependencies:
npm install
-
Copy
.env.exampleto.env.localand fill in your credentials:cp .env.example .env.local
Start the mobile app:
npm run mobile:devThen press:
ifor iOS simulatorafor Android emulatorwfor web
Start the dashboard app:
npm run dashboard:dev -- -p 3001Route map (dashboard app):
/-> public landing page/app-> Expo web app (same domain)/admin/login-> admin login/admin-> admin dashboard/api/*-> backend API routes
Deploy dashboard preview:
npm run dashboard:deployDeploy dashboard production:
npm run dashboard:deploy:prodslugswap/
├── apps/
│ ├── mobile/ # Expo mobile app
│ └── dashboard/ # Next.js dashboard + API routes
├── db/ # Drizzle schema + migrations
├── scripts/ # Project scripts
└── .github/workflows/ # CI/CD workflows
Instagram story generation now lives in scripts/instagram-stories/ and the preview route is served from apps/dashboard/app/ig-stories/.
See slugswap-release.md for the detailed release plan.
Current Focus: Release 1
- Donor onboarding with monthly preferences
- Requester weekly allowance visibility
- Claim code generation and redemption
- Basic impact and history views
For questions, issues, or contribution guidance, contact the development team.
The GET barcode flow currently does not use a server-side session cache. Each barcode fetch re-authenticates with GET using the stored device credentials/PIN and then requests the latest payload.
For clients consuming claim/scan status:
GET /api/get/scan-statereturns scan/status metadata only (state,lastCheckedAt,expiresAt).- Barcode payloads are returned by
GET /api/get/barcode.
Keep those endpoints separate in client logic to avoid treating scan-state responses as barcode payload responses.