The diagram below shows every API call the app makes during setup and what the server stores at each step. The bootstrap token is only used once (step 1); all subsequent calls use the permanent auth token returned in the response.
sequenceDiagram
participant User
participant App as DailyRoundup App
participant Server as roundup-server
participant Trello
participant KC as iCloud Keychain
Note over User,KC: Step 1 — Create account
User->>App: Tap Connect (server URL,<br/>bootstrap token, API key,<br/>webhook secret)
App->>Server: POST /dailyroundup/account<br/>Authorization: Bearer <bootstrap_token>
Note right of Server: Verify bootstrap token (constant-time compare)<br/>Generate permanent auth token<br/>Hash token with SHA-256<br/>INSERT INTO accounts<br/>(auth_token_hash, NULLs for Trello fields)
Server-->>App: 201 { account_id, auth_token }
Note over User,KC: Step 2 — Verify token
App->>Server: GET /dailyroundup/changes<br/>Authorization: Bearer <auth_token>
Note right of Server: Hash token → look up account<br/>Return empty changes list
Server-->>App: 200 { changes: [], has_more: false }
Note over User,KC: Step 3 — Save Trello credentials
App->>Server: PUT /dailyroundup/account<br/>{ trello_api_key, trello_webhook_secret }
Note right of Server: UPDATE accounts<br/>SET trello_api_key, trello_webhook_secret
Server-->>App: 200 { masked credentials }
App->>KC: Save auth_token to iCloud Keychain
Note over User,KC: Step 4 — Trello OAuth
App->>Trello: Open https://trello.com/1/authorize<br/>key, name=DailyRoundup,<br/>scope=read,write, expiration=never
User->>Trello: Approve access
Trello-->>App: Redirect dailyroundup://trello-oauth<br/>#token=<trello_token>
App->>Server: PUT /dailyroundup/account<br/>{ trello_token }
Note right of Server: UPDATE accounts<br/>SET trello_token
Server-->>App: 200 { masked credentials }
Note over User,KC: Step 5 — Create synced list
User->>App: Tap Create Synced List…<br/>select board + list
App->>Server: POST /dailyroundup/lists<br/>{ name, trello_board_id, trello_list_id }
Note right of Server: INSERT INTO sync_lists<br/>Register Trello webhook<br/>for list and board
Server->>Trello: POST /webhooks (list + board)
Trello-->>Server: webhook IDs
Server-->>App: 201 { sync_list_id, name,<br/>trello_list_id, trello_board_id }
| Step | API Call | What the server stores |
|---|---|---|
| 1. Create account | POST /dailyroundup/account |
New row in accounts with SHA-256 hashed auth token; Trello fields are NULL |
| 2. Verify token | GET /dailyroundup/changes |
Nothing — read-only check that the token is valid |
| 3. Save credentials | PUT /dailyroundup/account |
Updates trello_api_key and trello_webhook_secret on the account row |
| 4. Trello OAuth | PUT /dailyroundup/account |
Updates trello_token on the account row |
| 5. Create synced list | POST /dailyroundup/lists |
New row in sync_lists linking a Trello list to the account; registers Trello webhooks |
The permanent auth token is returned in plaintext exactly once (step 1) and never stored on the server — only its SHA-256 hash is persisted. Trello credentials are stored in plaintext on the server (needed for API calls) but are masked in all API responses.