# Gas Stations Feature

Complete gas station discovery and management feature with Google Maps integration, caching, and user favorites.

## Quick Summary

Search nearby gas stations via Google Maps API. Users can view stations on a map, save favorites with custom notes, and integrate station data into fuel logging. Search results cached for 1 hour. JWT required for all endpoints. User data isolation via `user_id`.

## Implementation Phases Status

| Phase | Feature | Status |
|-------|---------|--------|
| 1 | Frontend K8s-aligned secrets pattern | ✅ Complete |
| 2 | Backend improvements (circuit breaker, tests) | ✅ Complete |
| 3 | Frontend foundation (types, API, hooks) | ✅ Complete |
| 4 | Frontend components (card, list, form, map) | ✅ Complete |
| 5 | Desktop page with map/search layout | ✅ Complete |
| 6 | Mobile screen with tab navigation | 🔄 In Progress |
| 7 | Fuel logs integration (StationPicker) | ⏳ Pending |
| 8 | Testing (unit, integration, E2E) | ⏳ Pending |
| 9 | Documentation (API, setup, troubleshooting) | ⏳ Pending |
| 10 | Validation & Polish (lint, tests, manual) | ⏳ Pending |
| 11 | Deployment preparation & checklist | ⏳ Pending |

## Architecture

### Backend Structure
```
features/stations/
├── api/                        # HTTP handlers and routes
│   ├── stations.controller.ts
│   └── stations.routes.ts
├── domain/                     # Business logic
│   ├── stations.service.ts
│   └── stations.types.ts
├── data/                       # Database access
│   └── stations.repository.ts
├── external/google-maps/       # External API
│   ├── google-maps.client.ts
│   ├── google-maps.circuit-breaker.ts
│   └── google-maps.types.ts
├── jobs/                       # Scheduled tasks
│   └── cache-cleanup.job.ts
├── migrations/                 # Database schema
│   ├── 001_create_stations_tables.sql
│   └── 002_add_indexes.sql
├── tests/                      # Test suite
│   ├── fixtures/
│   ├── unit/
│   └── integration/
└── index.ts                    # Feature exports
```

### Frontend Structure
```
features/stations/
├── types/                      # TypeScript definitions
│   └── stations.types.ts
├── api/                        # API client
│   └── stations.api.ts
├── hooks/                      # React Query hooks
│   ├── useStationsSearch.ts
│   ├── useSavedStations.ts
│   ├── useSaveStation.ts
│   ├── useDeleteStation.ts
│   └── useGeolocation.ts
├── utils/                      # Utilities
│   ├── distance.ts
│   ├── maps-loader.ts
│   └── map-utils.ts
├── components/                 # React components
│   ├── StationCard.tsx
│   ├── StationsList.tsx
│   ├── SavedStationsList.tsx
│   ├── StationsSearchForm.tsx
│   └── StationMap.tsx
├── pages/                      # Page layouts
│   └── StationsPage.tsx        # Desktop
├── mobile/                     # Mobile layouts (Phase 6)
│   └── StationsMobileScreen.tsx
└── __tests__/                  # Tests (Phase 8)
```

## API Endpoints (All require JWT)

```
POST /api/stations/search
  Body: { latitude, longitude, radius?, fuelType? }
  Response: { stations[], searchLocation, searchRadius, timestamp }

POST /api/stations/save
  Body: { placeId, nickname?, notes?, isFavorite? }
  Response: SavedStation

GET /api/stations/saved
  Response: SavedStation[]

GET /api/stations/saved/:placeId
  Response: SavedStation | 404

PATCH /api/stations/saved/:placeId
  Body: { nickname?, notes?, isFavorite? }
  Response: SavedStation

DELETE /api/stations/saved/:placeId
  Response: 204
```

## Database Schema

### station_cache
Temporary Google Places results (auto-cleanup after 24h)

```sql
- id: UUID PRIMARY KEY
- place_id: VARCHAR UNIQUE
- name: VARCHAR
- address: VARCHAR
- latitude: DECIMAL
- longitude: DECIMAL
- rating: DECIMAL
- photo_url: VARCHAR
- created_at: TIMESTAMP
```

### saved_stations
User's favorite stations with metadata

```sql
- id: UUID PRIMARY KEY
- user_id: VARCHAR (indexed)
- place_id: VARCHAR (indexed)
- nickname: VARCHAR
- notes: TEXT
- is_favorite: BOOLEAN
- created_at: TIMESTAMP
- updated_at: TIMESTAMP
- deleted_at: TIMESTAMP (soft delete)
- UNIQUE(user_id, place_id)
```

## Key Features Implemented

✅ **Security**
- User-scoped data isolation via `user_id` filtering
- Parameterized queries (no SQL injection)
- JWT authentication required on all endpoints
- K8s-aligned secrets pattern (never in environment variables)

✅ **Performance**
- Redis caching with 1-hour TTL
- Circuit breaker for resilience (10s timeout, 50% threshold)
- Database indexes on user_id and place_id
- Scheduled cache cleanup (24h auto-expiry)
- Lazy-loaded Google Maps API in browser

✅ **User Experience**
- Real-time browser geolocation with permission handling
- Touch-friendly 44px minimum button heights
- Responsive map with auto-fit bounds
- Saved stations with custom nicknames and notes
- One-click directions to Google Maps

## Testing

### Run Tests
```bash
# Backend feature tests
cd backend
npm test -- features/stations

# Frontend component tests (Phase 8)
cd frontend
npm test -- stations

# E2E tests (Phase 8)
npm run e2e
```

### Coverage Goals
- Backend: >80% coverage
- Frontend components: >80% coverage
- All critical paths tested

## Deployment

### Prerequisites
1. Google Maps API key with Places API enabled
2. PostgreSQL database with migrations applied
3. Redis cache service running
4. Docker for containerization

### Setup
```bash
# Create secrets directory
mkdir -p ./secrets/app

# Add Google Maps API key
echo "YOUR_API_KEY_HERE" > ./secrets/app/google-maps-api-key.txt

# Build and start
make setup
make logs

# Verify
curl https://motovaultpro.com/api/health
```

### Verification
```bash
# Check secrets mounted
docker compose exec mvp-frontend cat /run/secrets/google-maps-api-key

# Check config generated
docker compose exec mvp-frontend cat /usr/share/nginx/html/config.js

# Test API endpoint
curl -H "Authorization: Bearer $TOKEN" https://motovaultpro.com/api/stations/saved
```

## Next Steps (Phases 6-11)

### Phase 6: Mobile Implementation
Create mobile bottom-tab navigation screen with Search, Saved, Map tabs.

### Phase 7: Fuel Logs Integration
Add StationPicker component with autocomplete to FuelLogForm.

### Phases 8-11: Testing, Docs, Validation, Deployment
Follow the detailed plan in `/docs/GAS-STATIONS.md`.

## References

- Full implementation plan: `/docs/GAS-STATIONS.md`
- Runtime config pattern: `/frontend/docs/RUNTIME-CONFIG.md`
- Design patterns: See Platform feature (`backend/src/features/platform/`)
- Component patterns: See Vehicles feature (`frontend/src/features/vehicles/`)
