version: "1.0"

service:
  name: municipal-transit-planner
  environment: production
  region: ca-central-1
  timezone: America/Toronto
  replicas: 3

image:
  repository: registry.city.example/transit/planner
  tag: "2026.07.31"
  pullPolicy: IfNotPresent

server:
  host: 0.0.0.0
  port: 8080
  requestTimeout: 15s
  gracefulShutdownTimeout: 30s

routing:
  modes:
    - bus
    - streetcar
    - subway
    - light_rail
    - walking
    - cycling
  maxTransfers: 3
  maxWalkingDistanceMeters: 1200
  wheelchairAccessibleByDefault: false
  transferPenaltySeconds: 240
  walkingSpeedMetersPerSecond: 1.3
  cyclingSpeedMetersPerSecond: 4.2

dataSources:
  gtfs:
    static:
      url: https://open-data.city.example/transit/gtfs.zip
      refreshSchedule: "0 3 * * *"
      validation:
        rejectExpiredFeeds: true
        maximumFeedAgeHours: 48
    realtime:
      tripUpdatesUrl: https://api.city.example/gtfs-rt/trip-updates
      vehiclePositionsUrl: https://api.city.example/gtfs-rt/vehicle-positions
      serviceAlertsUrl: https://api.city.example/gtfs-rt/service-alerts
      refreshIntervalSeconds: 20
      timeoutSeconds: 5
  municipalOpenData:
    bikeStationsUrl: https://open-data.city.example/mobility/bike-stations.json
    accessibleEntrancesUrl: https://open-data.city.example/transit/accessible-entrances.geojson

database:
  driver: postgresql
  host: transit-db.internal
  port: 5432
  name: transit_planner
  usernameFromSecret: transit-planner-db
  passwordFromSecret: transit-planner-db
  sslMode: require
  pool:
    minimumConnections: 5
    maximumConnections: 30
    idleTimeoutSeconds: 300

cache:
  provider: redis
  host: transit-cache.internal
  port: 6379
  database: 2
  ttlSeconds:
    itinerary: 120
    stopDepartures: 30
    serviceAlerts: 20

features:
  realtimeArrivals: true
  disruptionAwareRouting: true
  fareEstimation: true
  bikeShareIntegration: true
  parkAndRide: false
  multilingualResults:
    enabled: true
    locales:
      - en-CA
      - fr-CA

fares:
  currency: CAD
  defaultAdultFare: 3.35
  transferWindowMinutes: 120
  reducedFareCategories:
    - senior
    - student
    - youth

observability:
  logLevel: info
  logFormat: json
  metrics:
    enabled: true
    path: /metrics
  tracing:
    enabled: true
    sampleRate: 0.1
  healthChecks:
    livenessPath: /health/live
    readinessPath: /health/ready

rateLimits:
  anonymous:
    requestsPerMinute: 60
    burst: 20
  authenticated:
    requestsPerMinute: 300
    burst: 75

privacy:
  retainSearchHistory: false
  anonymizeClientAddresses: true
  preciseLocationLogRetentionHours: 0

alerts:
  staleRealtimeFeedMinutes: 5
  failedStaticImportThreshold: 1
  notificationChannel: transit-operations

maintenance:
  graphRebuildSchedule: "15 3 * * *"
  retainPreviousGraphs: 3
  temporaryDirectory: /var/lib/transit-planner/tmp