# 009 — Expo Mobile Application Integration

**Issue:** #16
**Status:** Draft
**Created:** 2026-05-29

## Objective

Integrate an Expo-based React Native mobile application into the `cloud-reader` monorepo, sharing types, API client patterns, and configuration with the existing web frontend.

## Directory Structure

```
cloud-reader/
├── mobile/                    # Expo React Native app
│   ├── package.json
│   ├── app.json
│   ├── tsconfig.json
│   ├── babel.config.js
│   ├── App.tsx               # Root component
│   ├── src/
│   │   ├── api/              # API client (mirrors frontend/src/api/ pattern)
│   │   │   ├── client.ts     # Axios instance + JWT interceptor
│   │   │   ├── books.ts      # Book API calls
│   │   │   └── annotations.ts
│   │   ├── screens/          # Screen-level components
│   │   ├── components/       # Reusable UI components
│   │   ├── navigation/       # React Navigation setup
│   │   ├── context/          # Auth context, etc.
│   │   ├── hooks/            # Custom hooks
│   │   └── types/            # Mobile-specific types
│   └── assets/
├── packages/
│   └── shared/
│       ├── package.json
│       ├── tsconfig.json
│       └── src/
│           ├── types.ts      # Shared domain types (Book, User, Bookmark, Note)
│           └── utils.ts      # Shared utility functions
└── package.json              # Root — updated workspace config
```

## Monorepo Workspace Config

Root `package.json` workspaces array updated to include `"mobile"`, `"packages/shared"` alongside existing `"frontend"` and `"backend"`.

## Shared `packages/shared`

- `@cloud-reader/shared` package published within the monorepo
- Exports:
  - All domain types (`Book`, `BookSummary`, `Bookmark`, `Note`, `User`, `AnnotationEntry`, `PaginatedResponse`, `TokenResponse`)
  - API endpoint constants
  - Date formatting helpers
  - Validation utilities (email regex, password strength check)

## Mobile App Structure

### API Client (`mobile/src/api/client.ts`)
- Axios instance configured with:
  - Base URL from environment variable (`EXPO_PUBLIC_API_URL`)
  - JWT token attachment via request interceptor
  - Token refresh response interceptor on 401
  - Uses `AsyncStorage` for token persistence (instead of `localStorage`)

### Navigation (`mobile/src/navigation/`)
- React Navigation stack:
  1. `AuthStack` — Login, Register screens
  2. `MainTabs` — Library, Search, Settings tabs
  3. `BookReader` — Full-screen reading view

### Key Screens
| Screen | Route | Purpose |
|--------|-------|---------|
| Login | `Auth/Login` | Email/password login |
| Register | `Auth/Register` | User registration |
| Library | `Main/Library` | Book list with filtering |
| BookDetail | `Main/BookDetail` | Book metadata + actions |
| Reader | `Reader/View` | EPUB/PDF rendering |
| Search | `Main/Search` | Book discovery |
| Settings | `Main/Settings` | Profile, theme, download mgmt |

## Backend Changes Required

None. The existing Django REST API already serves all endpoints needed by the mobile app. The mobile app communicates with the same backend via the shared API base URL.

## Docker

No changes to `docker-compose.yml` needed — the mobile app runs on-device or via Expo Go, not inside Docker.

## CI/CD Considerations

The monorepo structure supports a single pipeline that can:
- `yarn install` at root (installs all workspaces)
- `yarn workspace @cloud-reader/shared build`
- `yarn workspace @cloud-reader/mobile build` (Expo EAS for mobile builds)
- `yarn workspace @cloud-reader/frontend build` (Vite for web builds)
