# GPS Auto-Detect Location Plan for RateRight

## Research Summary

### Current Location Implementation
- **Database Schema**: Uses PostgreSQL `point` type for location storage in `profiles`, `jobs`, and `companies` tables
- **Current Fields**: 
  - `location` (point type) - stores lat/lng coordinates
  - `suburb` (text) - human-readable suburb name
  - `site_address` (text) - full address for job sites
- **TypeScript Types**: Location is typed as `{ lat: number; lng: number } | null`
- **No Existing Geolocation**: No browser geolocation API implementation found

### Database Schema Analysis
```sql
-- Current location fields in jobs table
location point,
suburb text,
site_address text,

-- Current location fields in profiles table  
location point,
suburb text,
```

## GPS/Geolocation Best Practices Research

### Browser Geolocation API
- **navigator.geolocation.getCurrentPosition()** - Standard API for GPS access
- **Accuracy Levels**: 
  - GPS: 3-10 meters (best accuracy)
  - WiFi: 20-50 meters
  - Cell tower: 100+ meters
  - IP-based: 1-100+ km (least accurate)

### Permission Handling
- **HTTPS Required**: Geolocation only works on secure contexts
- **User Consent**: Browser shows permission prompt on first use
- **Permission States**: granted, denied, prompt (default)
- **Best Practice**: Explain why location is needed before requesting

### Fallback Strategy
1. **Primary**: GPS/WiFi geolocation
2. **Secondary**: IP-based location (less accurate)
3. **Tertiary**: Manual address input

## UX Flow Design

### For Contractors Posting Jobs
1. **Location Input Section**:
   - "Use my current location" button with GPS icon
   - Manual address input field (existing)
   - Radius selection: 5km, 10km, 25km, 50km (default: 25km)

2. **GPS Button Flow**:
   ```
   Tap "Use current location" → Show permission prompt → 
   Show loading state → Display detected address with edit option → 
   Show accuracy indicator ("Accurate to ~50m")
   ```

3. **Error Handling**:
   - Permission denied: "Location access denied. Please enable in browser settings or enter address manually."
   - GPS unavailable: "Unable to get location. Please check your connection or enter address manually."

### For Workers Finding Jobs
1. **"Find Jobs Near Me" Button**:
   - Prominent button on jobs page
   - One-tap location detection
   - Auto-apply location filter

2. **Location Filter Options**:
   - Current location (with GPS icon)
   - Enter suburb/postcode
   - Radius slider: 5km, 10km, 25km, 50km

## Technical Implementation Plan

### 1. Database Updates
```sql
-- Add separate lat/lng columns for better query performance
ALTER TABLE jobs ADD COLUMN lat DECIMAL(10, 8);
ALTER TABLE jobs ADD COLUMN lng DECIMAL(11, 8);
ALTER TABLE jobs ADD COLUMN location_accuracy INTEGER; -- in meters
ALTER TABLE jobs ADD COLUMN location_source TEXT; -- 'gps', 'wifi', 'ip', 'manual'

ALTER TABLE profiles ADD COLUMN lat DECIMAL(10, 8);
ALTER TABLE profiles ADD COLUMN lng DECIMAL(11, 8);
ALTER TABLE profiles ADD COLUMN location_accuracy INTEGER;
ALTER TABLE profiles ADD COLUMN location_source TEXT;

-- Create indexes for geo-queries
CREATE INDEX idx_jobs_location ON jobs USING GIST (ST_MakePoint(lng, lat));
CREATE INDEX idx_profiles_location ON profiles USING GIST (ST_MakePoint(lng, lat));
```

### 2. Geolocation Service Module
```typescript
// lib/geolocation.ts
interface LocationResult {
  lat: number;
  lng: number;
  accuracy: number;
  source: 'gps' | 'wifi' | 'ip' | 'manual';
  address?: string;
  suburb?: string;
}

class GeolocationService {
  async getCurrentPosition(): Promise<LocationResult> {
    // Implementation with fallback chain
  }
  
  async reverseGeocode(lat: number, lng: number): Promise<{address: string, suburb: string}> {
    // Google Maps API integration
  }
  
  calculateDistance(lat1: number, lng1: number, lat2: number, lng2: number): number {
    // Haversine formula implementation
  }
}
```

### 3. React Hook for Location
```typescript
// hooks/useLocation.ts
export function useLocation() {
  const [location, setLocation] = useState<LocationResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  
  const getLocation = async () => {
    // Handle permission and get location
  };
  
  return { location, loading, error, getLocation };
}
```

### 4. Location-Aware Components
- `<LocationButton />` - GPS detection button with loading states
- `<LocationInput />` - Combined GPS/manual input component
- `<DistanceFilter />` - Radius selection component
- `<NearbyJobs />` - Jobs list sorted by distance

### 5. Search/Matching Implementation
```sql
-- Find jobs within radius (PostgreSQL)
SELECT *, 
  (6371 * acos(cos(radians($1)) * cos(radians(lat)) * 
  cos(radians(lng) - radians($2)) + sin(radians($1)) * 
  sin(radians(lat)))) AS distance
FROM jobs 
WHERE status = 'active'
HAVING distance <= $3
ORDER BY distance;
```

## Privacy Considerations

### Data Protection
- **Don't store exact home addresses** publicly
- **Show approximate location only** (round to nearest 0.1km)
- **Option to hide location** entirely in settings
- **Location data access** limited to authenticated users only

### User Control
- **Clear location history** option
- **Disable location tracking** in settings
- **Manual override** always available
- **Location expires** after session or specified time

### Security
- **Rate limit** location API calls
- **Validate coordinates** before storing
- **Sanitize address data** to prevent injection
- **Audit log** for location access

## Implementation Phases

### Phase 1: Core Geolocation (Week 1)
- [ ] Implement geolocation service module
- [ ] Add GPS button to job posting form
- [ ] Create location detection hook
- [ ] Basic error handling

### Phase 2: Reverse Geocoding (Week 2)
- [ ] Google Maps API integration
- [ ] Address autocomplete
- [ ] Suburb extraction
- [ ] Accuracy indicators

### Phase 3: Database Migration (Week 2)
- [ ] Run migration to add lat/lng columns
- [ ] Migrate existing point data
- [ ] Update TypeScript types
- [ ] Create indexes

### Phase 4: Worker Features (Week 3)
- [ ] "Find jobs near me" button
- [ ] Distance-based filtering
- [ ] Radius selection UI
- [ ] Sort by distance

### Phase 5: Privacy & Optimization (Week 4)
- [ ] Privacy settings
- [ ] Location caching
- [ ] Performance optimization
- [ ] Analytics integration

## API Requirements

### Google Maps API Services Needed
- **Geocoding API**: Convert lat/lng to address
- **Places API**: Address autocomplete
- **Geolocation API**: WiFi/cell tower location (fallback)

### Rate Limiting Considerations
- Cache reverse geocoding results
- Batch location updates
- Client-side throttling
- Debounce user inputs

## Testing Strategy

### Unit Tests
- Geolocation service methods
- Distance calculations
- Permission handling
- Error scenarios

### Integration Tests
- Full location flow
- Database queries
- API rate limiting
- Fallback mechanisms

### User Testing
- Permission prompt clarity
- Location accuracy
- Manual override flow
- Error message helpfulness

## Success Metrics

### Adoption Metrics
- % of jobs posted with GPS location
- % of workers using "near me" feature
- Location permission grant rate
- Manual address entry reduction

### Quality Metrics
- Location accuracy (vs manual entry)
- Search result relevance
- User satisfaction with location features
- Support tickets related to location

## Future Enhancements

### Advanced Features
- **Geofencing**: Notify workers of jobs in area
- **Route optimization**: Suggest optimal job sequences
- **Location analytics**: Heat maps of job density
- **Travel time estimates**: Include commute time in matching

### Platform Extensions
- **iOS/Android apps**: Native GPS integration
- **Offline support**: Cache location data
- **Multi-location**: Support for multiple work sites
- **Location sharing**: Temporary location sharing between users