payfrit-food-ios/CLAUDE.md
John Pinkyfloyd 71e7ec34f6 Initial commit: PayfritFood iOS app
- SwiftUI + async/await architecture
- Barcode scanning with AVFoundation
- Product display with score ring, NOVA badge, nutrition
- Alternatives with sort/filter
- Auth (login/register)
- Favorites & history
- Account management
- Dark theme
- Connected to food.payfrit.com API (Open Food Facts proxy)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-16 16:58:21 -07:00

129 lines
4.4 KiB
Markdown

# PayfritFood - iOS App
Native Swift/SwiftUI iOS app for scanning food products, viewing health scores, and finding healthier alternatives.
**Bundle ID**: `com.payfrit.food`
**Display Name**: Payfrit Food
**API Base**: `https://food.payfrit.com/api`
## Build & Deploy
```bash
# Build for device
cd ~/payfrit-food-ios && xcodebuild -project PayfritFood.xcodeproj -scheme PayfritFood -destination 'id=00008030-000244863413C02E' -allowProvisioningUpdates build
# Install to phone
xcrun devicectl device install app --device 00008030-000244863413C02E ~/Library/Developer/Xcode/DerivedData/PayfritFood-*/Build/Products/Debug-iphoneos/PayfritFood.app
# Launch app
xcrun devicectl device process launch --device 00008030-000244863413C02E com.payfrit.food
```
## Project Structure
```
PayfritFood/
├── PayfritFoodApp.swift # App entry point
├── Info.plist # App config, permissions
├── Assets.xcassets/ # App icons, colors
├── Models/
│ ├── Product.swift # Product with score, NOVA, nutrition
│ ├── Alternative.swift # Alternative product with links
│ ├── UserProfile.swift # User profile
│ └── ScanHistory.swift # Scan history item
├── ViewModels/
│ └── AppState.swift # Central state (@MainActor ObservableObject)
├── Services/
│ ├── APIService.swift # Actor-based API client
│ ├── AuthStorage.swift # Keychain token storage
│ ├── BarcodeScanner.swift # AVFoundation barcode scanning
│ └── LocationService.swift # CoreLocation for distance
└── Views/
├── RootView.swift # Tab navigation
├── ScanTab/
│ ├── ScanScreen.swift # Camera + manual entry
│ └── ManualEntrySheet.swift
├── ProductTab/
│ ├── ProductScreen.swift # Product detail
│ ├── ScoreRing.swift # Animated score circle
│ ├── NOVABadge.swift # NOVA 1-4 badge
│ ├── DietaryPills.swift # Dietary tags
│ ├── NutritionSection.swift
│ └── IngredientsSection.swift
├── AlternativesTab/
│ ├── AlternativesScreen.swift
│ ├── FilterChips.swift
│ ├── AlternativeCard.swift
│ └── SponsoredCard.swift
├── FavoritesTab/
│ └── FavoritesScreen.swift
├── HistoryTab/
│ └── HistoryScreen.swift
├── AccountTab/
│ ├── AccountScreen.swift
│ ├── LoginSheet.swift
│ └── RegisterSheet.swift
└── Components/
└── ProductCard.swift
```
## Architecture
### State Management
- **AppState** (`@MainActor ObservableObject`): Single source of truth
- Authentication: userId, userToken, userProfile, isPremium
- Current product and alternatives
- Navigation state (selectedTab, showLoginSheet, etc.)
### API Service
- **APIService** (Swift actor): Thread-safe singleton
- Base URL: `https://food.payfrit.com/api`
- Auth via `Authorization: Bearer {token}` header
### Key Endpoints
- `POST /auth/login` - Login with email/password
- `POST /auth/register` - Register new user
- `POST /product/lookup` - Lookup product by barcode
- `GET /product/{id}/alternatives` - Get healthier alternatives
- `GET /favorites` - Get user favorites
- `GET /history` - Get scan history
## Features
### Barcode Scanning
- AVFoundation with AVCaptureMetadataOutput
- Supported formats: EAN-8, EAN-13, UPC-A, UPC-E, Code-128
- Manual entry fallback
### Product Display
- Animated score ring (0-100)
- NOVA badge (1-4 processing level)
- Dietary pills (vegan, gluten-free, etc.)
- Expandable nutrition facts
- Expandable ingredients list
### Alternatives
- Sort by: Rating, Price, Distance, Processing Level
- Filter chips: Dietary (vegan, GF, etc.), Availability (delivery, pickup)
- Sponsored cards with action links (premium users see no sponsored content)
### User Features
- Favorites (requires auth)
- Scan history (requires auth)
- Account: export data, logout, delete account
- Premium: removes sponsored content
## Permissions
- **Camera**: Barcode scanning
- **Location**: Find nearby stores
## Dependencies
- None (uses only system frameworks)
## iOS Version
- Minimum: iOS 16.0
- SwiftUI + async/await + URLSession