> ## Documentation Index
> Fetch the complete documentation index at: https://docs.joinfindu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Student API Vision

> Future API design for mobile app optimization

# Student App API Vision

This document outlines potential API designs for optimizing the FindU iOS app experience. Currently, the app communicates directly with Supabase.

<Note>
  This is a design reference document. These endpoints do not currently exist. The iOS app uses Supabase Swift SDK for all operations.
</Note>

## Current Implementation

The iOS app currently:

* Uses Supabase Swift SDK
* Handles authentication via Supabase Auth
* Queries database directly
* Manages real-time subscriptions

```swift theme={null}
// Current approach
let schools = try await supabase
    .from("schools")
    .select("*")
    .order("match_score", ascending: false)
    .limit(20)
    .execute()
```

## Future API Benefits

A dedicated Student API could provide:

### 1. Mobile Optimization

Reduced payload sizes and batched data:

```swift theme={null}
// Future API approach
let recommendations = try await api.getRecommendations(
    compressed: true,
    includeImages: .thumbnail
)
```

### 2. Offline Support

Cache-friendly endpoints with sync capabilities:

```swift theme={null}
// Sync local changes when online
let syncResult = try await api.syncOfflineActions(
    swipes: localSwipes,
    messages: localDrafts
)
```

### 3. Simplified Data Access

Pre-computed and enriched responses:

```swift theme={null}
// Get everything needed for home screen in one call
let homeData = try await api.getHomeScreen()
// Returns: recommendations, unread messages, new matches, etc.
```

## Proposed Endpoint Structure

### Authentication & Profile

```
POST /student/auth/apple
POST /student/auth/google
POST /student/auth/refresh
GET  /student/profile
POST /student/profile
PATCH /student/profile
POST /student/profile/avatar
```

### Discovery & Matching

```
GET  /student/recommendations
POST /student/swipe
GET  /student/schools/:id
POST /student/schools/:id/save
GET  /student/matches
GET  /student/match/:schoolId/details
```

### Messaging

```
GET  /student/conversations
GET  /student/conversations/:id
POST /student/messages
PATCH /student/messages/:id/read
GET  /student/notifications
```

### Social Features

```
GET  /student/friends
POST /student/friends/add
POST /student/friends/share-profile
GET  /student/friends/:id/schools
POST /student/compare-schools
```

### Scholarships

```
GET  /student/scholarships
GET  /student/scholarships/saved
POST /student/scholarships/:id/save
GET  /student/scholarships/:id
```

## Mobile-First Design Patterns

### Compressed Responses

```typescript theme={null}
// Full response
interface School {
  id: string;
  name: string;
  location: { city: string; state: string; };
  stats: { /* 20+ fields */ };
  images: string[];
}

// Compressed for lists
interface SchoolCompressed {
  i: string;    // id
  n: string;    // name
  l: string;    // location "City, ST"
  m: number;    // matchScore
  img: string;  // thumbnail
}
```

### Progressive Data Loading

```typescript theme={null}
// Initial load - minimal data
GET /student/recommendations?fields=minimal

// User shows interest - load details
GET /student/schools/:id?fields=full

// Background sync - preload next batch
GET /student/recommendations/preload
```

### Optimistic Updates

```typescript theme={null}
// Immediate response with pending status
POST /student/swipe
Response: { status: 'pending', tempId: 'tmp_123' }

// Confirm via websocket or polling
WS: { event: 'swipe.confirmed', tempId: 'tmp_123', id: 'swipe_456' }
```

## Performance Optimizations

### Caching Strategy

```typescript theme={null}
// Cache headers for different resources
interface CachePolicy {
  schools: 'max-age=3600',           // 1 hour
  profile: 'max-age=300',            // 5 minutes  
  recommendations: 'private, max-age=1800', // 30 minutes
  messages: 'no-cache'               // Always fresh
}
```

### Batch Operations

```typescript theme={null}
// Batch multiple operations
POST /student/batch
{
  operations: [
    { method: 'POST', path: '/swipe', body: {...} },
    { method: 'GET', path: '/recommendations' },
    { method: 'PATCH', path: '/messages/123/read' }
  ]
}
```

### Delta Sync

```typescript theme={null}
// Only get changes since last sync
GET /student/sync?since=2024-01-15T10:00:00Z
Response: {
  newMessages: [...],
  updatedSchools: [...],
  deletedItems: [...]
}
```

## Push Notification Integration

```typescript theme={null}
// Register for notifications
POST /student/devices
{
  token: "APNS_TOKEN",
  platform: "ios",
  preferences: {
    messages: true,
    matches: true,
    reminders: true
  }
}

// Notification payload
{
  aps: {
    alert: "MIT liked you back! 🎉",
    badge: 1,
    sound: "match.caf"
  },
  findu: {
    type: "match",
    schoolId: "mit_123",
    deepLink: "findu://school/mit_123"
  }
}
```

## Implementation Considerations

### iOS SDK Design

```swift theme={null}
// Clean SDK interface
class FindUAPI {
    func getRecommendations() async throws -> [School]
    func recordSwipe(_ direction: SwipeDirection, for school: School) async throws
    func sendMessage(_ text: String, to conversation: Conversation) async throws
}

// With offline support
class FindUOfflineAPI: FindUAPI {
    private let cache: CacheManager
    private let queue: OfflineQueue
    
    override func recordSwipe(...) async throws {
        try queue.enqueue(.swipe(direction, school))
        try await syncIfOnline()
    }
}
```

### Error Handling

```swift theme={null}
enum FindUError: LocalizedError {
    case offline
    case invalidProfile(missing: [String])
    case rateLimited(retryAfter: TimeInterval)
    case schoolNotFound
    
    var errorDescription: String? {
        switch self {
        case .offline:
            return "You're offline. Changes will sync when connected."
        case .invalidProfile(let fields):
            return "Complete your profile: \(fields.joined(separator: ", "))"
        case .rateLimited(let retry):
            return "Too many requests. Try again in \(Int(retry)) seconds."
        case .schoolNotFound:
            return "This school is no longer available."
        }
    }
}
```

## Migration Strategy

If implementing this API:

1. **Phase 1**: Read-only endpoints
   * Recommendations
   * School details
   * Profile data

2. **Phase 2**: Core interactions
   * Swipe recording
   * Message sending
   * Profile updates

3. **Phase 3**: Advanced features
   * Offline sync
   * Batch operations
   * Push notifications

## Current Alternative

For now, the iOS app can optimize using:

* Supabase SDK with selective queries
* Local caching with UserDefaults/CoreData
* Background refresh tasks
* Supabase real-time for instant updates

See [iOS App Architecture](/ios-app/overview) for current implementation details.
