Files
SIB/CLAUDE.md

4.6 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

SIBU (Sistema de Transporte) is a PWA for public transportation in Panama. It has two main parts:

  • Backend: FastAPI + SQLModel + PostgreSQL (in backend/), managed with uv
  • Frontend: Vue 3 + Vite + TypeScript + Tailwind CSS (in frontend/), managed with bun

The frontend uses Supabase for auth and real-time data, while the backend provides the REST API. Both can be used together or independently.


Commands

Development

make dev              # Run both backend + frontend concurrently
make dev-backend      # Backend only → http://localhost:8000
make dev-frontend     # Frontend only → http://localhost:5173

Install

make setup            # Install all deps + instructions
make install-backend  # uv sync
make install-frontend # bun install

Migrations

make migrate-up                        # Apply all pending
make migrate-down                      # Rollback last
make migrate-create NAME=nombre        # Create new migration
make migrate-history                   # Show history

Lint & Format

make lint-backend      # ruff check --fix
make format-backend    # ruff format
make lint-frontend     # bun run build (type-check via vue-tsc)

Tests

make test-backend      # uv run pytest
make test-frontend     # bun run test

Database utilities

make seed              # Seed initial data
make db-reset          # Drop all tables + recreate (asks for confirmation)
make import-coordinates ROUTE="Boquete>David"  # Import coords from Supabase
make import-coordinates ALL=true

Package Management Rules

  • Backend: NEVER edit pyproject.toml manually — use uv add <package>
  • Frontend: NEVER edit package.json manually — use bun add <package>

Environment Variables

Backend (backend/.env.development)

DATABASE_URL=postgresql+asyncpg://localhost:5432/sibu_dev
ENVIRONMENT=development
DEBUG=true

Frontend (frontend/.env.development)

VITE_API_URL=http://localhost:8000
VITE_GOOGLE_MAPS_API_KEY=...
VITE_SUPABASE_URL=...
VITE_SUPABASE_ANON_KEY=...

Architecture

Frontend Architecture

Auth is handled by Supabase (src/supabase.ts). The useAuthStore (Pinia) listens to onAuthStateChange and only reloads the user profile on SIGNED_IN / INITIAL_SESSION events — not on TOKEN_REFRESHED — to avoid network hangs on mobile wake.

User roles: PASSENGER (default), DRIVER, PROMOTER, ADMIN. The router (src/router/index.ts) enforces role-based access via meta.requiresAuth and meta.role. Auth check has a 3-second timeout to avoid blocking the UI.

State: Pinia stores in src/stores/ — one per domain (auth, route, busStop, map, shuttle, taxi, coupon, favorites, schedule, theme). State is persisted via pinia-plugin-persistedstate.

Services (src/services/) are thin API clients — one per resource. They call the FastAPI backend or Supabase directly.

Composables (src/composables/) contain map logic: useGoogleMaps, useMapState, useDirectionsRoute, useETA, useParadaCercana, useFlujoPrincipal.

Routing structure:

  • / — Landing
  • /map — Main Google Maps view
  • /routes, /schedules, /bus-stop/:id — Transit info
  • /transporte/viajes-turisticos — Tourist shuttles (nested layout)
  • /transporte/taxis-locales — Local taxis
  • /discover, /coupons, /favorites, /profile — App features
  • /admin, /driver, /promoter — Role-protected dashboards

PWA: Configured with vite-plugin-pwa. Service worker uses autoUpdate. API routes (/api, /rest/v1) are excluded from navigation fallback to prevent blank screens.

i18n: vue-i18n with es and en locales in src/i18n/locales/.

Backend Architecture

backend/app/
  ├── api/        # Route handlers (FastAPI routers)
  ├── core/       # config.py (pydantic-settings), database.py, seed.py
  ├── models/     # SQLModel table models
  ├── schemas/    # Pydantic request/response schemas
  └── services/   # Business logic layer

Config is loaded from app/core/config.py using pydantic-settings. Database sessions use async SQLAlchemy via asyncpg. All API routes use the /api/ prefix.

Vue Component Conventions

  • Always use <script setup> with TypeScript
  • Import paths use the @/ alias for src/
  • Components are split: components/ (reusable), views/ (full screens)
  • Map-related components live in components/map/