Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5a42ed5
chore(deps): bump urllib3 from 2.6.3 to 2.7.0 in /backends/fastapi
dependabot[bot] May 19, 2026
c486e45
docs: add developer setup README, fix env examples, remove old mockup…
DIodide Jun 10, 2026
907308e
Merge pull request #11 from TigerAppsOrg/docs/dev-setup-readme
DIodide Jun 10, 2026
41716f2
Merge pull request #12 from TigerAppsOrg/staging
DIodide Jun 10, 2026
2920b1e
Merge pull request #1 from TigerAppsOrg/dependabot/uv/backends/fastap…
DIodide Jun 10, 2026
8fca3fc
fix(security): resolve all open Dependabot alerts
DIodide Jun 10, 2026
61498c6
docs: name Ibraheem as env-var contact, expand Postgres setup steps
DIodide Jun 10, 2026
e1e4560
Merge pull request #13 from TigerAppsOrg/fix/security-dep-bumps
DIodide Jun 10, 2026
97a804d
Merge pull request #14 from TigerAppsOrg/staging
DIodide Jun 10, 2026
dd6ffec
feat(seed): make re-runnable and cover newer tables
DIodide Jun 10, 2026
023b028
Merge pull request #15 from TigerAppsOrg/feat/seed-improvements
DIodide Jun 10, 2026
8825649
Merge pull request #16 from TigerAppsOrg/staging
DIodide Jun 10, 2026
61153fe
ui change?
Jun 11, 2026
502b85a
Merge branch 'ui-updates' into staging
Jun 16, 2026
d58057a
Merge remote-tracking branch 'upstream/main' into ui-updates
sophia-you Jun 17, 2026
9c0cba4
ui: fixed demo event errors
sophia-you Jun 17, 2026
4836630
Merge branch 'staging' into ui-updates
sophia-you Jun 17, 2026
9d65285
fixed explore page layout and profile page bugs
angelina-ji Jun 17, 2026
c6f8a4c
Merge pull request #25 from TigerAppsOrg/staging
angelina-ji Jun 17, 2026
0ce8821
fix: refresh seeded event dates on reseed instead of skipping; render…
rohanmatta11 Jul 18, 2026
0543fb6
run db:seed via bun instead of tsx to inherit DATABASE_URL; document …
rohanmatta11 Jul 18, 2026
aeb1f00
implement event extraction pipeline (remove secrets)
Jul 25, 2026
3e278f1
remove any possible secret
Jul 26, 2026
b03339e
changed lookup mechanics to be deterministic
rohanmatta11 Jul 31, 2026
0bf758b
Merge pull request #29 from TigerAppsOrg/TIG-256-Seed-Demo-Flows
angelina-ji Jul 31, 2026
791398b
Merge pull request #36 from TigerAppsOrg/staging
angelina-ji Jul 31, 2026
321b604
resolve merge conflicts
Aug 2, 2026
b2ec222
re-ran migration with USING cast and revert --force
Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# ----- PostgreSQL (Docker) -----
POSTGRES_USER=forum
POSTGRES_PASSWORD=forum_password
POSTGRES_PASSWORD=YOUR_DB_PASSWORD_HERE
POSTGRES_DB=the_forum
POSTGRES_PORT=5434

Expand All @@ -16,17 +16,17 @@ DATABASE_URL=postgresql://forum:forum_password@localhost:5434/the_forum
AUTH_SECRET=your-auth-secret-here
AUTH_AZURE_AD_CLIENT_ID=your-client-id
AUTH_AZURE_AD_CLIENT_SECRET=your-client-secret
AUTH_AZURE_AD_TENANT_ID=2ff60116-7431-425d-b5af-077d7791bda4
AUTH_AZURE_AD_TENANT_ID=YOUR_TENANT_ID_HERE

# ----- AWS S3 (image uploads) -----
# AWS_S3_BUCKET=the-forum-uploads
# AWS_REGION=us-east-1

# ----- Next.js public vars (prefix with NEXT_PUBLIC_) -----
# NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_MAPBOX_TOKEN=pk.your-mapbox-public-token
NEXT_PUBLIC_CAMPUS_MAP_TOKEN=pk.campus-map-public-token
NEXT_PUBLIC_CAMPUS_MAP_STYLE=mapbox://styles/account/style-id
NEXT_PUBLIC_MAPBOX_TOKEN=YOUR_CAMPUS_MAPBOX_TOKEN_HERE
NEXT_PUBLIC_CAMPUS_MAP_TOKEN=YOUR_CAMPUS_MAP_TOKEN_HERE
NEXT_PUBLIC_CAMPUS_MAP_STYLE=YOUR_CAMPUS_MAP_STYLE_HERE

# ----- FastAPI -----
# FASTAPI_SECRET_KEY=changeme
Expand All @@ -44,4 +44,4 @@ NEXT_PUBLIC_CAMPUS_MAP_STYLE=mapbox://styles/account/style-id

# ----- Listserv Scraper -----
LISTSERV_EMAIL=tigerapp@princeton.edu
LISTSERV_PASSWORD=your-listserv-password
LISTSERV_PASSWORD=YOUR_LISTSERV_PASSWORD_HERE
21 changes: 21 additions & 0 deletions .github/workflows/enforce-staging-to-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Enforce staging → main

on:
pull_request:
branches: [main]

jobs:
enforce-staging-source:
name: enforce-staging-source
runs-on: ubuntu-latest
steps:
- name: Verify PR source branch is staging
env:
HEAD_REF: ${{ github.head_ref }}
run: |
if [ "$HEAD_REF" != "staging" ]; then
echo "::error::Pull requests into main must come from 'staging' (got '$HEAD_REF')."
echo "Merge your branch into staging first, then open a PR from staging into main."
exit 1
fi
echo "OK: PR source is staging."
41 changes: 41 additions & 0 deletions .github/workflows/scrape_listserv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Scrape WhitmanWire

on:
schedule:
# Runs at 8:00 AM UTC (4:00 AM Eastern Time) every day
- cron: '0 8 * * *'
workflow_dispatch: # Allows you to click a "Run workflow" button in GitHub's UI

jobs:
scrape-and-commit:
runs-on: ubuntu-latest
# This permission is required so the bot can push the JSON file back to your repo
permissions:
contents: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11' # The script uses standard libraries, so this is fine

- name: Run Scraper
env:
# Pulls securely from GitHub Secrets
LISTSERV_EMAIL: ${{ secrets.LISTSERV_EMAIL }}
LISTSERV_PASSWORD: ${{ secrets.LISTSERV_PASSWORD }}
run: |
python3 apps/listserv-scraper/src/scrape_listserv.py --list WHITMANWIRE --limit 100 --fetch-bodies

- name: Commit and push changes
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Stage the specific data folder where the script saves its output
git add apps/listserv-scraper/data/
# Commit the changes; if there are no new emails, it fails gracefully instead of crashing
git commit -m "chore: update WhitmanWire scraped data" || echo "No changes to commit"
git push
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ build/
!.env.example
!**/.env.example
!**/env.local.example
.forum_venv/

# ---- Database ----
drizzle/
# drizzle/

# ---- Python ----
__pycache__/
Expand Down
190 changes: 190 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# The Forum

Princeton's campus events platform, built by [TigerApps](https://tigerapps.org).

This is a [Turborepo](https://turbo.build) monorepo managed with [Bun](https://bun.sh):

| Package | What it is |
|---|---|
| `apps/web` | **The main app** — Next.js 15 (App Router), React 19, Tailwind v4, shadcn/ui |
| `apps/database` | Shared Drizzle ORM schema + migrations (PostgreSQL) |
| `apps/admin-web` | Admin dashboard — Vite + React |
| `backends/fastapi` | FastAPI backend (Python 3.12, managed with `uv`) |
| `apps/listserv-scraper` | Python scraper for Princeton listserv archives |
| `apps/mpu-scraper` | Scraper for MyPrincetonU events |

New to the project? Follow **Quick start** below — it gets `apps/web` running locally,
which is the primary thing you need. The Python backend and scrapers are optional
until you work on them.

---

## Prerequisites

| Tool | Version | Install |
|---|---|---|
| [Bun](https://bun.sh) | ≥ 1.2 | macOS/Linux: `curl -fsSL https://bun.sh/install \| bash` · Windows: `powershell -c "irm bun.sh/install.ps1 \| iex"` |
| [Docker Desktop](https://www.docker.com/products/docker-desktop/) | latest | docker.com (used only for local Postgres) |
| [Git](https://git-scm.com) | ≥ 2.40 | Pre-installed on macOS; `winget install Git.Git` on Windows |
| [uv](https://docs.astral.sh/uv/) | ≥ 0.5 | Only needed for the Python backend — see [Python backend](#python-backend-optional) |

> **Windows:** use [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) or Git Bash
> for all commands below. Restart your terminal after installing tools so PATH updates apply.

**Never use `npm`, `yarn`, or `pnpm` in this repo — always `bun`.**

---

## Quick start (`apps/web`)

### 1. Clone and install

```bash
git clone https://github.com/TigerAppsOrg/TheForum.git
cd TheForum
bun install # installs every workspace package + sets up Husky pre-commit hooks
```

### 2. Environment variables

Copy the example files:

```bash
cp .env.example .env # root — used by docker-compose
cp apps/web/.env.local.example apps/web/.env.local # Next.js app
cp apps/database/.env.example apps/database/.env # drizzle-kit CLI
```

Then fill in `apps/web/.env.local`. Env vars are validated at startup by
[`apps/web/src/env.ts`](apps/web/src/env.ts) — the app won't boot if a required
one is missing, and that file is the source of truth for what's required.

> **Can't obtain a value yourself? Ask Ibraheem.** He is the contact for all
> credentials that aren't self-serve (Entra ID, Mapbox tokens, AWS, etc.).

| Variable | Where to get it |
|---|---|
| `DATABASE_URL` | Default in the example file works as-is with the Docker database (port **5434**) |
| `AUTH_SECRET` | Generate your own: `openssl rand -base64 32` |
| `AUTH_AZURE_AD_CLIENT_ID` / `AUTH_AZURE_AD_CLIENT_SECRET` | **Ask Ibraheem** — these are the Microsoft Entra ID app credentials for Princeton CAS login |
| `AUTH_AZURE_AD_TENANT_ID` | Princeton's tenant ID — already filled in the example file |
| `NEXT_PUBLIC_MAPBOX_TOKEN` / `NEXT_PUBLIC_CAMPUS_MAP_TOKEN` / `NEXT_PUBLIC_CAMPUS_MAP_STYLE` | **Ask Ibraheem** — Mapbox tokens + the Princeton campus map style URL |
| `AWS_S3_BUCKET` / `AWS_REGION` | Optional (image uploads) — ask Ibraheem if you're working on that feature |

### 3. Start the database

Make sure **Docker Desktop is running**, then from the repo root:

```bash
bun run db:up # starts Postgres 17 in Docker (container: the-forum-db, host port 5434)
bun run db:push # push the Drizzle schema into the fresh database
```

Sanity checks:

```bash
docker compose ps # the-forum-db should show "Up (healthy)"
bun run db:logs # tail the Postgres logs if something looks wrong
```

The database URL is `postgresql://forum:forum_password@localhost:5434/the_forum`
(also reachable with any Postgres client, e.g. `psql`, TablePlus, or `bun run db:studio`).

Optionally fill the database with realistic demo data:

```bash
bun run db:seed
```

### 4. Run the app

```bash
cd apps/web && bun run dev
```

Open <http://localhost:3000>. You're set up.

To run **everything at once** (web + admin + FastAPI) from the repo root:

```bash
bun run dev # Turborepo TUI: web :3000, admin-web :5173, FastAPI :8000
```

(FastAPI will only start if you've done the [Python backend](#python-backend-optional) setup.)

---

## Everyday commands

```bash
bun run check # Biome lint + format with auto-fix (run before pushing)
bun run format # format only
bun run build # build all packages

bun run db:up # start Postgres db:down stop it (data persists)
bun run db:push # push schema (dev) db:generate generate SQL migrations
bun run db:migrate # apply migrations db:studio visual DB browser
bun run db:seed # seed demo data (safe to re-run any time)
```

Pre-commit hooks (Husky + lint-staged) automatically run Biome on staged files —
if your commit fails, read the Biome output, fix, and re-commit.

### Conventions

- **Env vars in `apps/web`:** always `import { env } from "~/env"` — never `process.env.*` directly.
New vars get added to `apps/web/src/env.ts` *and* the `.env.example` files.
- **UI components:** use [shadcn/ui](https://ui.shadcn.com). Add new ones from `apps/web`:
`bunx shadcn@latest add <component>`.
- **Linting:** Biome only (no ESLint/Prettier). Python uses Ruff.

---

## Python backend (optional)

Only needed if you're working on `backends/fastapi` or the scrapers.

```bash
cd backends/fastapi
cp .env.example .env # default DATABASE_URL works with the Docker database
uv sync # creates .venv and installs all dependencies
bun run dev # = uv run uvicorn app.main:app --reload --port 8000
```

API docs live at <http://localhost:8000/docs>. Lint with `uv run ruff check .`
and format with `uv run ruff format .`.

---

## Branching workflow

`main` is protected — you cannot push to it directly, and pull requests into `main`
are only accepted from `staging`.

1. Branch off `main`: `git checkout -b feat/my-feature origin/main`
2. Open a PR **into `staging`** and merge it there
3. When `staging` is ready to ship, open a PR from `staging` into `main`

---

## Troubleshooting

**The app crashes on startup with "Invalid environment variables"**
A required var in `apps/web/.env.local` is missing or malformed — compare against
`apps/web/.env.local.example` and the table above.

**`ECONNREFUSED` / `DATABASE_URL` errors**
The database container isn't running (`bun run db:up`), or your `DATABASE_URL`
uses the wrong port — the Docker database listens on **5434**, not 5432.

**Port 5434 already in use**
Change `POSTGRES_PORT` in the root `.env` and update `DATABASE_URL` everywhere to match.

**Husky hooks not running**
Re-run `bun install` from the repo root (the `prepare` script reinstalls hooks).

**`bun run dev` doesn't start FastAPI**
Expected unless you've run `uv sync` in `backends/fastapi` and `uv` is on your PATH.

**Wipe the database and start fresh**
`docker compose down -v` (deletes the data volume), then `bun run db:up && bun run db:push && bun run db:seed`.
Loading
Loading