Technical
Muse Otter — Technical Documentation
Muse Otter Team • February 9, 2026
Muse Otter — Technical Documentation
RevenueCat Shipyard Creator Contest 2026
Tech Stack
Every piece chosen for one reason: ship fast, scale later, don’t compromise.
| Layer | Technology | Why |
|---|---|---|
| Frontend | Flutter 3.24+ | One codebase → iOS, Android, Web, macOS |
| State | Riverpod 2.6+ | Type-safe, testable, code-generated |
| Backend | Cloud Functions v2 | Auto-scaling, pay-per-use |
| Database | Cloud Firestore | Real-time listeners, offline support |
| Auth | Firebase Auth | Anonymous → account linking |
| AI | Genkit 1.27+ | Google’s AI orchestration framework |
| Model | Gemini 2.0 Flash | Fast, affordable, good for coaching |
| Payments | RevenueCat 9.10+ | Cross-platform subs in hours |
| Voice | Vapi SDK | Real-time voice calls |
Architecture
┌─────────────────────────────────────────────────────┐
│ FLUTTER APP │
│ (Clean Architecture) │
│ │
│ Presentation → Domain → Data │
│ (UI/Riverpod) (Entities) (Firebase) │
└────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ FIREBASE BACKEND │
│ │
│ Auth │ Firestore │ Cloud Functions v2 │
│ │ │ • AI chat responses │
│ │ │ • Context extraction │
│ │ │ • Webhooks │
└────────────────────────┬────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│RevenueCat│ │ Genkit │ │ Vapi │
│ Subs │ │ +Gemini │ │ Voice │
└──────────┘ └──────────┘ └──────────┘
Clean Architecture — Feature-First
Every feature follows the same structure:
lib/features/{feature}/
├── data/ ← Firebase integration
├── domain/ ← Business logic (entities, use cases)
└── presentation/ ← UI (screens, widgets, providers)
Rules: Entities are immutable (freezed). Use Cases return Either<Exception, T>. Repositories are abstract in domain/, implemented in data/.
AI Pipeline
How every AI interaction works:
- User sends message → Write to Firestore with
status: pending - Cloud Function triggers (
onChatMessageCreate) - Function loads: coach system prompt + user context + last 20 messages
- Genkit calls Gemini 2.0 Flash
- Response written to Firestore → App updates via real-time listener
Context injection makes the same model feel like a different coach for each user:
System prompt structure:
├── Coach personality & methodology
├── User personal context (project, values, goals)
├── Recent Foundation entries
└── Language directive (en/fr)
RevenueCat Implementation
Products
| Product ID | Price | Period |
|---|---|---|
monthly_10 | $9.99 | Monthly |
yearly_80 | $79.99 | Yearly (save 33%) |
Entitlement: Muse Otter Pro
Architecture
┌─────────────┐ Purchase ┌─────────────┐
│ Flutter App │──────────────►│ RevenueCat │
│ │ │ │
│ purchases_ │ Entitle- │ (App Store/ │
│ flutter SDK │◄──────────────│ Play Store) │
└──────┬──────┘ ments └──────┬──────┘
│ │
│ Read status │ Webhook events
│ (stream) │ (server-to-server)
▼ ▼
┌─────────────────────────────────────────────┐
│ FIRESTORE │
│ │
│ users/{userId} │
│ ├── subscriptionStatus: free|pro|lifetime │
│ └── subscriptionUpdatedAt: timestamp │
│ │
│ ══ Single source of truth ══ │
└─────────────────────────────────────────────┘
Webhook Events
| RevenueCat Event | Action | New Status |
|---|---|---|
| INITIAL_PURCHASE | Grant Pro | pro |
| RENEWAL | Keep Pro | pro |
| EXPIRATION | Revoke Pro | free |
| CANCELLATION | No change | — (keeps Pro until expiry) |
Protected statuses: donation and lifetime are never modified by webhooks — manual grants for testers and supporters.
Summary
- Stack: Flutter + Firebase + Genkit/Gemini — one codebase, multi-platform
- Architecture: Clean Architecture with Riverpod, feature-first organization
- AI: Document-status pattern with context injection for personalized coaching
- RevenueCat: Server webhooks sync to Firestore as single source of truth
Built solo in 3 weeks. Designed to scale.