Skip to Content
⚠️Active Development Notice: TimeTiles is under active development. Information may be placeholder content or not up-to-date.
DevelopmentContributing

Development Setup

Environment setup and day-to-day development workflows for TimeTiles.

Quick Start

git clone https://github.com/jfilter/timetiles.git cd timetiles make init # installs deps, starts DB, runs migrations, seeds, starts dev server

See Quick Start for prerequisites and database mode options.

Commands

CommandWhat it does
make devStart dev server (auto-starts database)
make checkLint + typecheck all packages
make testRun unit + integration tests
make test-e2eRun Playwright E2E tests
pnpm exec oxfmt <file>Format the reported files only
make migrateRun database migrations
make seedSeed database with sample data
make freshFull reset: database + migrate + seed
make statusCheck environment health

make format and pnpm format run only the formatter, without lint autofixes. Prefer named files to avoid unrelated formatting changes. Avoid broad eslint --fix runs: they can strip suppressions for oxlint-owned rules. make check-ai reports whole-tree formatting failures even when other checks are scoped.

make clean deletes the development database; make fresh does the same and then migrates and reseeds it. Back up any data you need before using either command. Docker cleanup is limited to this project’s Compose resources; it does not prune other projects’ resources.

make check-ai without arguments runs fast Oxlint and TypeScript checks across the packages, including Shared and the scraper SDK. It does not run ESLint; use pnpm lint for the full workspace lint gate. PACKAGE=web also runs ESLint, while FILES="..." uses Oxlint and filters TypeScript diagnostics to the requested files. Package selectors are web, docs, ui, and timescrape; the legacy scraper alias selects the TimeScrape runner, not the SDK.

ESLint runs from the repository root so SonarJS can resolve dependency versions from pnpm-workspace.yaml. The shared pnpm -w lint:eslint <root-relative paths> command uses ESLint’s file-based configuration lookup, preserving each package’s rules and ignores. Package lint scripts keep separate cache files; use those scripts or pnpm lint for normal checks. The Oxlint bridge resolves its configuration relative to the repository, not the current working directory.

Database Seeding

make seed ARGS="development" # Rich, realistic data (default) make seed ARGS="testing --truncate" # Fast, deterministic data for tests make seed ARGS="demo" # Polished data for demos

Available presets: minimal, testing, e2e, development, demo, benchmark. Add --truncate to clear existing data first.

Workflow

  1. Create a feature branch from main
  2. Make your changes
  3. Run make check — lint and typecheck must pass
  4. Write tests for new functionality
  5. Commit using conventional commits
  6. Open a pull request

Code Standards

  • TypeScript strict mode — all code must pass strict type checking
  • Named imports only — import { foo } from 'bar'
  • No console.log — use logger.info() / logError() from @/lib/logger
  • React Query for all data fetching — never fetch directly in components
  • Coordinates in [longitude, latitude] order (GeoJSON standard)
  • PostGIS for spatial queries — no client-side geo computations

Layered Architecture

The lib/ directory follows a strict import hierarchy:

Layer 0 — Foundation utils/, security/, types/, constants/, geospatial/, filters/, definitions/, schemas/ Layer 1 — Infrastructure (can import Layer 0) services/, database/, middleware/ Layer 2 — Domain (can import Layer 0 + 1) ingest/, account/, export/, email/, collections/, blocks/ Layer 3 — Application api/, hooks/, jobs/, config/, context/, globals/, openapi/, seed/, data-packages/, metadata/

Each layer can only import from the same layer or below. packages/eslint-config/base.js enforces this and declares per-file exceptions, including foundation configuration helpers and the Payload composition root.

Migrations

make migrate-create # Auto-generate from schema changes make migrate # Apply pending migrations

Never create migration files manually — always use Payload’s generator.

Troubleshooting

ProblemSolution
Port 3000 in usemake kill-dev
Database connection errormake status, then make ensure-infra
Stale statemake fresh
TypeScript errors after updatespnpm install && make check

Further Reading

Last updated on