# Pantry Sync

Web app for running a campus food pantry: one shared inventory, students place orders and book pickup windows, volunteers and admins keep stock updated and watch alerts and usage.

## What this project is

**Pantry Sync** is a full-stack app meant for a school or nonprofit pantry. Students see what is available, add items to a cart, and complete checkout with a date/time for pickup. Staff with the **volunteer** role use a **team** dashboard to help fulfill orders and monitor operations. **Admins** manage inventory, user roles, pantry-wide settings, and see heavier analytics.

Authentication is **Supabase** (email/password). The **Express** API stores business data in **PostgreSQL** via **Drizzle**. The React app talks to Supabase for login and to the API for everything else (inventory, orders, settings).

## Roles

| Role | In the database | Typical use |
|------|------------------|-------------|
| `user` | default for self-registration | Student: browse, order, schedule pickup |
| `volunteer` | set by an admin | Team dashboard: inventory help, alerts, pickups |
| `admin` | set by an admin | Full management: users, inventory, settings, analytics |

Routes are guarded in the frontend (`App.tsx` / `ProtectedRoute`) and again on the API with middleware (`requireAdmin`, `requireAdminOrTeam`, etc.).

## Tech stack

| Layer | Choice |
|-------|--------|
| Frontend | React 18, TypeScript, Vite, React Router, Tailwind CSS |
| Auth | Supabase Auth (JWT to the API) |
| Backend | Node.js, Express, TypeScript (`tsx` in dev) |
| Database | PostgreSQL, Drizzle ORM |

## Repository layout

| Path | What |
|------|------|
| **`README.txt`** | Plain-text directory map (course / binder style) |
| **`README.md`** | This file — overview, run, API |
| **`Installation_Guide.md`** | Install steps and env vars |
| **`User_Manual.md`** | Using the app by role |
| **`frontend/`** | Web client (Vite + React). Deployable build: `npm run build` → `frontend/dist/` |
| **`backend/`** | REST API. Deployable build: `npm run build` → `backend/dist/` |
| **`Database/`** | `database.sql` + notes for Postgres bootstrap |
| **`screenshots/`** | PNGs used in `Installation_Guide.md` and `User_Manual.md` |

## Configuration

1. Copy **`frontend/.env.example`** → `frontend/.env` — `VITE_SUPABASE_*`, `VITE_API_URL` (default API base `http://localhost:5000/api`).
2. Copy **`backend/.env.example`** → `backend/.env` — `DATABASE_URL`, Supabase URL + anon + **service role** keys, optional `FRONTEND_URL` (production CORS).

Never commit `.env`. The backend needs the **service role** key for admin Auth operations (e.g. seed script); keep it server-side only.

## Database

- **Schema source of truth:** `backend/src/database/schema.ts`. Drizzle migrations live under `backend/drizzle/`.
- **Quick bootstrap / reference:** `Database/database.sql` — creates tables and inserts demo categories/items (no real users). Apply it in Supabase SQL editor or `psql`.
- **Demo users + inventory:** from `backend/`, with `SUPABASE_SERVICE_ROLE_KEY` set: `npm run db:seed` (see `backend/scripts/seed-data.ts`). Details in `Database/README.txt`.

## Running locally

**Requirements:** Node.js 18+, npm.

```bash
git clone <repository-url>
cd Pantry-System-App
npm run install:all
npm run dev
```

- Frontend (Vite): **http://localhost:3000** — proxies `/api` to the backend in dev (`frontend/vite.config.ts`).
- API: **http://localhost:5000** — JSON under **`/api`** (`backend/src/index.ts` mounts `apiRoutes`).

Other useful scripts:

| Command | Purpose |
|---------|---------|
| `npm run dev:frontend` / `npm run dev:backend` | One side only |
| `npm run build` | Production build both packages |
| `cd backend && npm run db:seed` | Seed demo users + sample data |
| `cd backend && npm run db:studio` | Drizzle Studio (needs `DATABASE_URL`) |

Step-by-step setup: **`Installation_Guide.md`**. End-user flows: **`User_Manual.md`**.

## How the pieces talk

1. User signs in via Supabase in the browser.
2. Frontend sends `Authorization: Bearer <access_token>` to the API.
3. Middleware verifies the JWT with Supabase and loads the matching row from `public.users` for role checks.
4. Drizzle reads/writes Postgres (inventory, orders, settings, etc.).

## Features (high level)

- Inventory with categories, quantities, expiry dates, low-stock flags  
- Student cart → order → pickup scheduling (`/checkout`, schedule API)  
- Order lifecycle (status stored on the `orders` row — see schema comments and pantry routes)  
- Dashboards: stats, activity, alerts (expiring / low stock), analytics charts on admin & team views  
- Pantry branding / contact info via **settings** (`pantry_settings` table + `/api/settings`)

## API overview

Base path: **`/api`**. Examples (not exhaustive — check `backend/src/routes/`):

| Area | Prefix | Notes |
|------|--------|--------|
| Auth | `/api/auth` | register, login, logout, **`GET /me`** (current profile) |
| Pantry | `/api/pantry` | inventory, orders (incl. schedule + status), stats, activity, alerts, analytics, categories, pickups |
| Users | `/api/user` | admin user list, get/update/delete users (role-gated) |
| Settings | `/api/settings` | pantry settings (admin can update) |

Health: **`GET /health`**. API index: **`GET /api`**.

Production: set **`NODE_ENV=production`**, **`FRONTEND_URL`** to your deployed origin(s), and point **`DATABASE_URL`** at your hosted Postgres.

## Development notes

- Monorepo via **npm workspaces**; root scripts delegate to `frontend` and `backend`.
- Backend uses **Helmet**, **CORS**, **Morgan**; errors hide stack details outside development.
- Frontend env vars must be prefixed with **`VITE_`** to be exposed to the client.

## License

See **`LICENSE`** in the repo root.
