ShareBite is a full-stack food rescue platform built to move surplus food from donors to NGOs as quickly and transparently as possible. The application combines a polished public site, role-based dashboards, operational APIs, real-time notifications, map-driven discovery, and optional rider logistics into one system.
Short description (for GitHub About):
ShareBite is a full-stack food rescue platform that connects donors, NGOs, riders, and admins to reduce food waste with real-time coordination, map-based pickups, and transparent fulfillment workflows.
Detailed description (for documentation, pitch decks, or submissions):
ShareBite helps organizations rescue and redistribute surplus food efficiently. Donors publish available food, NGOs request and track pickups, riders support last-mile movement, and admins manage verification, moderation, and operational visibility. The platform combines role-based dashboards, map-driven logistics, real-time notifications, secure APIs, and production-ready deployment workflows to make food redistribution faster, safer, and more accountable.
The codebase is organized around four main actors:
DONORusers publish and manage food donations.NGOusers discover food, request pickups, and complete collection.RIDERusers handle optional last-mile pickup and delivery.ADMINusers verify organizations, review activity, moderate issues, and monitor platform health.
ShareBite solves the food-rescue workflow end to end:
- Donors publish surplus food with quantity, expiry, and pickup location in minutes.
- NGOs discover nearby, available donations and request pickups quickly.
- Riders can be assigned for assisted pickup and handover when direct collection is difficult.
- Admins verify organizations, moderate abuse, monitor activity, and maintain platform trust.
The result is a practical, real-world coordination system that reduces food waste and improves delivery speed to communities that need support.
- Role-based authentication and dashboards for donors, NGOs, riders, and admins
- Food donation publishing with category, quantity, weight, expiry, pickup window, and map coordinates
- NGO request and fulfillment flows, including direct handover and rider-assisted delivery
- Real-time notifications and messaging over a dedicated websocket server
- Redis-backed rate limiting, OTP storage, geospatial donation lookup, rider location, and karma leaderboard
- Cloudflare R2 presigned uploads for food images and delivery proof
- AI support chat and voice transcription endpoints using Groq
- Translation support and map-based interfaces for multilingual, location-aware usage
- Admin tools for users, requests, reviews, reports, logs, bugs, verification, and operational stats
- Karma, badges, and leaderboard mechanics for donor and rider engagement
| Category | Technology |
|---|---|
| Frontend | Next.js 16 App Router, React 19, TypeScript |
| UI and styling | Tailwind CSS, Radix UI, custom UI components, Framer Motion |
| Backend | Next.js route handlers, standalone websocket server with ws |
| Data | PostgreSQL via Prisma 7 and @prisma/adapter-pg |
| Realtime and cache | Redis with ioredis |
| File storage | Cloudflare R2 via S3-compatible APIs |
| Maps | Mapbox GL |
| AI features | Groq via AI SDK, Groq Whisper transcription |
| Resend | |
| Bot protection | Cloudflare Turnstile |
| Testing | Vitest |
| Runtime and packaging | Bun, Docker, Docker Compose |
| Infrastructure and deployment | Kubernetes, Argo CD, Terraform, AWS ECS/Fargate, ALB, networking, and domain wiring |
sharebite/
|-- app/ # App Router pages, layouts, route groups, and API handlers
| |-- (auth)/ # Public login, register, and password recovery pages
| |-- (dashboard)/ # Role-specific dashboard experiences
| |-- api/ # Route handlers for auth, donations, requests, chat, admin, etc.
| |-- demo/ # Demo pages
| `-- terms/ # Role-specific terms pages
|-- components/ # Reusable UI, chat, map, support, and provider components
|-- lib/ # Shared auth, Prisma, Redis, storage, notifications, validation, and helpers
|-- prisma/ # Prisma schema, migrations, and badge seeding
|-- public/ # Static assets
|-- server/ # Standalone websocket server and background worker scripts
|-- terraform/ # AWS deployment infrastructure
|-- tests/ # Route and behavior-oriented Vitest suites
|-- Dockerfile # Container image build
|-- docker-compose.yml # Multi-service local stack
|-- proxy.ts # Global API auth, RBAC, and CORS handling
`-- start.sh # Container startup script
/public landing page/login,/register,/forgot-password/donationsshared browsing area/terms/*role-specific terms pages/demo/*experimental or presentation pages
/donor/*donor dashboard, profile, donations, NGOs, messages, notifications, complaints/ngo/*NGO dashboard, find-food, requests, history, messages, notifications, complaints/rider/*rider dashboard, bounties, missions, notifications, settings/admin/*admin dashboard, users, requests, donations, reviews, reports, logs, map, verification, bugs, settings
/api/auth/*registration, login, logout, session lookup, OTP verification, password reset, token fetch/api/donations/*donation CRUD and cleanup/api/requests/*pickup requests, approval, rider assignment, handover, delivery, verification/api/chat/*AI support, conversations, messages, read state, voice transcription/api/admin/*admin dashboards and moderation endpoints/api/upload/*authenticated presigned upload endpoints/api/public/statspublic impact stats/api/leaderboardkarma leaderboard/api/translatetranslation proxy/api/bugs,/api/reports,/api/donor-reports,/api/reviews,/api/notifications
Browser
|
v
Next.js App Router UI
|
+--> Next.js API routes ----------------------------+
| |
| +--> PostgreSQL via Prisma
| +--> Redis for rate limits, geo, OTP, leaderboard, rider location
| +--> Cloudflare R2 for uploads
| +--> Groq for AI chat and transcription
| +--> Resend for password reset email
| +--> RapidAPI translation provider
|
+--> /api/auth/token --> websocket connection ------> server/ws.ts
|
+--> Redis pub/sub fan-out
+--> real-time notifications, chat, typing, rider tracking
The Prisma schema centers on a few important entities:
User: base identity model with role, verification state, profile, location, strikes, suspension, and rider availabilityFoodDonation: donor-created donation record with food details, status, timing, and pickup locationPickupRequest: NGO request lifecycle, optional rider assignment, handover PIN, proof, and timestampsNotification: persistent in-app alerts for request status, new donations, bug responses, and system eventsConversationandMessage: one-to-one operational chat around donationsReview: post-transaction trust signal tied to a donationAuditLog,Report,DonorReport,Violation: admin moderation and governance recordsBadgeandUserBadge: donor recognition and achievement trackingBugReportandBugResponse: user support issue intake and admin replies
Two status systems work together:
FoodDonation.status:AVAILABLE,REQUESTED,APPROVED,COLLECTED,EXPIREDPickupRequest.status:PENDING,APPROVED,REJECTED,ASSIGNED,ON_THE_WAY,COMPLETED
In the current code, most operational progress is tracked on PickupRequest.status, while FoodDonation.status is actively moved through AVAILABLE, APPROVED, and COLLECTED.
The project includes a committed .env.example. The table below is the practical reference for required and optional runtime configuration.
| Variable | Required | Used for |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection for Prisma and worker processes |
JWT_SECRET |
Yes | Session token signing and verification |
REDIS_URL |
Recommended | Rate limiting, OTP storage, geo search, leaderboard, rider location, websocket fan-out |
NEXT_PUBLIC_APP_URL |
Recommended | Allowed origin for API CORS handling in proxy.ts |
NEXT_PUBLIC_WS_URL |
Recommended | Browser websocket base URL |
INTERNAL_WS_URL |
Recommended | Internal HTTP relay from app server to websocket server |
R2_ACCOUNT_ID |
Yes for uploads | Cloudflare R2 endpoint construction |
R2_ACCESS_KEY_ID |
Yes for uploads | Cloudflare R2 credentials |
R2_SECRET_ACCESS_KEY |
Yes for uploads | Cloudflare R2 credentials |
R2_BUCKET_NAME |
Yes for uploads | Bucket used for signed uploads |
R2_PUBLIC_DOMAIN |
Yes for uploads | Public base URL for uploaded objects |
NEXT_PUBLIC_MAPBOX_TOKEN |
Recommended | Map rendering in donor, NGO, and rider interfaces |
GROQ_API_KEY |
Optional | AI support chat and voice transcription |
RESEND_API_KEY |
Optional | Forgot-password email delivery |
RAPIDAPI_KEY |
Optional | Translation API access |
RAPIDAPI_HOST |
Optional | Translation API host |
NEXT_PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY |
Recommended | Browser Turnstile widget |
CLOUDFLARE_TURNSTILE_SECRET_KEY |
Recommended | Server-side Turnstile verification |
NODE_ENV |
Recommended | Runtime mode for cookies and logging behavior |
- Bun installed locally
- PostgreSQL available, or the
dbservice from Docker Compose - Redis available, or the
redisservice from Docker Compose
bun installAdd the environment variables listed above. At minimum you should supply:
DATABASE_URL=postgresql://...
JWT_SECRET=replace-this
REDIS_URL=redis://127.0.0.1:6379
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_WS_URL=ws://localhost:8080
INTERNAL_WS_URL=http://localhost:8081
R2_ACCOUNT_ID=
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_BUCKET_NAME=
R2_PUBLIC_DOMAIN=
NEXT_PUBLIC_MAPBOX_TOKEN=
GROQ_API_KEY=
RESEND_API_KEY=
RAPIDAPI_KEY=
RAPIDAPI_HOST=
NEXT_PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY=
CLOUDFLARE_TURNSTILE_SECRET_KEY=bunx prisma generate
bunx prisma migrate devOptional seed step for badge data:
bun run prisma/seed-badges.tsIf you do not already have PostgreSQL and Redis running locally:
docker compose up db redis -dStart the web app and websocket server in separate terminals:
bun run devbun run wsIf you want the expiry alert worker running as well:
bun run server/watchtower.tsThen open http://localhost:3000.
The repository includes a multi-service Compose setup with:
webfor the Next.js applicationwsfor the dedicated websocket and internal relay serverdbfor PostgreSQLredisfor cache and realtime coordination
Bring the full stack up with:
docker compose up --buildThe committed start.sh currently starts server/ws.ts and then runs bun run dev for the web application. That is convenient for iterative environments, but it is not a typical hardened production launch path. The image itself is built with standalone output, so if you want a stricter production runtime, update the startup command to use the built server rather than the dev server.
Run the suite with:
bun run testAvailable test coverage currently targets API and behavior-heavy areas such as:
- authentication
- donations
- requests
- donor and NGO flows
- admin actions
- notifications
- uploads
- leaderboard
- reports and reviews
- regression checks
Linting can be run with:
bun run lintThe Dockerfile builds a standalone Next.js output, copies the generated Prisma client, includes the websocket server files, and exposes ports 3000, 8080, and 8081.
The terraform/ directory defines an AWS-oriented deployment shape with:
- ECS Fargate service
- ECR repository
- ALB listeners and target groups
- VPC and network resources
- domain wiring
- environment variable injection for the app runtime
The ECS definition is set up to expose both the web port and websocket port through the load balancer.
This repository now includes Kubernetes and Argo CD manifests for deploying only application workloads:
web(Next.js) on port3000ws(websocket server) on port8080
No PostgreSQL or Redis manifests are included. The deployment expects external managed services through environment variables (DATABASE_URL, REDIS_URL).
- Application architecture is complete.
- API, websocket, and operational workflows are complete.
- Kubernetes base and overlays are complete.
- Argo CD Applications are complete.
- External Secrets integration is complete.
- Manual CI workflow is configured and available when needed.
Only final deployment execution steps are left at cluster/runtime level (secret backend setup, TLS readiness, image tag updates, and Argo CD sync).
k8s/base/: shared manifests (deployments, services, ingress, HPAs, PDBs, config, ExternalSecret, pre-sync migration job)k8s/overlays/dev/: dev hostnames and scaling overridesk8s/overlays/prod/: production hostnames and scaling overridesargocd/: Argo CDApplicationresources for dev and prod
The Kubernetes deployments override container commands so one process runs per pod:
- Web deployment command:
node server.js - WS deployment command:
bun run server/ws.ts
This avoids the multi-process start.sh behavior inside orchestrated production workloads.
The file k8s/base/presync-migrate-job.yaml is an Argo CD PreSync hook that runs:
bunx prisma migrate deploy --schema prisma/schema.prismaThis ensures schema migrations are applied before workloads are updated.
- Confirm
repoURLin these files points to your Git repository:
argocd/sharebite-dev-application.yamlargocd/sharebite-prod-application.yaml
- Install External Secrets Operator in your cluster and create a
ClusterSecretStorenamedsharebite-cluster-secrets. - Populate your external secret backend with environment-specific keys used by overlays:
sharebite/devsharebite/prod
- Update immutable image tags before each deployment:
k8s/overlays/dev/kustomization.yamlk8s/overlays/prod/kustomization.yaml
- Apply Argo CD applications:
kubectl apply -f argocd/sharebite-dev-application.yaml
kubectl apply -f argocd/sharebite-prod-application.yamlThe app workloads read runtime secrets from the Kubernetes secret sharebite-secrets, which is created automatically by the External Secrets resources.
- Dev application uses automated sync (
prune+selfHeal). - Prod application is set to manual sync for safer releases.
Use Argo CD rollback to a previous healthy revision:
argocd app rollback sharebite-prod <history-id>If required, you can also roll back individual deployments:
kubectl -n sharebite-prod rollout undo deployment/sharebite-web
kubectl -n sharebite-prod rollout undo deployment/sharebite-wsproxy.tshandles CORS, API route protection, and an extra admin-only guard for/api/admin/*.lib/auth.tsresolves sessions across role-specific cookies and tries to infer the preferred role from the request path.withSecurity()applies rate limiting and security headers around many route handlers. If Redis is unavailable, rate limiting fails open rather than taking the API down.- Donation geo-indexing, rider location, leaderboard, OTP storage, and websocket pub/sub all depend on Redis.
server/watchtower.tsexists as a background worker for urgent expiry alerts, but it is not part of the defaultpackage.jsonscripts.- The registration route currently allows direct admin registration. That may be acceptable for internal use, but most production deployments would gate admin creation behind an invite or secret.
- README for setup and repo orientation
- Architecture Guide for the technical layout
- Workflow Guide for lifecycle and operations
- API Test Notes for test context
This project is licensed under the MIT License. See LICENSE for details.