Cuti-E Architecture¶
Cuti-E is a character-driven feedback platform that enables indie app developers to provide personalized support through mascot characters.
System Overview¶
flowchart TB
subgraph apps["Customer Apps"]
ios["iOS App<br/>(CutiE SDK)"]
android["Android App<br/>(CutiE SDK)"]
end
subgraph platform["Cuti-E Platform"]
api["Cloudflare Worker API<br/>(Multi-tenant, Edge-native)"]
db["Cloudflare D1<br/>(SQLite at Edge)"]
pages["Cloudflare Pages<br/>(Website + Admin Dashboard)"]
end
subgraph admin["Admin Interfaces"]
adminios["iOS Admin App"]
adminweb["Web Dashboard"]
end
ios --> api
android --> api
api --> db
adminios --> api
adminweb --> api
Tech Stack¶
| Component | Technology |
|---|---|
| Backend | Cloudflare Workers (JavaScript) |
| Database | Cloudflare D1 (SQLite) |
| iOS SDK | Swift Package Manager |
| iOS Admin | SwiftUI (iOS 16+) |
| Android SDK | Kotlin / Jetpack Compose |
| Web Admin | Static HTML/CSS/JS |
| Website | Static site on Cloudflare Pages |
Architecture Principles¶
- Character-First -- All responses appear as coming from the app's mascot character
- Mobile-Native -- Admin apps are native iOS/Android (not web wrappers)
- Edge-Native -- Cloudflare Workers for global, low-latency responses
- Multi-Tenant -- Single backend serves all customers with data isolation
- Privacy-First -- Minimal data collection, user anonymity by default
- Offline-Capable -- SDK queues feedback when offline, syncs when online
Backend: Handler Pattern¶
The backend uses domain-based organization with one file per handler:
cloudflare-worker/src/
├── index.js # Main router
├── handlers/
│ ├── auth.js # Authentication endpoints
│ ├── conversations.js
│ ├── messages.js
│ ├── team.js
│ └── ...
└── utils/
├── validation.js
├── email.js
└── notifications/
Mobile Architecture (MVVM)¶
Both iOS and Android SDKs use MVVM with a repository pattern:
| Platform | View Layer | State Management | Data Layer |
|---|---|---|---|
| iOS | SwiftUI Views | @ObservableObject / @StateObject |
Services (AuthManager, APIClient) |
| Android | Jetpack Compose | ViewModel + StateFlow |
Repositories (AuthRepository) |
Authentication¶
Cuti-E has two authentication mechanisms:
| Mechanism | Used By | Headers | Purpose |
|---|---|---|---|
| Session Token | Admin Dashboard, iOS Admin App | Authorization: Bearer <token> |
Admin users managing conversations |
| App ID + Device Secret | iOS/Android SDKs | X-App-ID, X-Device-ID, X-Device-Secret |
End users submitting feedback |
SDK Challenge-Response Flow¶
sequenceDiagram
participant SDK as iOS/Android SDK
participant API as Cuti-E API
SDK->>API: POST /v1/auth/device/challenge
Note over SDK,API: Send app_id + device_id
API-->>SDK: challenge_token (valid 30 days)
SDK->>SDK: device_secret = SHA256(device_id + challenge_token)
SDK->>API: Subsequent requests with X-Device-Secret
API->>API: Recompute expected secret, compare
Feedback Data Flow¶
sequenceDiagram
participant User as App User
participant SDK as CutiE SDK
participant API as Cloudflare Worker
participant DB as D1 Database
participant Admin as Admin App
User->>SDK: Submit feedback
SDK->>API: POST /v1/conversations
API->>DB: Store conversation + message
API-->>SDK: conversation_id
API->>Admin: Push notification
Admin->>API: POST /v1/conversations/:id/messages
API->>DB: Store admin reply
API->>SDK: Push notification to user
SDK-->>User: Show mascot response
Multi-Tenancy¶
Every database query includes customer_id in the WHERE clause for data isolation. Each customer can customize:
- Mascot name and avatar
- Branding colors for SDK UI
- Welcome message in feedback form
Live URLs¶
| Service | URL |
|---|---|
| Website | cuti-e.com |
| Production API | https://api.cuti-e.com |
| Sandbox API | https://cutie-worker-sandbox.invotekas.workers.dev |
| Admin Dashboard | https://app.cuti-e.com |
| SDK Docs | cuti-e.com/docs/ |