Skip to content

Street Guides: UI + API

This document describes the current street-guide behavior implemented in the web app and Firebase Functions API.

Map UI Behavior

Map provider:

  • MapEditor now uses Leaflet + OpenStreetMap tiles (free provider), not Google Maps.

Street detail page (/streets/:streetId)

  • Map view is rendered via MapEditor in street-context mode.
  • The map intentionally stays lightweight:
    • Draws only the A→B street line.
    • Shows endpoint markers A and B.
    • Does not render business/shop markers.
    • Does not render building polygons/markers.
  • The map includes:
    • A to B distance badge (km).
    • Locate A button.
    • Locate B button.
    • Locate Street button (fits A/B in view).
    • Get There link to Google Maps directions.
    • Route A-B link to Google Maps A→B walking route.

Street editor page (/streets/:streetId/edit)

  • Map view is rendered via MapEditor in default mode.
  • Endpoint markers A and B are visible and draggable when edit mode is on.
  • Enter Edit Mode / Exit Edit Mode is controlled in toolbar.
  • In edit mode:
    • Drag A and B to update startPoint and endPoint.
    • Click map to place new businesses.
  • Shop markers are intentionally not rendered on the map for a lighter street-level view.

Street View mode

  • Uses StreetViewEditor (not the map) for immersive street view.
  • Viewer location is only applied when user is near the street (distance check in StreetDetailPage).

Firestore Data Model (Street)

  • Street guide document: streetGuides/{streetId}
  • Businesses subcollection: streetGuides/{streetId}/businesses/{businessId}
  • Buildings subcollection: streetGuides/{streetId}/buildings/{buildingId}
  • Key street geometry fields:
    • startPoint: { lat, lng } (A)
    • endPoint: { lat, lng } (B)

Firestore Rules

Current rules allow authenticated reads and writes for street guides and nested businesses/buildings:

  • match /streetGuides/{streetGuideId}
  • match /streetGuides/{streetGuideId}/businesses/{businessId}
  • match /streetGuides/{streetGuideId}/buildings/{buildingId}

File: firestore.rules

REST API (Firebase Functions)

Base:

  • Authenticated API: /api/v1/*
  • OpenAPI spec JSON: /openapi.json (public)

Street routes are defined in: functions/src/api/routes/streets.ts

Street guides

  • GET /api/v1/streets
  • GET /api/v1/streets/:id
  • POST /api/v1/streets
  • PATCH /api/v1/streets/:id
  • DELETE /api/v1/streets/:id

Street businesses

  • GET /api/v1/streets/:id/businesses
  • GET /api/v1/streets/:id/businesses/:bizId
  • POST /api/v1/streets/:id/businesses
  • PATCH /api/v1/streets/:id/businesses/:bizId
  • DELETE /api/v1/streets/:id/businesses/:bizId

Street buildings

  • GET /api/v1/streets/:id/buildings
  • GET /api/v1/streets/:id/buildings/:buildingId
  • POST /api/v1/streets/:id/buildings
  • PATCH /api/v1/streets/:id/buildings/:buildingId
  • DELETE /api/v1/streets/:id/buildings/:buildingId

OpenAPI Docs Update Flow

OpenAPI is generated from route metadata and emitted to:

  • Source: functions/src/api/openapi.ts
  • Generator script: functions/scripts/generate-openapi.ts

Regenerate with:

bash
cd functions
npm run generate:openapi

The API function serves the generated spec at /openapi.json.