RevenueCat Shipyard 2026 Submission
Developer: Ramkumar Gudivada
Creator Brief: Simon @BetterCreating
Submission Date: February 10, 2026
"Simon's audience loves productivity, great design, and building systems β and he wants to bring coaching to more people. Create a clean, minimal mobile app where users can browse, create, and share AI coaches, add personal context/values, and start chatting immediately. No complex setup, just guidance at the right moment."
App Structure:
app/
βββ (tabs)/ # Main tab navigation
β βββ index.tsx # Home/Coach Selection
β βββ chat.tsx # Chat Interface
β βββ settings.tsx # Settings & Account
βββ _layout.tsx # Root layout with providers
βββ onboarding.tsx # First-time user flow
βββ paywall.tsx # Subscription screen
components/
βββ CoachCard.tsx # Coach selection cards
βββ ChatBubble.tsx # Message display
βββ PremiumBanner.tsx # Upgrade prompts
βββ LoadingSpinner.tsx # Loading states
contexts/
βββ ChatContext.tsx # Chat state management
βββ PremiumContext.tsx # Subscription state
βββ CoachContext.tsx # Active coach tracking
utils/
βββ ai-service.ts # OpenAI integration
βββ revenuecat.ts # RevenueCat SDK wrapper
βββ storage.ts # AsyncStorage helpers
API Key: appl_ooxzpzwxHOQNkUCjODAkqnLDbjJ
Entitlement ID: premium
Bundle ID: com.ramkumar.gudivada.nirvanaicoachv2
| Property | Value |
|---|---|
| Product ID | monthly_premium |
| Type | Auto-Renewable Subscription |
| Duration | 1 Month |
| Price | $9.99 USD |
| Subscription Group | Premium Subscriptions |
| Status | Ready to Submit |
Offering ID: default (Current)
Packages:
- $rc_monthly β monthly_premium
- $rc_annual β yearly_premium (future)
- $rc_lifetime β lifetime_premium (future)
// utils/revenuecat.ts
import Purchases from 'react-native-purchases';
const API_KEYS = {
ios: 'appl_ooxzpzwxHOQNkUCjODAkqnLDbjJ',
android: 'goog_YOUR_KEY_HERE',
};
export class RevenueCatService {
static async init() {
// Safety check for Expo Go
if (Constants.executionEnvironment === 'storeClient') {
console.log('[RevenueCat] Running in Expo Go - Mock Mode');
this.mockPro = true;
return;
}
try {
if (Platform.OS === 'ios') {
await Purchases.configure({ apiKey: API_KEYS.ios });
}
if (__DEV__) {
await Purchases.setLogLevel(Purchases.LOG_LEVEL.DEBUG);
}
console.log('RevenueCat Initialized');
} catch (e) {
console.warn('RevenueCat Init Failed:', e);
}
}
}
static async purchasePackage(pkg: PurchasesPackage) {
try {
const { customerInfo } = await Purchases.purchasePackage(pkg);
return { success: true, customerInfo };
} catch (e: any) {
if (!e.userCancelled) {
console.error('Purchase error', e);
return { success: false, error: e.message };
} else {
return { success: false, userCancelled: true };
}
}
}
static async isPro(): Promise<boolean> {
if (this.mockPro) return true; // Mock for testing
try {
const customerInfo = await this.getCustomerInfo();
return customerInfo?.entitlements.active['premium'] !== undefined;
} catch (e) {
console.error("Failed to check pro status", e);
return false;
}
}
Model: GPT-4
API Version: v1
Max Tokens: 500 per response
Temperature: 0.7 (balanced creativity)
// utils/ai-service.ts
import OpenAI from 'openai';
const OPENAI_API_KEY = process.env.EXPO_PUBLIC_OPENAI_API_KEY || '';
const openai = new OpenAI({
apiKey: OPENAI_API_KEY,
});
export async function sendMessage(
coachType: string,
messages: Message[]
): Promise<string> {
try {
const systemPrompt = getCoachSystemPrompt(coachType);
const completion = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{ role: 'system', content: systemPrompt },
...messages.map(m => ({
role: m.role,
content: m.content
}))
],
max_tokens: 500,
temperature: 0.7,
});
return completion.choices[0].message.content || 'No response';
} catch (error) {
console.error('OpenAI API Error:', error);
throw error;
}
}
Each coach has a specialized system prompt:
| Coach | Specialization |
|---|---|
| Fitness Coach | Certified personal trainer and nutritionist providing evidence-based fitness advice, workout plans, and nutrition guidance |
| Career Coach | Experienced career counselor specializing in tech careers, resume writing, interview prep, and salary negotiation |
| Mindfulness Coach | Meditation instructor and stress management expert guiding mindfulness practices and mental wellness |
| Relationship Coach | Licensed relationship therapist providing advice on communication, conflict resolution, and healthy relationships |
| Finance Coach | Certified financial planner helping with budgeting, saving, investing, and financial goal setting |
| Productivity Coach | Productivity expert specializing in time management, workflow optimization, and habit building |
EXPO_PUBLIC_OPENAI_API_KEYappl_ooxzpzwxHOQNkUCjODAkqnLDbjJTrigger: Manual workflow dispatch
Runner: macOS-latest
Build Time: ~24 minutes
name: Build iOS App
on:
workflow_dispatch:
jobs:
build:
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: npm
- name: Setup EAS
uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: Install dependencies
run: npm install
- name: Build iOS App
run: eas build --platform ios --profile production
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
EXPO_PUBLIC_OPENAI_API_KEY: ${{ secrets.EXPO_PUBLIC_OPENAI_API_KEY }}
- name: Submit to TestFlight
run: eas submit --platform ios --profile production
env:
EXPO_APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.EXPO_APPLE_APP_SPECIFIC_PASSWORD }}
| Metric | Target |
|---|---|
| App launch time | < 2 seconds |
| Chat response time | < 3 seconds |
| Purchase flow | < 5 seconds |
| Memory usage | < 150 MB |