Tabliczki ZTM (MVP) — live stop-board dashboards for ZTM Gdańsk
- 1. Project name
- 2. Project description
- 3. Tech stack
- 4. Getting started locally
- 5. Available scripts
- 6. Testing
- 7. API Testing with Postman
- 8. Test plan
- 9. Project scope
- 10. Project status
- 11. License
Tabliczki ZTM is a web app for tracking real-time departures from multiple public transport stops in Gdańsk (ZTM Gdańsk). It aggregates data from the Open Gdańsk / Otwarty Gdańsk public API and presents it as customizable dashboards (sets of stop boards).
The core idea is to make it fast to monitor several boards at once, plus provide a TV / high-readability view that can run passively on a monitor/TV.
- Product requirements (PRD): see
.ai/prd.md - Tech stack notes: see
.ai/tech-stack.md - QA / Test plan: see
.ai/test-plan.md
- Frontend
- Astro 5: routing and server-side rendering (SSR)
- Svelte 5: interactive UI (dashboard, widgets, search, management views)
- TypeScript 5
- CSS: modern, native CSS (Custom Properties, Grid, Flexbox) — no heavy UI framework
- UI approach: minimally styled native HTML elements (
<dialog>,<form>,<button>,<input>)
- Backend
- Supabase: PostgreSQL + Auth + RLS (used for user-owned sets and set items)
- Server API (Astro): REST endpoints for auth/sets/items and ZTM proxy endpoints (with caching/timeouts)
- Supabase Edge Functions (optional / future): alternative place for ZTM proxy/aggregation/caching
- Infrastructure (planned)
- Vercel (recommended)
- CI/CD: GitHub Actions
- Data source
- Open Gdańsk (ZTM Gdańsk):
https://ckan.multimediagdansk.pl/dataset/tristar
- Open Gdańsk (ZTM Gdańsk):
- Node.js:
22.14.0(from.nvmrc) - npm: comes with Node.js
nvm use
npm install
npm run devThen open the dev server URL printed by Astro (typically http://localhost:4321).
src/
components/ # Astro + Svelte components
layouts/ # Astro layouts
lib/ # services and helpers
pages/ # Astro pages (incl. pages/api for endpoints)
styles/ # global styles
public/ # static public assets
From package.json:
npm run dev: start the Astro dev servernpm run build: build for productionnpm run preview: preview the production build locallynpm run astro: run the Astro CLInpm run lint: run ESLint on the reponpm run lint:fix: auto-fix ESLint issues where possiblenpm run format: format with Prettiernpm run test: run all tests (unit + E2E)npm run test:unit: run unit tests with Vitestnpm run test:unit:watch: run unit tests in watch modenpm run test:unit:ui: run unit tests with Vitest UInpm run test:unit:coverage: run unit tests with coverage reportnpm run test:e2e: run E2E tests with Playwright (excludes screenshot tests)npm run test:e2e:ui: run E2E tests with Playwright UInpm run test:e2e:headed: run E2E tests in headed mode (see browser)npm run test:e2e:debug: debug E2E tests with Playwright Inspectornpm run screenshots: generate screenshots for documentation (headed mode)npm run screenshots:ci: generate screenshots for documentation (headless mode)
The project includes comprehensive test coverage:
- Unit tests: Vitest for validation, error mapping, and business logic
- Integration tests: API endpoint tests with mocked database
- E2E tests: Playwright for full user flow testing
- Screenshot tests: Automated screenshot generation for documentation
# Run all tests
npm run test
# Run unit tests only
npm run test:unit
# Run E2E tests only (excludes screenshots)
npm run test:e2e
# Watch mode for development
npm run test:unit:watch
# Generate coverage report
npm run test:unit:coverageAutomated tool for capturing app screenshots in multiple variants:
# Generate screenshots (see browser)
npm run screenshots
# Generate screenshots (headless, for CI)
npm run screenshots:ciFeatures:
- Captures all business flows (login, dashboard, sets, stops, TV view)
- Generates 4 variants: desktop/mobile × light/dark theme
- Organized output:
screenshots/{viewport}/{theme}/{screen-name}.png - Note: Screenshot tests run separately from regular E2E tests to avoid conflicts
- Test directory structure: src/tests/README.md
- Test plan: .ai/test-plan.md
- E2E setup guide: E2E_SETUP.md
vitest.config.ts- Vitest configurationplaywright.config.ts- Playwright configuration.env.test.example- Example test environment variables (copy to.env.test)
You can test the REST API endpoints locally using Postman (or any HTTP client). This repo does not include a Postman collection/environment yet, so configure the base URL manually (e.g. http://localhost:4321).
- Authenticate:
- Protected endpoints use Supabase session cookies.
- In Postman: call
POST /api/auth/loginfirst and keep cookies enabled for subsequent requests.
- Sets Management: GET, POST, PATCH, DELETE operations on sets
- Set Items Management: GET, POST, DELETE operations on items within sets
- ZTM (public): stops and departures endpoints for testing upstream integration
- ✅ Works with the local dev server (
npm run dev) - ✅ Supports testing both protected and public endpoints
For detailed setup instructions, authentication methods, and troubleshooting, see:
- .ai/api-plan.md - Full API specification
# 1. Start the dev server
npm run devRecommended checks for API responses:
- HTTP status codes
- Response structure
- Error codes and messages
- Business logic constraints (max 6 sets, max 6 items, etc.)
The project’s QA assumptions, scenarios, and acceptance criteria are described in:
- Authentication
- Email/password sign-up and sign-in
- No email verification required by default in MVP (but UI supports environments that require confirmation)
- Session persistence (“remember me” behavior)
- Stop-board sets
- Up to 6 sets per user
- Set name up to 20 characters
- Rename inline on the sets list (save on Enter / blur)
- Delete sets (with their content)
- Dashboard
- Grid of widgets: up to 6 stop boards per set
- Stop search with autocomplete (name, pole number, direction)
- Widget shows: line, direction, arrival time (relative/absolute), accessibility icons (bike, stroller/wheelchair)
- Show first 6 departures, scroll to see more
- Special messages ticker/marquee when API returns messages
- Refreshing & resiliency
- Auto refresh every 60 seconds
- Shared refresh progress bar at the top of the screen (under header)
- On refresh errors: warnings and retry on the next cycle; after 3 consecutive failures the refresh cycle is stopped with a “Try again” CTA
- Refresh is paused while dialogs are open and when the browser tab is hidden; on return it refreshes immediately and resets the error counter
- TV mode (public, no login) ✅ IMPLEMENTED
- Accessible via
/tv/{stopId}route - High readability: large stop name, clock (HH:mm), list of departures
- Passive view with minimal interaction (theme toggle, reload on error)
- Auto-refresh every 60 seconds with retry mechanism (max 3 attempts)
- Optimized for large screens (responsive typography up to 3rem)
- Accessible via
- UI
- Header: current time, set switcher (dashboard), links to set/account management
- Theme switcher: Light / Dark / System (default), persisted locally (fallback to
prefers-color-schemewhen unset) - Responsive layout (RWD)
- Offline mode (requires a constant API connection)
- Social features and sharing sets between users
- Push notifications for disruptions
- Map-based stop search
- Manual reordering of boards in the grid (only add/remove)
- Advanced filtering of lines within a single board
MVP: in progress. Requirements are defined in .ai/prd.md; implementation may be partial and will evolve as features are built and integrated.
MIT (as currently stated by the repository).
If you want this to be explicit for GitHub tooling, add a LICENSE file with the MIT text.