Saan sa UPLB ang ___?

Schedules, buildings, jeepney routes, and "where is PSLH 1?" on one campus map.
Room TBA is a map-first web app for UPLB students. You search a room code, building nickname, or course; the app puts it on an interactive campus map, shows schedules when we have them, and keeps working when the signal drops.
No account needed to browse. Editors and contributors fix data in the same app (login popup on the map, not a separate admin site).
Data note: Room and class listings are updated each term by volunteers. The active term follows the academic calendar (midyear Jun–Jul, 2nd sem Jan–May, etc.). Class search lists lecture, lab, thesis, special problem, and similar sections; ones without a room in AMIS show as unassigned. Room schedules list only lecture and lab sections with assigned rooms. Wrong schedule? Open an issue.
| Goal | How |
|---|---|
| Find PSLH 1 or PhySci | Search + aliases (PhySci, HUM, …) |
| Room schedule this sem | Term filter + timetable |
| Personal schedule route | Build a plan in Planner → Map tools → Schedule → pick a day, route stops |
| Browse all classes | Status bar → Browse classes; search by course code |
| Plan your classes | Planner view to build a draft schedule |
| Course Planner explainer | Four-panel, screenshot-ready guide |
| Final exam time & room | Search course code → finals panel; room panel during finals week |
| Building location | Map, pins, directions, Google Maps |
| Landmarks, services, orgs & offices | Sidebar directories, distinct map pins, and shareable detail links |
| Offline / bad signal | PWA + local cache; tiles if already loaded |
| Campus events | Events on map with routes |
| Jeepney routes | Route overlays |
| 3D view | Buildings + Makiling terrain (online) |
| Understand section names | Wiki guide to the A–H / S–Z class time blocks |
Editor / contributor mode (password from the team)
| Power | Where |
|---|---|
| Move building & dorm pins | Map edit mode (pencil) |
| Add or correct landmarks, services, organizations, offices & units | Add something to the map or the side-panel editor; pick the map pin |
| Fix room/building/college copy | Side panel → Edit |
| Suggest edits without publishing | Suggest an edit → admin review queue |
| Upload event posters | Event editor + R2 image upload (when configured) |
| Manage public credit | Account settings → optional HTTPS avatar/profile link; uncheck credits to opt out |
| Undo a pin drag | Toolbar undo/redo (session); durable history tracked in #202 |
Login: /?editor=login or the shield / status bar in the app. /admin URLs redirect back into the map.
flowchart LR
subgraph browser [Your phone or laptop]
Search[Search bar]
PGlite[(PGlite offline cache)]
Map[Map + side panel]
end
subgraph cloud [When online]
API[Astro API routes]
DB[(Supabase Postgres)]
end
Search --> PGlite
PGlite -->|stale or empty| API
API --> DB
API --> Map
PGlite --> Map
- First visit online: app syncs buildings, rooms, classes, aliases, and events into browser storage.
- You search: local data first; network when sync keys say something changed.
- You pick a result: map flies to the pin; side panel shows schedules, directions, and a share link.
- You go offline: last sync still answers "saan ang room na 'to?" (map tiles need a prior download or visit).
- Astro 7 + Svelte 5
- Bun
- Supabase Postgres + Drizzle (
drizzle/) - PGlite in the browser for offline data
- MapLibre GL, OSM / MapTiler tiles
- Vercel for SSR and API routes
- Cloudflare R2 for event uploads (optional)
Contributor notes: AGENTS.md
- Bun 1.3+
- A Supabase Postgres URL (
DATABASE_URL); session pooler recommended for dev ADMIN_PASSWORDif you want editor login locallyISR_BYPASS_TOKEN(optional locally; required on Vercel for on-demand SEO page revalidation after editor publishes)
git clone https://github.com/uplbtools/room-tba.git
cd room-tba
cp .env.example .env.local
# Fill DATABASE_URL (staging pooler) and ADMIN_PASSWORD; see .env.example for prod/E2E URLs
bun install
bun devOpen http://localhost:4321. Without DATABASE_URL, the dev server starts but pages that hit the DB will 500. That is expected.
This project uses Biome for both formatting and linting (replacing Prettier and ESLint).
# Check format + lint (no writes):
bun run lint
# Auto-fix all safe issues:
bun run lint:fix
# Format only:
bun run formatInstall the Biome VS Code extension for format-on-save support. The workspace settings in .vscode/settings.json configure this automatically.
| Command | Does what |
|---|---|
bun dev |
Dev server |
bun run build |
Production build (needs DATABASE_URL; entity SEO pages render on first request via Vercel ISR, not at build) |
bun test src/lib src/constants |
Unit + store tests (no DB required) |
bun run test:components |
Vitest component/layout tests |
bun run test:integration |
API + DB integration (E2E DB; see docs/testing.md) |
bun run e2e |
Playwright blocking suite (uses serve:e2e: node adapter build + preview) |
bun run e2e:advisory |
Playwright advisory (non-blocking in CI) |
bun run lint |
Biome check (format + lint) |
bun run lint:fix |
Biome check with auto-fixes |
bun run format |
Biome format write |
bunx drizzle-kit studio |
Browse/edit Postgres visually |
bun run seed:aliases |
Seed building aliases from public/room_info.json |
bun run seed:deep-research |
Fill-only data-gap seed from the 2026-07 research report (DATABASE_URL; --dry-run supported) |
bun run generate:pglite-schema |
Regenerate the offline PGlite init SQL from drizzle/schema.ts |
bun run import:osa-orgs |
Add the current public OSA organization directory (DATABASE_URL; safe to rerun) |
bun run import:campus-offices |
Add missing campus offices and units (DATABASE_URL; safe to rerun) |
bun run import:amis-classes |
Upsert AMIS classes (docs/amis-com-refresh-runbook.md) |
bun run import:final-exams |
Import OUR finals JSON into Postgres (DATABASE_URL; see docs/final-exams-data-source.md) |
Legacy data/info.db SQLite is only for old seed/export scripts (bun:sqlite, not runtime). Production uses Supabase Postgres via DATABASE_URL. Archived SQLite migrations live in drizzle-migrations/: do not edit; active schema is drizzle/.
Optional env vars (R2 uploads, Supabase Auth client): see .env.example. Staging vs production: set PUBLIC_APP_ENV=staging on Vercel Preview and local dev; production uses production (default) and hides the staging banner.
flowchart TB
root[room-tba]
root --> src
root --> drizzle["drizzle/ schema + migrations"]
root --> docs["docs/ QA and layout notes"]
root --> public["public/ static assets"]
root --> agents[AGENTS.md]
src --> pages["pages/ routes + /api"]
src --> components["components/ Svelte UI"]
src --> lib["lib/ stores, services, PGlite sync"]
Deep editor QA: docs/editor-foundation-test-plan.md
PR checklist: docs/agentic-qa-process.md
See CONTRIBUTING.md for how to help:
- Report wrong data or campus QA: no clone, no PR
- Write code: branch off
staging, PR tostaging(developer guide) - Maintainers / agents: AGENTS.md · agent tooling (
bun run install:agent-tooling+install:agent-pluginsonce per machine)
Good first issues · Data: label data · QA: label qa
Implementers: issue hygiene · PR QA process
Version follows semver. Pushes to main run semantic-release (skip with [skip ci] in the commit message). The in-app status bar shows vX.Y.Z from package.json.
Dry run: bun run release:dry
Maintainer: Simonee Ezekiel Mariquit
Built with help from:
| Person | Helped with |
|---|---|
| Ken Ramiscal | UI, offline support, map |
| Kalinaw Lukas Aom Bebis | UI, bug fixes, map |
| Niño Anthony Marmeto | Electrical Engineering building info |
| Rosh Almario | Institute of Chemistry room directions |
| Eunice Almeyda | Logo |
| Mary Gwyneth Telmosa | UI design |
Org: uplbtools · Campus tool, not an official UPLB product.
MIT. Use it, fork it, teach with it. If you deploy a fork for another campus, change the data, not just the logo.