Publicar nas Lojas
← Voltar

Publicar nas Lojas

Guia passo a passo para publicar o BBrain na App Store (iOS) e Google Play (Android).

🍎
App Store
iOS β€” iPhone e iPad
$99/ano
1
Apple Developer Program
Cadastre-se no programa de desenvolvedor da Apple. Custa $99/ano e Γ© obrigatΓ³rio para publicar qualquer app.
developer.apple.com/programs β†’
2
Criar App ID no Apple Developer Portal
No portal, crie um novo App ID com bundle identifier ΓΊnico (ex: io.aproove.bbrain). Ative as capabilities necessΓ‘rias (Push Notifications, etc.).
3
Criar app no App Store Connect
Acesse App Store Connect, clique em "+" e crie um novo app usando o App ID criado. Escolha a plataforma e o idioma primΓ‘rio.
4
Preparar os assets visuais
VocΓͺ precisarΓ‘ de:
Ícone do app
1024Γ—1024px, PNG sem transparΓͺncia
Screenshots iPhone 6.7"
1290Γ—2796px (obrigatΓ³rio)
Screenshots iPhone 6.1"
1179Γ—2556px
Screenshots iPad
2048Γ—2732px (se suportar iPad)
5
Preencher metadados
No App Store Connect, preencha: nome do app (30 chars), subtΓ­tulo (30 chars), descriΓ§Γ£o (4000 chars), palavras-chave (100 chars), URL de suporte e URL de privacidade. Escolha a categoria primΓ‘ria.
6
Build e upload
Compile o app via React Native ou Flutter para iOS. Archive via Xcode e faΓ§a upload pelo Xcode Organizer ou pelo app Transporter (gratuito na Mac App Store).
7
Submeter para review
Selecione o build no App Store Connect e clique em "Submit for Review". O processo leva de 1 a 3 dias ΓΊteis na primeira submissΓ£o.
8
PrecificaΓ§Γ£o
BBrain pode ser publicado como Free com In-App Purchase (para o plano Pro), ou como Paid App. Recomendado: Free + IAP via RevenueCat ou Stripe.
πŸ€–
Google Play
Android
$25 taxa ΓΊnica
1
Google Play Console
Crie uma conta no Google Play Console. A taxa de registro Γ© ΓΊnica ($25) β€” sem anuidade.
play.google.com/console β†’
2
Criar aplicativo
No Console, clique em "Criar app", escolha o idioma padrΓ£o e o tipo (app ou jogo). Defina se Γ© gratuito ou pago (nΓ£o pode mudar depois de gratuito para pago).
3
Ficha do app
Preencha: tΓ­tulo (50 chars), descriΓ§Γ£o curta (80 chars), descriΓ§Γ£o completa (4000 chars). FaΓ§a upload de screenshots (mΓ­nimo 2), feature graphic (1024Γ—500px) e Γ­cone (512Γ—512px).
4
PolΓ­tica de privacidade
ObrigatΓ³ria para todos os apps. Deve estar hospedada em uma URL pΓΊblica. Use um gerador gratuito se necessΓ‘rio.
privacypolicygenerator.info β†’
5
Build assinado
Compile o APK ou AAB (Android App Bundle β€” recomendado). Assine com sua keystore. Para Flutter: flutter build appbundle --release. Para React Native: siga o guia oficial.
6
LanΓ§amento em estΓ‘gios
Recomendado: comece com Teste Interno (qualquer pessoa com link) β†’ Alpha (atΓ© 50 usuΓ‘rios) β†’ Beta (grupo maior) β†’ ProduΓ§Γ£o (lanΓ§amento pΓΊblico).
7
Review
O primeiro review leva de 1 a 7 dias. Updates subsequentes sΓ£o mais rΓ‘pidos (geralmente horas). A Play Store Γ© mais permissiva que a App Store.
πŸ€–
Gerar metadados com IA
Use o Gemini (Google AI Studio) para gerar todos os textos das lojas em segundos
Sua API Key nΓ£o Γ© armazenada nem enviada a nenhum servidor alΓ©m do Google. A chave fica apenas no seu navegador durante esta sessΓ£o. Obtenha uma chave gratuita em aistudio.google.com/apikey.
🎨
Ícone do App β€” 1024Γ—1024px
PNG sem transparΓͺncia, fundo sΓ³lido obrigatΓ³rio

Preview 120px

Requisitos da Apple:

  • 1024Γ—1024 px, PNG, sem canal alpha (sem transparΓͺncia)
  • Sem cantos arredondados β€” a Apple aplica automaticamente
  • ResoluΓ§Γ£o @1x (nΓ£o escalar para 2x/3x neste arquivo)
  • Fundo sΓ³lido β€” gradiente de #1a0a3a para #3a1f7a

Para converter o SVG em PNG 1024Γ—1024: abra no Figma, exporte como PNG 1x Β· ou use magick icon.svg -resize 1024x1024 icon.png

πŸ“±
Screenshots obrigatΓ³rios
DimensΓ΅es exatas para aprovaΓ§Γ£o na App Store
Dispositivo DimensΓ£o Qtde mΓ­n. Status
iPhone 6.7" (15 Pro Max) 1290 Γ— 2796 px 4 telas ObrigatΓ³rio
iPhone 6.1" (15) 1179 Γ— 2556 px 2 telas ObrigatΓ³rio
iPad Pro 12.9" (6Βͺ gen) 2048 Γ— 2732 px 2 telas Recomendado

πŸ“‹ Telas sugeridas (iPhone 6.7" β€” 4 obrigatΓ³rias)

  1. Tela 1 β€” Hero: fundo escuro, tagline "Em que vocΓͺ estΓ‘ pensando?" + input centralizado
  2. Tela 2 β€” Ideias: lista de ideias capturadas com status e badges coloridos
  3. Tela 3 β€” SessΓ£o ativa: banner de sessΓ£o + timer + diΓ‘rio em andamento
  4. Tela 4 β€” Roadmap: ideias organizadas por fase com avaliaΓ§Γ£o IA

Ferramentas gratuitas para criar screenshots: Figma (Community β†’ "App Screenshot") ou Rotato (rotato.app, free tier). Para iPad, use frame de mockup da Apple Design Resources.

πŸ“
Metadados β€” App Store Connect
Copie e cole direto no App Store Connect

NOME DO APP Β· 30 chars

BBrain β€” Capture suas ideias

28 caracteres βœ“

SUBTÍTULO · 30 chars

O segundo cΓ©rebro de quem pensa

31 caracteres β€” ajustar para: "Segundo cΓ©rebro para criadores" (30)

PALAVRAS-CHAVE Β· 100 chars

ideias,segundo cΓ©rebro,notas,produtividade,fundador,startup,journaling,captura,IA

82 caracteres βœ“

CATEGORIA PRIMÁRIA

Produtividade

Categoria secundΓ‘ria sugerida: NegΓ³cios

URLS

Suporte: https://bbrainapp.you/guia
Privacidade: https://bbrainapp.you/privacidade
Marketing: https://bbrainapp.you

DESCRIÇÃO Β· atΓ© 4000 chars

Calculando...

πŸ’°
Modelo de PrecificaΓ§Γ£o
RecomendaΓ§Γ£o para App Store e Google Play

βœ“ Recomendado: Free App + In-App Purchase (IAP)

App gratuito para download. Planos Pro desbloqueados via compra dentro do app (IAP). Maior conversΓ£o de downloads β€” usuΓ‘rio experimenta antes de pagar.

Via RevenueCat (recomendado)

  • GrΓ‘tis atΓ© $2.5k MRR
  • SDK iOS + Android
  • Dashboard de assinaturas
  • revenuecat.com

StoreKit direto (sem custo)

  • Sem taxa extra
  • Mais trabalhoso
  • SΓ³ iOS nativo
  • DocumentaΓ§Γ£o Apple

Nota: A Apple retΓ©m 30% das receitas (15% para apps com menos de $1M/ano no Small Business Program). O Google Play retΓ©m 15% nos primeiros $1M/ano. Os preΓ§os listados nos planos jΓ‘ consideram essa margem.

πŸ€–
Google Play β€” Ficha do App
Metadados obrigatΓ³rios para o Google Play Console

TÍTULO · 50 chars

BBrain β€” Capture e organize suas ideias

39 caracteres βœ“

DESCRIÇÃO CURTA Β· 80 chars

O segundo cΓ©rebro de quem nΓ£o para de pensar. Ideias, sessΓ΅es e roadmap.

72 caracteres βœ“

DESCRIÇÃO COMPLETA Β· atΓ© 4000 chars

ASSETS GRÁFICOS

  • Ícone: 512Γ—512 px, PNG 32-bit β€” use o SVG acima, exporte em 512px
  • Feature Graphic: 1024Γ—500 px, PNG ou JPG (obrigatΓ³rio para destaque)
  • Screenshots: mΓ­nimo 2, recomendado 8 β€” dimensΓ΅es livres dentro dos limites do Play
  • Video (opcional): YouTube URL, atΓ© 2 min, trailer do app

Feature Graphic β€” especificaΓ§Γ£o

BBrain O segundo cΓ©rebro de quem pensa muito
βš™οΈ
Build Assinado β€” APK / AAB
Android App Bundle (recomendado) ou APK para sideload
1

Criar Keystore (uma vez)

keytool -genkey -v -keystore bbrain.keystore \ -alias bbrain -keyalg RSA -keysize 2048 \ -validity 10000

⚠️ Guarde o arquivo bbrain.keystore e a senha em local seguro β€” sem ele nΓ£o Γ© possΓ­vel publicar atualizaΓ§Γ΅es.

2

Build com Flutter (recomendado)

flutter build appbundle --release \ --build-name=1.0.0 --build-number=1

SaΓ­da: build/app/outputs/bundle/release/app-release.aab

3

Build com React Native

cd android ./gradlew bundleRelease

Configure android/app/build.gradle com as chaves da keystore via variΓ‘veis de ambiente.

4

Upload no Google Play Console

  • Acesse play.google.com/console β†’ Criar app
  • Conta de dev Google Play: taxa ΓΊnica de $25 USD
  • Upload o .aab em ProduΓ§Γ£o β†’ VersΓ΅es β†’ Criar release
  • Preencha a ficha, adicione screenshots e feature graphic
πŸ€–
Gerar App com IA
Prompt tΓ©cnico completo para Google AI Studio Β· React Native + Expo

Cole este prompt em aistudio.google.com/apps para gerar o projeto completo React Native/Expo do BBrain. O prompt cobre backend, frontend, design system, autenticaΓ§Γ£o, Stripe e todas as telas.

You are an expert React Native developer. Build a complete, production-ready mobile app called **BBrain** for iOS and Android using Expo SDK 51+ and TypeScript.

═══════════════════════════════════════════
OVERVIEW
═══════════════════════════════════════════
BBrain is a private founder's journal and idea capture tool.
Single user, premium, offline-capable.
Backend: REST API at https://bbrainapp.you (Node.js, no framework)
Auth: Bearer token, daily expiry (client-side), SHA-256 passwords

═══════════════════════════════════════════
TECH STACK
═══════════════════════════════════════════
- React Native 0.74+ with Expo SDK 51
- TypeScript (strict)
- React Navigation v6 (Bottom Tabs + Stack)
- Expo SecureStore (token storage)
- Expo Notifications (push reminders)
- @stripe/stripe-react-native (payments)
- React Query (TanStack) for data fetching
- NativeWind v4 (Tailwind CSS for RN) OR StyleSheet
- Expo Router (file-based routing)
- expo-web-browser (for Stripe Checkout)
- dayjs (dates)

═══════════════════════════════════════════
DESIGN SYSTEM
═══════════════════════════════════════════
Colors:
  brain:      #1A0A3A  (primary dark purple β€” auth screens, CTAs)
  brain-mid:  #3A1F7A  (secondary purple β€” accents)
  paper:      #F7F5EF  (warm off-white β€” app background)
  surface:    #FFFFFF  (cards)
  paper2:     #EFEDE6  (muted areas)
  ink:        #111110  (primary text)
  ink2:       #4A4A47  (secondary text)
  ink3:       #9A9A96  (muted text)
  green:      #2A5F2A on #EDF5ED  (roadmap status)
  amber:      #7A4A0A on #FDF2E2  (in-analysis status)
  blue:       #0D4A8A on #E8F0FB  (new idea status)
  red:        #8A1A1A on #FBEAEA  (delete/error)
  purple:     #4A1D7A on #F3EEFB  (evaluation)
  whatsapp:   #25D366 on #E8FDF2

Typography:
  Font: DM Sans (Google Fonts via expo-font)
  Mono: DM Mono (idea IDs, timers, counters)
  Sizes: xs=10, sm=11, base=13, md=14, lg=15, xl=16, 2xl=20, 3xl=26

Spacing: 4px base unit (4,8,12,16,20,24,32,40,48)
Radius: sm=6, md=10, lg=12, xl=16, 2xl=18, full=9999
Shadows: subtle β€” elevation 1-4, shadowOpacity 0.05-0.15

═══════════════════════════════════════════
NAVIGATION STRUCTURE
═══════════════════════════════════════════
Unauthenticated stack:
  - LoginScreen
  - ChangePasswordScreen (force_password_change flow)
  - LegacyMessageScreen (special users: Karina, CecΓ­lia)
  - ForgotPasswordScreen
  - ResetPasswordScreen

Authenticated bottom tabs:
  πŸ’‘ Ideas    β†’ IdeasScreen (home)
  πŸ““ Sessions β†’ SessionsScreen
  πŸ—ΊοΈ Roadmap  β†’ RoadmapScreen
  πŸ“Š Report   β†’ ReportScreen
  βš™οΈ Settings β†’ SettingsScreen

═══════════════════════════════════════════
API BASE URL: https://bbrainapp.you
AUTH HEADER:  Authorization: Bearer {token}
═══════════════════════════════════════════

ALL API ENDPOINTS:

[AUTH β€” no token required]
GET  /api/auth/status
  β†’ { setup_required: bool, authenticated: bool }

POST /api/auth/login
  body: { username, password }
  β†’ { token, username, force_password_change: bool, firstLoginMessage?: string }

POST /api/auth/setup
  body: { username, password }
  β†’ { token, username }

POST /api/auth/change-password  [requires token]
  body: { password }
  β†’ { success: true }

POST /api/auth/logout  [requires token]
  β†’ { success: true }

POST /api/auth/reset-request
  β†’ { success: true }

POST /api/auth/reset
  body: { code, password }
  β†’ { success: true }

[IDEAS β€” requires token]
GET  /api/ideas?status=nova&source=whatsapp
  β†’ { ideas: Idea[], meta: { total, on_roadmap, archived, from_whatsapp } }

POST /api/ideas
  body: { text, source?, session_id? }
  β†’ { idea: Idea }

PATCH /api/ideas/:id
  body: { status?, tags?, evaluation?, roadmap_phase?, connections? }
  β†’ { idea: Idea }

DELETE /api/ideas/:id
  β†’ { success: true }

Idea object:
{
  id: string,            // "20260320-ABC12"
  text: string,
  source: "web"|"whatsapp"|"api",
  whatsapp_from: string|null,
  created_at: string,    // ISO 8601
  status: "nova"|"em_analise"|"no_roadmap"|"arquivada",
  tags: string[],
  evaluation: string|null,
  roadmap_phase: "backlog"|"planejado"|"em_execucao"|"concluido"|null,
  connections: string[],
  session_id: string|null,
  updated_at: string|null
}

[SESSIONS β€” requires token]
GET  /api/sessions
  β†’ { sessions: Session[], meta: { total_sessions, total_hours, last_session } }

POST /api/sessions
  body: { location, initial_thoughts? }
  β†’ { session: Session }

PATCH /api/sessions/:id
  body: { ended_at, duration_minutes }
  β†’ { session: Session }

Session object:
{
  id: string,
  started_at: string,
  ended_at: string|null,
  location: string,
  initial_thoughts: string|null,
  duration_minutes: number|null,
  features_worked: string[],
  ideas_captured: string[],
  social_content: string|null
}

[SETTINGS β€” requires token]
GET  /api/settings
  β†’ { settings: { plan, reminder_frequency, reminder_time, reminder_channels } }

POST /api/settings
  body: { plan?, reminder_frequency?, reminder_time?, reminder_channels? }
  β†’ { settings: {...} }

settings.plan values: "free"|"pro"|"power"
settings.reminder_frequency: ""|"monthly"|"every15days"|"every2days"|"daily"
  - free plan: monthly, every15days only
  - pro plan: + every2days
  - power plan: all (including daily)
settings.reminder_channels: "email"|"whatsapp"|"email,whatsapp"
  - whatsapp only for pro and power plans

[REPORT β€” requires token]
GET  /api/report/monthly?month=2026-03
  β†’ {
      month, ideas_count, sessions_count, roadmap_count,
      total_duration (minutes), best_day: { date, count }|null,
      ideas: IdeaReport[], sessions: SessionReport[]
    }

[STRIPE β€” requires token except webhook]
GET  /api/stripe/plans
  β†’ { plans: [{ id, name, price_brl, price_usd, features[] }] }

POST /api/stripe/checkout
  body: { plan: "pro"|"power" }
  β†’ { url: string, session_id: string }

GET  /api/stripe/portal
  β†’ { url: string }

POST /api/stripe/webhook  [Stripe calls this β€” no auth]
  Stripe events handled: checkout.session.completed, customer.subscription.deleted

[VERSION]
GET /api/version
  β†’ { version, updated_at }

═══════════════════════════════════════════
SCREEN SPECIFICATIONS
═══════════════════════════════════════════

── LoginScreen ──
Background: brain (#1A0A3A), full screen
Layout: centered, max-width 340px
Elements:
  - Language selector top: PT πŸ‡§πŸ‡· | EN πŸ‡ΊπŸ‡Έ | FR πŸ‡«πŸ‡· | ES πŸ‡ͺπŸ‡Έ | DE πŸ‡©πŸ‡ͺ
  - Brain emoji 🧠 (52px)
  - Title "BBrain" (26px bold, white)
  - Subtitle "Aproove Β· DiΓ‘rio do Fundador" (muted white)
  - Username input (dark glass morphism: rgba(255,255,255,0.07))
  - Password input + show/hide toggle
  - "Entrar" button (white bg, brain text, full width)
  - Error text (red #F87171)
  - "Esqueci minha senha" link
  - "Criar conta" link (only if setup_required)
On login success:
  - Save token to SecureStore
  - Save today's date to SecureStore
  - If force_password_change β†’ navigate to ChangePasswordScreen
  - If firstLoginMessage β†’ navigate to LegacyMessageScreen
  - Else β†’ navigate to main tabs

── ChangePasswordScreen ──
Background: brain
Elements:
  - Lock emoji πŸ”
  - "Defina sua senha" title
  - "Por seguranΓ§a, crie uma senha pessoal antes de continuar." subtitle
  - New password input
  - Confirm password input
  - "Confirmar" button
On success: navigate to main tabs

── LegacyMessageScreen ──
Background: brain
Elements:
  - Brain emoji
  - Message text (italic, white, pre-line whitespace)
  - "Entrar no BBrain" button
Persist message in AsyncStorage for permanent footer display.

── IdeasScreen (Main Tab) ──
Header:
  - BBrain logo + subtitle
  - Stat chips: N ideias, N no roadmap, N sessΓ΅es
  - Active session indicator (green dot + timer)
  - πŸ”” reminder settings button
  - Language selector
  - Logout button

Session banner (when active):
  - Background: #EEF0F4 (light gray)
  - Text: #1A2A4A (dark blue)
  - Green pulse dot + location + elapsed timer
  - "Encerrar sessΓ£o" button

Capture area:
  - White card, rounded
  - TextInput multiline "Qualquer pensamento..."
  - "Registrar ideia" button + Ctrl+Enter hint

Filter pills row:
  Todas | Novas | Roadmap | Em anΓ‘lise | Arquivadas (with counts)

Ideas list (FlatList):
  Each card (white, rounded 12):
    - Index number (#001) DM Mono
    - Idea text
    - Meta row: date, source badge (WhatsApp/Web), status badge
    - If roadmap_phase: phase badge
    - If session_id: linked session tag
    - If evaluation: purple evaluation block
    - Action buttons: +Roadmap | Analisar | Arquivar / Reabrir | βœ•

Status badge colors:
  nova β†’ blue, em_analise β†’ amber, no_roadmap β†’ green, arquivada β†’ paper/muted

Swipe gesture on idea card (optional):
  Left β†’ Archive; Right β†’ Roadmap

── SessionsScreen ──
Header: "+ Nova sessΓ£o" button

When no active session:
  Show check-in form (inline, full screen):
    - "Nova sessΓ£o de trabalho" title + datetime
    - Location pills: Em casa | No escritΓ³rio | De madrugada | No cafΓ© | Viajando + free text
    - "O que vocΓͺ estΓ‘ pensando?" textarea
    - "ComeΓ§ar a trabalhar" CTA button (brain, full width)
    - "Continuar sem registrar sessΓ£o" skip link

Sessions list (FlatList):
  Each session card:
    - Date block (large day number + month)
    - Time range: 09:30 β†’ 11:45
    - Location with πŸ“
    - Duration (DM Mono)
    - Ideas captured count
    - Initial thoughts (italic quote)
    - Ideas from this session (expandable)
    - "✦ Gerar conteΓΊdo" / "πŸ“± Ver post" button
    - Social post preview (Instagram/LinkedIn draft)

── RoadmapScreen ──
Toggle: Kanban | Lista

Kanban view (4 columns, horizontal scroll):
  πŸ“‹ Backlog | πŸ”§ Planejado | ⚑ Em execuΓ§Γ£o | βœ… ConcluΓ­do
  Each column: idea cards with move-to-phase buttons

List view:
  Each row: phase badge (colored) + idea text + "Mover para" select

Empty state: "Adicione ideias ao Roadmap na aba πŸ’‘"

── ReportScreen ──
Month picker (default: current month)
"Gerar" button

Report sections:
  Stats grid (2x2 or 2x3):
    - N ideias capturadas
    - N sessΓ΅es registradas
    - N no roadmap
    - Xh Xmin trabalhadas
    - Melhor dia (date + count)

  Ideas list section:
    Each: date chip + idea text (truncated 200 chars)

  Sessions list section:
    Each: date chip + location + duration + initial thoughts excerpt

"↓ Exportar HTML" button β†’ Share sheet with HTML string

── SettingsScreen ──
User info section:
  - Username + plan badge
  - "Gerenciar assinatura" β†’ Stripe portal (for paid plans)

Reminders section:
  - Frequency select (restrictions by plan, show "upgrade" for locked options)
  - Time picker
  - Channel: Email checkbox + WhatsApp checkbox (pro/power only)
  - "Salvar" button

Plans section (if free plan):
  Plan cards: Free | Pro R$14,90/mΓͺs | Power R$29,90/mΓͺs
  "Fazer upgrade" β†’ stripeCheckout() β†’ open in browser

Language section:
  Flag buttons PT | EN | FR | ES | DE

App section:
  - App version
  - "PolΓ­tica de Privacidade" link
  - "Logout" button (red tint)

═══════════════════════════════════════════
AUTHENTICATION FLOW (client-side)
═══════════════════════════════════════════
1. On app start: read token from SecureStore
2. Check if token date === today (local expiry)
3. Call GET /api/auth/status with token
4. If authenticated β†’ load main tabs
5. If not β†’ show LoginScreen
6. After login: store { token, tokenDate } in SecureStore
7. On logout: delete from SecureStore, call POST /api/auth/logout

═══════════════════════════════════════════
STRIPE PAYMENT FLOW
═══════════════════════════════════════════
1. User taps "Fazer upgrade" on SettingsScreen
2. App calls POST /api/stripe/checkout with { plan }
3. Server creates Checkout Session, returns { url }
4. App opens url in expo-web-browser
5. User completes payment on Stripe Checkout
6. Stripe calls POST /api/stripe/webhook β†’ server updates plan in Sheets
7. App polls GET /api/settings on return from browser
8. Plan badge updates in UI

For subscription management:
1. User taps "Gerenciar assinatura"
2. App calls GET /api/stripe/portal
3. Opens returned url in expo-web-browser

Plan restrictions (enforced client-side, validated server-side):
  free:  reminder_frequency ∈ { monthly, every15days }; channel = email only
  pro:   + every2days; + whatsapp channel
  power: + daily; all channels; early access to new features

═══════════════════════════════════════════
OFFLINE SUPPORT
═══════════════════════════════════════════
- Cache ideas and sessions in AsyncStorage on fetch
- On API failure: read from cache, show "offline" indicator
- Queue failed POST/PATCH operations and retry on reconnect
- Use NetInfo to detect connectivity

═══════════════════════════════════════════
I18N (5 languages)
═══════════════════════════════════════════
Supported: pt-BR (default), en-US, fr-FR, es-ES, de-DE
Use react-i18next with inline namespace.
Language stored in AsyncStorage. Settable from Login screen and Settings.

═══════════════════════════════════════════
PROJECT FILE STRUCTURE
═══════════════════════════════════════════
bbrain-app/
β”œβ”€β”€ app.json                    # Expo config
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ _layout.tsx             # Root navigator
β”‚   β”œβ”€β”€ (auth)/
β”‚   β”‚   β”œβ”€β”€ login.tsx
β”‚   β”‚   β”œβ”€β”€ change-password.tsx
β”‚   β”‚   β”œβ”€β”€ legacy-message.tsx
β”‚   β”‚   β”œβ”€β”€ forgot-password.tsx
β”‚   β”‚   └── reset-password.tsx
β”‚   └── (tabs)/
β”‚       β”œβ”€β”€ _layout.tsx         # Bottom tabs
β”‚       β”œβ”€β”€ ideas.tsx
β”‚       β”œβ”€β”€ sessions.tsx
β”‚       β”œβ”€β”€ roadmap.tsx
β”‚       β”œβ”€β”€ report.tsx
β”‚       └── settings.tsx
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ IdeaCard.tsx
β”‚   β”œβ”€β”€ SessionCard.tsx
β”‚   β”œβ”€β”€ RoadmapKanban.tsx
β”‚   β”œβ”€β”€ SessionBanner.tsx
β”‚   β”œβ”€β”€ CheckInForm.tsx
β”‚   β”œβ”€β”€ ReminderBanner.tsx
β”‚   β”œβ”€β”€ PlanBadge.tsx
β”‚   └── ui/                     # Button, Input, Badge, Toast, Modal
β”œβ”€β”€ hooks/
β”‚   β”œβ”€β”€ useAuth.ts
β”‚   β”œβ”€β”€ useIdeas.ts
β”‚   β”œβ”€β”€ useSessions.ts
β”‚   β”œβ”€β”€ useSettings.ts
β”‚   └── useStripe.ts
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ api.ts                  # Axios/fetch wrapper with auth header
β”‚   β”œβ”€β”€ auth.ts                 # Token storage (SecureStore)
β”‚   β”œβ”€β”€ i18n.ts                 # Translations
β”‚   └── stripe.ts               # Stripe helpers
β”œβ”€β”€ types/
β”‚   └── index.ts                # Idea, Session, Settings, Plan interfaces
└── assets/
    β”œβ”€β”€ icon.png                # 1024x1024 PNG
    └── splash.png

═══════════════════════════════════════════
PACKAGE.JSON DEPENDENCIES
═══════════════════════════════════════════
{
  "expo": "~51.0.0",
  "react": "18.2.0",
  "react-native": "0.74.x",
  "expo-router": "~3.5.0",
  "expo-secure-store": "~13.0.0",
  "@react-navigation/bottom-tabs": "^6.6.0",
  "@tanstack/react-query": "^5.40.0",
  "@stripe/stripe-react-native": "0.37.x",
  "expo-web-browser": "~13.0.0",
  "expo-notifications": "~0.28.0",
  "react-i18next": "^14.1.0",
  "i18next": "^23.11.0",
  "dayjs": "^1.11.11",
  "nativewind": "^4.0.36",
  "@react-native-async-storage/async-storage": "1.23.1",
  "@react-native-community/netinfo": "11.3.x"
}

═══════════════════════════════════════════
app.json (Expo config)
═══════════════════════════════════════════
{
  "expo": {
    "name": "BBrain",
    "slug": "bbrain",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "scheme": "bbrain",
    "userInterfaceStyle": "light",
    "splash": { "image": "./assets/splash.png", "backgroundColor": "#1A0A3A" },
    "ios": {
      "supportsTablet": false,
      "bundleIdentifier": "you.bbrainapp.bbrain",
      "buildNumber": "1"
    },
    "android": {
      "adaptiveIcon": { "foregroundImage": "./assets/icon.png", "backgroundColor": "#1A0A3A" },
      "package": "you.bbrainapp.bbrain",
      "versionCode": 1
    },
    "plugins": [
      "expo-router",
      "expo-secure-store",
      ["expo-notifications", { "sounds": [] }],
      ["@stripe/stripe-react-native", { "merchantIdentifier": "merchant.you.bbrainapp" }]
    ],
    "extra": {
      "apiBaseUrl": "https://bbrainapp.you",
      "stripePublishableKey": "pk_live_YOUR_KEY_HERE"
    }
  }
}

═══════════════════════════════════════════
IMPORTANT IMPLEMENTATION NOTES
═══════════════════════════════════════════
1. The API uses NO CORS restrictions β€” all requests must include Authorization header.
2. Idea IDs are formatted as "YYYYMMDD-XXXXX" (date + 5-char alphanumeric).
3. Token expiry is client-side daily check (compare stored date to today).
4. The master admin "brunomassa" always has plan="power" (server-enforced).
5. For Stripe: use WebBrowser.openAuthSessionAsync() to handle redirect back to app.
6. Special users Karina and CecΓ­lia receive a legacy message on first login β€” store in AsyncStorage permanently.
7. Session timer: start counting from session.started_at using setInterval every second.
8. Roadmap phases: backlog β†’ planejado β†’ em_execucao β†’ concluido (in order).
9. Report export: use expo-sharing + expo-file-system to save HTML and share.
10. Language preference: store in AsyncStorage, apply to all text via i18next.

Generate the complete, production-ready code for all files listed in the project structure above.
Start with: types/index.ts β†’ lib/api.ts β†’ lib/auth.ts β†’ lib/i18n.ts β†’ hooks/ β†’ components/ui/ β†’ components/ β†’ app/(auth)/ β†’ app/(tabs)/ β†’ app/_layout.tsx
πŸ’³
Stripe β€” ConfiguraΓ§Γ£o de Pagamentos
3 planos Β· Free / Pro R$14,90 / Power R$29,90
Free
R$ 0
Lembrete a cada 15/30 dias Β· E-mail
BBrain Pro ✦
R$14,90/mΓͺs
Lembrete a cada 2 dias Β· WhatsApp
BBrain Power ✦✦
R$29,90/mΓͺs
Lembrete diΓ‘rio Β· Acesso antecipado

VariΓ‘veis de ambiente para configurar no Fly.io:

# Obter em: dashboard.stripe.com β†’ API Keys
flyctl secrets set STRIPE_SECRET_KEY=sk_live_...
flyctl secrets set STRIPE_WEBHOOK_SECRET=whsec_...

# Criar produtos em: dashboard.stripe.com β†’ Products
# Produto "BBrain Pro" β†’ PreΓ§o recorrente R$14,90/mΓͺs
flyctl secrets set STRIPE_PRICE_PRO=price_...

# Produto "BBrain Power" β†’ PreΓ§o recorrente R$29,90/mΓͺs
flyctl secrets set STRIPE_PRICE_POWER=price_...

# URL base do app (jΓ‘ deve estar configurada)
flyctl secrets set APP_BASE_URL=https://bbrainapp.you

Configurar webhook no Stripe Dashboard:

# Em: dashboard.stripe.com β†’ Webhooks β†’ Add endpoint
Endpoint URL: https://bbrainapp.you/api/stripe/webhook

Eventos a escutar:
  βœ“ checkout.session.completed
  βœ“ invoice.payment_succeeded
  βœ“ customer.subscription.deleted

Endpoints disponΓ­veis na API:

MΓ©todo Endpoint DescriΓ§Γ£o
POST/api/stripe/checkoutCria checkout session Β· body: { plan: "pro"|"power" } β†’ { url }
GET/api/stripe/portalCustomer portal (gerenciar assinatura) β†’ { url }
GET/api/stripe/plansLista planos e preΓ§os (pΓΊblico)
POST/api/stripe/webhookRecebe eventos Stripe (sem auth)
πŸͺ‘
Gerar App com Google Stitch
Prompt para stitch.withgoogle.com Β· Web App / PWA

Cole este prompt em stitch.withgoogle.com para gerar uma Web App / PWA completa do BBrain. O Stitch gera apps web responsivos prontos para deploy β€” ideal para ter uma versΓ£o web funcional do app enquanto o React Native Γ© desenvolvido.

Build a complete, production-ready Progressive Web App (PWA) called **BBrain** β€” a private founder's journal and idea capture tool for iOS and Android home screen installation.

═══════════════════════════════════════════
PRODUCT OVERVIEW
═══════════════════════════════════════════
BBrain is a personal "second brain" for founders, indie hackers, and content creators.
Single user, premium app. Mobile-first, installable as PWA.
Tagline: "Capture ideas in 3 seconds. Review them forever."

Backend API: https://bbrainapp.you (REST, Node.js)
Auth: Bearer token stored in localStorage, daily expiry (client manages TTL)
Language: start in PT-BR; user can switch to EN / FR / ES / DE in settings

═══════════════════════════════════════════
DESIGN SYSTEM
═══════════════════════════════════════════
Font: DM Sans (body), DM Serif Display (headings) β€” from Google Fonts
Colors:
  --brain:      #1a0a3a   (deep navy β€” primary brand)
  --brain-mid:  #3a1f7a   (purple β€” accents, buttons)
  --brain-lite: #a78bfa   (light purple β€” highlights)
  --paper:      #f7f5ef   (warm off-white β€” background)
  --paper2:     #efede6
  --paper3:     #e4e1d8
  --ink:        #111110
  --ink2:       #4a4a47
  --ink3:       #9a9a96
  --green:      #2a5f2a
  --amber:      #7a4a0a

Border radius: 12–14px for cards, 8px for buttons/inputs
Shadows: subtle (0 4px 16px rgba(26,10,58,.08))
Motion: 200ms ease transitions, no heavy animations

═══════════════════════════════════════════
PWA REQUIREMENTS
═══════════════════════════════════════════
- manifest.json: name "BBrain", short_name "BBrain", theme_color #1a0a3a, background_color #f7f5ef, display standalone, orientation portrait
- Service Worker: cache shell + API GET responses for offline read
- Icons: generate from the letter B on brain (#1a0a3a) background β€” sizes 192, 512
- iOS meta tags: apple-mobile-web-app-capable, apple-mobile-web-app-status-bar-style black-translucent
- Install prompt: show "Add to home screen" banner after 3rd visit

═══════════════════════════════════════════
AUTH FLOW
═══════════════════════════════════════════
POST /api/auth/login
  body: { username, password }
  β†’ { token, username, force_password_change }

If force_password_change === true β†’ show ChangePasswordScreen before app

POST /api/auth/change-password
  headers: Authorization: Bearer {token}
  body: { current_password, new_password }
  β†’ { success }

POST /api/auth/logout
  headers: Authorization: Bearer {token}

All authenticated requests must include:
  Authorization: Bearer {token}

Store token in localStorage key "bbrain_token"
Token TTL: compute from login timestamp, expire after 86400s client-side
On 401 β†’ clear localStorage, redirect to login

═══════════════════════════════════════════
API REFERENCE
═══════════════════════════════════════════
Base URL: https://bbrainapp.you

── IDEAS ──
GET  /api/ideas
  params: ?status=nova|analisando|arquivada&source=web|whatsapp
  β†’ { ideas: Idea[], meta: { total, by_status: {nova,analisando,arquivada} } }

POST /api/ideas
  body: { text, source?, tags?, roadmap_phase?, session_id? }
  β†’ { idea: Idea }

PATCH /api/ideas/:id
  body: { status?, roadmap_phase?, tags?, connections? }
  β†’ { idea: Idea }

DELETE /api/ideas/:id
  β†’ { success: true }

── SESSIONS ──
GET  /api/sessions
  β†’ { sessions: Session[] }

POST /api/sessions
  body: { location?, focus?, energy? }
  β†’ { session: Session }

PATCH /api/sessions/:id
  body: { checked_out_at?, ideas_captured?, features_worked? }
  β†’ { session: Session }

── SETTINGS ──
GET  /api/settings
  β†’ { settings: { email, plan: "free"|"pro"|"power", reminder_frequency, reminder_time, reminder_channels, last_reminder } }

POST /api/settings
  body: { email?, reminder_frequency?, reminder_time?, reminder_channels?, plan? }
  β†’ { success: true }

── REPORT ──
GET  /api/report/monthly?month=YYYY-MM
  β†’ { month, total_ideas, by_status, by_source, sessions_count, avg_ideas_per_session, top_ideas: Idea[] }

── STRIPE ──
GET  /api/stripe/plans   (public β€” no auth)
  β†’ { plans: [{ id, name, price_brl, price_usd, features[] }] }

POST /api/stripe/checkout
  body: { plan: "pro"|"power" }
  β†’ { url: string }   β€” redirect user to this URL

GET  /api/stripe/portal
  β†’ { url: string }   β€” redirect to Stripe customer portal

── MISC ──
GET  /api/status  (public)
  β†’ { server, version, ai_configured, whatsapp_configured }

═══════════════════════════════════════════
DATA MODELS
═══════════════════════════════════════════
Idea {
  id: string
  text: string
  source: "web" | "whatsapp"
  status: "nova" | "analisando" | "arquivada"
  tags: string[]
  roadmap_phase: "now" | "next" | "later" | "icebox" | null
  session_id: string | null
  created_at: ISO string
  updated_at: ISO string
}

Session {
  id: string
  started_at: ISO string
  checked_out_at: ISO string | null
  location: string
  focus: string
  energy: 1|2|3|4|5
  ideas_captured: number
  features_worked: string
}

Plan {
  free:  50 ideas/month, reminders monthly/every15days, email only
  pro:   unlimited, +every2days, +whatsapp
  power: unlimited, all frequencies (daily included), all channels
}

═══════════════════════════════════════════
SCREEN SPECIFICATIONS
═══════════════════════════════════════════

── /login ──
Full-screen brain (#1a0a3a) background
Center card (max-width 340px, white, border-radius 20px, shadow)
  - Language selector: πŸ‡§πŸ‡· PT | πŸ‡ΊπŸ‡Έ EN | πŸ‡«πŸ‡· FR | πŸ‡ͺπŸ‡Έ ES | πŸ‡©πŸ‡ͺ DE
  - 🧠 emoji (52px) + "BBrain" title (DM Serif, 28px, white)
  - Subtitle: "Aproove Β· DiΓ‘rio do Fundador" (muted)
  - Input: username (text, placeholder "UsuΓ‘rio")
  - Input: password (password, placeholder "Senha", show/hide toggle)
  - Button "Entrar" (full-width, brain-mid background, white, bold)
  - Link "Esqueci a senha" below button
  - Forgot password inline: email field + "Enviar link" + back link

── / (Home β€” Ideas tab) ──
Header (fixed, 56px, blur backdrop):
  - Logo "BBrain" (DM Serif, 20px, brain color)
  - Right: πŸ”” button (if plan β‰₯ free), username chip, logout

Bottom tab bar (4 tabs):
  πŸ’‘ Ideias | πŸ—“ SessΓ΅es | πŸ—Ί Roadmap | πŸ“Š RelatΓ³rio

Ideas tab content:
  - Status counters bar: Nova (N) Β· Analisando (N) Β· Arquivadas (N)
  - Active session banner (if session active): "Em sessΓ£o Β· {location} Β· {focus}"
    with Check-out button
  - "Nova Ideia" FAB (bottom-right, brain-mid color, +)
  - Idea list: card per idea
    Card: text (clamp 2 lines), status badge, created_at relative, tag chips
    Swipe left β†’ archive; Swipe right β†’ analyze
    Tap β†’ expand (full text, edit status, edit tags, roadmap_phase selector, delete)
  - Filter chips above list: Todas | Nova | Analisando | Arquivada

"Nova Ideia" modal (bottom sheet, handle bar):
  - Textarea (autofocus, large, placeholder "O que estΓ‘ na sua cabeΓ§a?")
  - Tags input (comma separated, shown as chips)
  - Roadmap phase selector: Now / Next / Later / Icebox
  - Submit button "Capturar" (full-width, brain-mid)
  - Keyboard shortcut: Enter to submit (Cmd/Ctrl+Enter on desktop)

── /sessions ──
"Nova SessΓ£o" button top-right
Session list (reverse chronological):
  - Card: date/time, location, focus, energy (β˜… stars), badge (active/closed)
  - Ideas captured count chip
  - Tap to expand: full details + ideas linked to this session

"Nova SessΓ£o" modal (bottom sheet):
  - Where are you? (text, placeholder "Casa, CafΓ©, EscritΓ³rio...")
  - What will you focus on? (textarea)
  - Energy level: 1–5 star selector
  - Button "Iniciar sessΓ£o" (brain-mid)

── /roadmap ──
Kanban board with 4 columns: Now | Next | Later | Icebox
  - Each column header shows count badge
  - Idea cards: drag-and-drop between columns (or tap β†’ select phase)
  - Cards: text (2 lines), status badge, created_at
  - Empty column: dashed border placeholder "Solte aqui"

Toggle above: πŸ—‚ Kanban | πŸ“‹ Lista
Lista view: flat list filtered by phase, grouped headers

── /report ──
Month picker: ← Fev 2026 β†’ (navigate months)
Stats cards grid (2 cols):
  - Total de Ideias (large number)
  - SessΓ΅es Realizadas
  - MΓ©dia ideias/sessΓ£o
  - Arquivadas este mΓͺs

Donut chart: Nova / Analisando / Arquivada (use CSS or simple SVG β€” no chart lib)
Top 5 ideias do mΓͺs: ranked list with index badges

── /settings (accessible from header or profile) ──
Sections:
  1. Conta: email display, change-password link
  2. Plano atual: badge (Free / Pro / Power)
     If free/pro: "Fazer upgrade" button β†’ /plans
  3. Lembretes:
     Frequency selector (options per plan):
       free: A cada 30 dias, A cada 15 dias
       pro:  + A cada 2 dias
       power: + Todo dia
     Time picker (HH:MM)
     Channel: Email (free+) Β· WhatsApp (pro+)
     Save button
  4. Idioma: 5 flag buttons
  5. Logout button (danger style)

── /plans ──
3 plan cards (stacked on mobile, side-by-side on tablet):
  Free: R$0 β€” 50 ideias/mΓͺs, lembretes mensais, email
  Pro:  R$14,90/mΓͺs β€” ilimitado, lembretes a cada 2 dias, WhatsApp β€” "Mais popular" badge
  Power:R$29,90/mΓͺs β€” tudo + todo dia + prioridade IA

Each card: features list with βœ“/βœ—, CTA button
  Free β†’ active chip "Seu plano"
  Pro/Power β†’ "Assinar" β†’ POST /api/stripe/checkout β†’ redirect to url

═══════════════════════════════════════════
TECHNICAL REQUIREMENTS
═══════════════════════════════════════════
Framework: vanilla JS + Web Components, OR React (your choice β€” prefer minimal bundle)
State management: simple module pattern or React Context β€” NO Redux
HTTP layer: a single api() helper that auto-attaches Authorization header and handles 401
Routing: client-side SPA, History API or hash routing
i18n: JSON translation files for 5 languages, detected from localStorage "bbrain_lang"
Offline: Service Worker caches GET /api/ideas and GET /api/sessions for read-only offline
Bundle: single HTML file output preferred (Stitch default), or index.html + assets
No external UI libraries β€” implement all components from scratch using the design tokens above

═══════════════════════════════════════════
EXTRA DETAILS
═══════════════════════════════════════════
- All dates shown in Brazilian format: DD/MM/YYYY HH:mm
- Relative time: "hΓ‘ 2 horas", "ontem", "hΓ‘ 3 dias"
- Empty states: friendly illustrations using CSS/emoji β€” no image files
- Error states: inline, non-blocking toast notifications (bottom center, 3s auto-dismiss)
- Loading states: skeleton screens, not spinners
- Accessibility: semantic HTML, aria-labels on icon buttons, focus rings
- Dark mode: NOT required for v1
- Analytics: NOT required for v1