managarten/apps/citycorners/CLAUDE.md
Till JS 8b96b82428 feat(citycorners): add 7 new location categories with 35 seed entries
Add cafe, bar, park, beach, hotel, event_venue, and viewpoint categories
to the CityCorners city guide. Each category includes 5 real Konstanz
locations with descriptions, addresses, and coordinates.

Changes across all layers: DB schema enum, DTOs, lookup keyword detection,
i18n (DE/EN), map colors, filter pills, landing page, and seed data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:53:04 +01:00

149 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CityCorners
City guide for Konstanz (Bodensee) showcasing locations, restaurants, museums, and sights.
## Live URLs
| Service | URL |
|---------|-----|
| **Web App** | https://citycorners.mana.how |
| **API** | https://citycorners-api.mana.how |
| **Landing** | https://citycorners-landing.pages.dev |
## Architecture
```
apps/citycorners/
├── apps/
│ ├── landing/ # Astro static site (Tailwind, Cloudflare Pages)
│ ├── backend/ # NestJS API (port 3025 dev, 3041 prod)
│ └── web/ # SvelteKit web app (port 5196 dev, 5022 prod)
└── CLAUDE.md
```
### Tech Stack
- **Backend:** NestJS 10, Drizzle ORM, PostgreSQL, mana-core-auth (JWT)
- **Web:** SvelteKit 2, Svelte 5 runes, Tailwind 4, Leaflet maps, svelte-i18n (DE/EN), PWA
- **Landing:** Astro 5, Tailwind 3, static site generation
- **Search:** mana-search integration (SearXNG + content extraction)
## Development
```bash
# Full stack (auth + backend + web)
pnpm dev:citycorners:full
# Individual apps
pnpm dev:citycorners:landing
pnpm dev:citycorners:backend
pnpm dev:citycorners:web
# Database
pnpm citycorners:db:push # Push schema
pnpm citycorners:db:studio # Drizzle Studio
pnpm citycorners:db:seed # Seed 41 sample locations
# Tests
pnpm --filter @citycorners/backend test # Run all tests (31 tests)
pnpm --filter @citycorners/backend test:watch # Watch mode
pnpm --filter @citycorners/backend test:cov # Coverage report
# Deploy
pnpm deploy:landing:citycorners # Landing to Cloudflare Pages
```
## Database
PostgreSQL database `citycorners` with Drizzle ORM.
### Schema
- **locations** name, category (enum: sight/restaurant/shop/museum/cafe/bar/park/beach/hotel/event_venue/viewpoint), description, address, lat/lng, imageUrl, timeline (JSONB array of {year, event})
- **favorites** userId, locationId (FK → locations, cascade delete), unique constraint on (userId, locationId)
## API Endpoints
All endpoints are prefixed with `/api/v1/` in production (via shared-nestjs-setup).
### Locations
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/locations` | No | List all (optional `?category=sight\|restaurant\|shop\|museum`) |
| GET | `/locations/search?q=` | No | Text search (ILIKE on name, description, address) |
| GET | `/locations/lookup?q=` | No | Web lookup via mana-search (scrapes info, auto-fills form) |
| GET | `/locations/:id` | No | Get single location |
| POST | `/locations` | Yes | Create location |
| PUT | `/locations/:id` | Yes | Update location |
| DELETE | `/locations/:id` | Yes | Delete location |
### Favorites
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/favorites` | Yes | List user's favorite location IDs |
| POST | `/favorites/:locationId` | Yes | Add to favorites |
| DELETE | `/favorites/:locationId` | Yes | Remove from favorites |
## Web App Pages
| Route | Description |
|-------|-------------|
| `/` | Location grid with category filter pills |
| `/map` | Leaflet map with color-coded markers |
| `/locations/:id` | Detail page with mini-map, timeline, favorite button |
| `/add` | Two-step flow: web lookup → edit form → submit |
| `/favorites` | User's saved locations |
| `/settings` | Theme mode/variant, account, about |
| `/login`, `/register` | Auth via shared-auth-ui |
| `/offline` | PWA offline fallback |
## Features
- **PWA:** Installable, offline fallback, service worker caching (API: NetworkFirst, images: CacheFirst)
- **i18n:** German + English, language switcher in PillNav, localStorage persistence
- **Favorites:** Optimistic updates, auth-gated heart button on cards + detail page
- **Search:** QuickInputBar in PillNav, backend ILIKE search
- **Web Lookup:** mana-search integration for auto-filling location data from the web
- **Branding:** Registered in shared-branding (AppId, icon, APP_URLS, app switcher)
## Categories
| DB Value | Label (DE) | Label (EN) | Card Color |
|----------|------------|------------|------------|
| `sight` | Sehenswürdigkeit | Sight | Blue |
| `restaurant` | Restaurant | Restaurant | Red |
| `shop` | Laden | Shop | Green |
| `museum` | Museum | Museum | Purple |
| `cafe` | Café | Café | Amber |
| `bar` | Bar | Bar | Orange |
| `park` | Park | Park | Emerald |
| `beach` | Strandbad | Beach | Cyan |
| `hotel` | Hotel | Hotel | Indigo |
| `event_venue` | Veranstaltungsort | Event Venue | Pink |
| `viewpoint` | Aussichtspunkt | Viewpoint | Sky |
## Tests
4 test suites, 31 tests covering:
- `LocationService` CRUD, search, category filtering
- `FavoriteService` add/remove/check, conflict handling
- `LocationLookupService` web search, content extraction, address/category detection, error handling
- `LocationController` endpoint routing, query params, auth guards
## Docker
- **Backend:** `apps/citycorners/apps/backend/Dockerfile` (multi-stage, port 3041 prod)
- **Web:** `apps/citycorners/apps/web/Dockerfile` (multi-stage, port 5022 prod)
- **Entrypoints:** Auto schema push, optional seed on start
- **docker-compose.macmini.yml:** Both services configured with health checks
## Environment Variables
| Variable | Used by | Description |
|----------|---------|-------------|
| `DATABASE_URL` | Backend | PostgreSQL connection string |
| `MANA_CORE_AUTH_URL` | Backend | Auth service URL |
| `MANA_SEARCH_URL` | Backend | mana-search service URL |
| `PUBLIC_BACKEND_URL` | Web | Backend API URL |
| `PUBLIC_MANA_CORE_AUTH_URL` | Web | Auth service URL (client) |