Skip to content

omsatodiya/otta

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

121 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Otta β€” Campus Emotional Companion

Every student deserves to feel understood before they feel alone.

Otta is a campus-aware mental wellness platform powered by Ollie the Otter β€” an AI companion who knows your college, your season, and how you actually feel. Built for Indian engineering campuses where placement anxiety, hostel loneliness, and midsem burnout are realities no generic wellness app addresses.


Screenshots

Add screenshots here once the demo is recorded.

Home & Mood Log Ollie Chat Peer Circles Counselor Portal
(screenshot) (screenshot) (screenshot) (screenshot)
Mood Patterns Missions Level & XP Login
(screenshot) (screenshot) (screenshot) (screenshot)

Quick Start

npm install
npm start          # Expo dev server

Open the QR code in Expo Go on a phone connected to the same Wi-Fi.

For a full native build:

expo run:android   # USB-connected device

Type checks:

npm run typecheck
npx expo install --check

Table of Contents

  1. Problem
  2. Solution
  3. Competitor Landscape
  4. Core Features
  5. Tech Stack
  6. High-Level Architecture
  7. Low-Level Design
  8. Data Models
  9. AI System Design
  10. Anonymous Peer Circles
  11. Counselor Intelligence
  12. Gamification System
  13. Privacy Architecture
  14. Screen Inventory
  15. Roadmap

Problem

Indian engineering students face a silent mental health crisis:

  • 5.4 crore students enrolled in higher education (UGC 2023)
  • 64% report significant academic stress (NIMHANS 2022)
  • <5% ever seek professional help β€” stigma, cost, and lack of access are barriers
  • Average wait time for on-campus counseling: 2–3 weeks

By the time a student reaches a counselor, the situation is often already severe. Existing solutions fail at three levels:

Problem Why apps fail
Campus blindness Generic apps don't know what "compres" or "placement season" means
Friction Mood tracking that takes more than 10 seconds gets abandoned
Isolation No peer support; no shared struggle; no community
Invisible to institutions Counselors have no visibility into campus-wide trends

Solution

Otta provides before-crisis support through four pillars:

mindmap
  root((Otta))
    Ollie AI
      Campus-aware chat
      Mood pattern memory
      Gemini Flash backbone
      OpenRouter fallback
    Mood Intelligence
      One-tap logging
      Calendar heatmap
      Distribution analytics
      Streak tracking
    Peer Circles
      Anonymous rooms
      Optional identity reveal
      Daily AI prompts
      Ollie warmth sends
    Counselor Portal
      Anonymous trend cards
      Risk alert triage
      Campus pulse signals
      Culture knowledge base
Loading

Competitor Landscape

Product Campus Context Peer Support Counselor Tools Anonymous India-first Gamified
Otta βœ… Deep βœ… Circles βœ… Dashboard βœ… Full βœ… βœ…
Wysa ❌ ❌ ❌ Partial ❌ ❌
Headspace ❌ ❌ ❌ ❌ ❌ ❌
YourDOST ❌ ❌ Limited ❌ βœ… ❌
iCall ❌ ❌ βœ… ❌ βœ… ❌
Intellect Partial ❌ Limited ❌ ❌ ❌
Finch ❌ ❌ ❌ ❌ ❌ βœ…

What competitors lack that Otta provides:

  • Knowledge of midsems, placement season, hostel culture, wing dynamics
  • Anonymous peer matching by emotional need
  • Counselor-facing campus intelligence without exposing student identity
  • Gamification that rewards showing up β€” not punishing absence

Core Features

1. Ollie AI Companion

Ollie is an animated otter mascot with emotional states (idle, wave, smile, celebrate, think, worry). Every conversation is grounded in:

  • Institution context β€” college name, season, lingo, and cultural knowledge set by the counselor
  • Mood history β€” recent check-ins and emotional patterns
  • Conversation memory β€” summarized per-session, stored in SQLite
  • Peer circle state β€” what circles the student is in

Ollie uses Gemini Flash as the primary model with OpenRouter as fallback. Responses are streamed token-by-token for a natural feel.

2. Mood Tracking

  • 5-mood palette: Calm, Stressed, Lonely, Tired, Hopeful
  • Optional note with intelligent keyboard handling (safe area aware)
  • Mood stored in SQLite with timestamp and reason
  • Mood Patterns modal: calendar heatmap, distribution bar chart, day-of-week frequency, weekly trend delta, recent check-in timeline

3. Anonymous Peer Circles

Three pre-seeded circles per tenant, each with:

  • Emoji-free anonymous names (Green Kite, Silver Leaf, etc.)
  • Daily rotating AI-generated prompts
  • Text messaging + reactions
  • Ollie warmth sends (costs 5 coins, sends a generated supportive message)
  • Optional identity reveal β€” mutual, peer-to-peer, with reciprocal reveal simulation

4. Wellness Missions

Daily rotating set of 4–5 missions (2 core + 2–3 rotating):

  • Core: Log mood, 5-min breathing
  • Rotating: Chat with Ollie, visit a Circle, 10-min walk, write one moment, sleep before midnight, etc.
  • Counter missions (e.g. "Drink 8 glasses") with dot progress
  • Bonus mission unlock for 10 coins
  • All mission state persisted in SQLite

5. Gamification (Level & Closet)

  • Coins earned per mood log, daily check-in, mission completion
  • XP = coins; level computed via floor(sqrt(xp/25)) + 1
  • Level perks (Mood Pioneer β†’ Campus Legend)
  • Closet screen (items, cosmetics β€” coin-gated)

6. Counselor Portal

Six tabs accessible after org creation:

  • Overview β€” active students, avg mood, high-risk count, weekly check-in chart, stress sources
  • Students β€” searchable anonymous list with risk badges, mood icons, bar metrics
  • Student Detail β€” score cards, timeline, wellness activity log
  • Risk Alerts β€” filter by status, action triage via proper Modal
  • Campus Pulse β€” AI campus insight, trend grid, early warning signals
  • Culture β€” set lingo, key timings, events, campus culture for Ollie
  • Settings β€” knowledge bases, save

Counselor role persisted to SQLite (app_state table) so returning counselors skip onboarding.


Tech Stack

Layer Technology
Framework Expo SDK 56 (React Native)
Language TypeScript
Navigation Custom tab system (no expo-router)
Local DB expo-sqlite β€” moods, conversations, missions, app state
AI Gemini Flash (primary) + OpenRouter (fallback)
Fonts Baloo 2 (headings) + Nunito (body)
Icons @expo/vector-icons β€” Ionicons exclusively
Animations react-native Animated API
Safe Area react-native-safe-area-context
Widgets expo-widgets (native build only)
Notifications expo-notifications

High-Level Architecture

flowchart TD
    subgraph Client["Mobile App (Expo)"]
        UI["React Native UI"]
        SQLite["SQLite (expo-sqlite)"]
        WB["Widget Bridge"]
    end

    subgraph AI["AI Layer"]
        Gemini["Gemini Flash"]
        OR["OpenRouter Fallback"]
    end

    subgraph Persistence["Local Persistence"]
        Moods["mood_entries"]
        Chats["conversations"]
        Missions["mission_states"]
        AppState["app_state"]
        Circles["circle_messages"]
    end

    UI --> SQLite
    SQLite --> Persistence
    UI --> Gemini
    Gemini -- "fails/rate-limited" --> OR
    UI --> WB
    WB --> NativeWidget["Native Home Widget"]
Loading

Key architectural decisions

  • Fully offline-first: All mood data, mission state, and conversations live in SQLite β€” no backend required for the demo
  • No navigation library: Custom tab state in App.tsx, screen transitions via ScreenTransition component
  • State lifting for shared concerns: Reveal state, keyboard height, and bottom insets flow down from AppContent to all screens
  • Role persistence: Counselor role stored in app_state KV table so the app auto-restores the session on relaunch

Low-Level Design

Mood Logging Flow

sequenceDiagram
    actor Student
    participant HomeScreen
    participant BottomSheet
    participant SQLite
    participant OllieContext

    Student->>HomeScreen: Taps "Log Mood"
    HomeScreen->>BottomSheet: Opens modal (animates up)
    Student->>BottomSheet: Selects mood + optional note
    BottomSheet->>SQLite: insertMood(tenantId, mood, note)
    SQLite-->>HomeScreen: mood saved
    HomeScreen->>OllieContext: Updates ollieState β†’ "wave"
    HomeScreen->>HomeScreen: Confetti animation + toast
    HomeScreen->>SQLite: recordDailyCheckin()
    HomeScreen->>SQLite: insertConversation(system context update)
Loading

AI Chat Flow

sequenceDiagram
    actor Student
    participant ChatComposer
    participant App
    participant generateOllieReply
    participant Gemini
    participant OpenRouter

    Student->>ChatComposer: Types message
    ChatComposer->>App: onSend(text)
    App->>SQLite: insertConversation(role=user)
    App->>generateOllieReply: messages[], userMemory, campusKnowledge
    generateOllieReply->>Gemini: POST /generateContent (streaming)
    alt Gemini success
        Gemini-->>generateOllieReply: streamed tokens
    else Gemini fails
        generateOllieReply->>OpenRouter: POST /chat/completions
        OpenRouter-->>generateOllieReply: response
    end
    generateOllieReply-->>App: full reply text
    App->>SQLite: insertConversation(role=assistant)
    App->>ChatComposer: renders streamed reply
Loading

Keyboard & Safe Area Flow

flowchart LR
    DeviceInsets["useSafeAreaInsets()"] --> bottomInset
    KeyboardListener["Keyboard.addListener(keyboardDidShow)"] --> keyboardHeight
    bottomInset --> navBottom["navBottom = max(16, bottomInset)"]
    bottomInset --> sheetPadding["sheetPaddingBottom = max(bottomInset, 20) + 8"]
    keyboardHeight --> composerBottom["composerBottom = kbHeight > 0 ? kbHeight+10 : navBottom+80"]
    keyboardHeight --> BottomNavVisible["BottomNav hidden only during chat/groups with active room"]
Loading

Counselor Portal Navigation

stateDiagram-v2
    [*] --> LoginScreen
    LoginScreen --> CounselorPortalScreen : Create Org / Auto-login
    CounselorPortalScreen --> Overview
    CounselorPortalScreen --> Students
    Students --> StudentDetail
    StudentDetail --> Students
    CounselorPortalScreen --> RiskAlerts
    CounselorPortalScreen --> CampusPulse
    CounselorPortalScreen --> Culture
    CounselorPortalScreen --> Settings
    CounselorPortalScreen --> LoginScreen : Logout (clears SQLite role)
Loading

Data Models

All data lives in SQLite via expo-sqlite. Tables are created in src/db/localDb.ts.

erDiagram
    mood_entries {
        int id PK
        text tenant_id
        text mood
        text reason
        text note
        text created_at
    }

    conversations {
        int id PK
        text tenant_id
        text session_id
        text role
        text content
        int tokens
        text created_at
        text last_interaction_at
    }

    daily_checkins {
        int id PK
        text tenant_id
        text date
        int completed
    }

    mission_states {
        int id PK
        text title
        text status
        int progress
        text date
    }

    circle_messages {
        int id PK
        text circle_name
        text sender
        text content
        int revealed
        text created_at
    }

    circle_reactions {
        int id PK
        int message_id FK
        text reactor
        text created_at
    }

    circle_checkins {
        int id PK
        text circle_name
        text mood
        text date
    }

    app_state {
        text key PK
        text value
    }

    user_memory {
        int id PK
        text tenant_id
        text key
        text value
        text updated_at
    }
Loading

app_state key-value pairs

Key Value Purpose
role "counselor" Persists counselor login across sessions
coins "42" Student coin balance
totalXp "120" Total XP earned
joinedCircles JSON array Which circles the student has joined
bonusMissionUnlocked "true" Bonus mission state
tenant_id tenant ID string Selected college

AI System Design

Context Assembly

Every Ollie message is assembled from five context layers:

flowchart TD
    A["Institution Context\n(college, season, lingo, events)"] --> F
    B["Mood History\n(last 5 moods + reasons)"] --> F
    C["User Memory\n(personality traits, goals, patterns)"] --> F
    D["Conversation History\n(sliding window, last 10 messages)"] --> F
    E["Current Message"] --> F
    F["System Prompt Builder"] --> G["Gemini Flash\ngeneraOllieReply()"]
    G --> H["Streamed Response"]
Loading

Ollie Personality Constraints

Ollie is not a therapist. The system prompt enforces:

  • Never diagnose conditions
  • Never use clinical language
  • Always validate before advising
  • Keep responses concise (2–4 sentences unless asked)
  • Reference campus context naturally ("placement week", "midsem prep")
  • Suggest professional help for severe distress

Model Selection Logic

// Primary: Gemini Flash via direct API
// Fallback: OpenRouter (any configured model)
// Decision: if Gemini throws, catch and route to OpenRouter

Anonymous Peer Circles

Identity System

Each student in a circle has a randomly assigned two-word alias (e.g. "Green Kite", "Silver Leaf"). Real names are never shown unless explicitly revealed.

sequenceDiagram
    actor River as River (Green Pebble)
    actor Jamie as Jamie (Green Kite)

    River->>Circle: Posts message
    Circle-->>Jamie: Shows as "Green Pebble said..."
    River->>Circle: Taps "Reveal Identity to Green Kite"
    Circle->>River: Confirms reveal intent
    River-->>Jamie: "Green Pebble revealed: River"
    Jamie->>Circle: Reciprocal reveal (simulated after 2s)
    Circle-->>River: "Green Kite revealed: Jamie"
Loading

Circle State Persistence

  • Join/leave state: app_state.joinedCircles
  • Reveal state: lifted to App.tsx (revealedToPeers / revealedFromPeers)
  • Messages: circle_messages table
  • Reactions: circle_reactions table
  • Check-in mood: circle_checkins table

Counselor Intelligence

Privacy Guarantees

flowchart LR
    subgraph Visible["Counselor CAN see"]
        A["Anonymous student IDs\ne.g. #A1C9"]
        B["Aggregated mood trends"]
        C["Risk score bands"]
        D["Participation rates"]
        E["Campus-wide patterns"]
    end

    subgraph Hidden["Counselor CANNOT see"]
        F["Real names"]
        G["Chat history"]
        H["Circle messages"]
        I["Journal entries"]
        J["Reveal decisions"]
    end
Loading

Risk Scoring (Demo)

Risk levels are computed from composite signals:

Level Score Range Signals
🟒 Normal 0–40 Consistent mood, high participation
🟑 Watch 41–60 Mild mood dip, some absence
🟠 Alert 61–79 Sustained negative mood, isolation signals
πŸ”΄ Critical 80–100 Rapid decline, no check-ins, high stress

Gamification System

flowchart LR
    MoodLog["Log Mood\n+10 coins"] --> Coins
    DailyCheckin["Daily Check-in\n+15 coins"] --> Coins
    Mission["Complete Mission\n+15–40 coins"] --> Coins
    Coins --> XP["XP = Coins"]
    XP --> Level["Level = floor(sqrt(XP/25)) + 1"]
    Level --> Perks["Level Perks unlock"]
    Coins --> Closet["Closet items"]
    Coins --> BonusMission["Bonus Mission unlock (-10)"]
    Coins --> WarmthSend["Circle warmth send (-5)"]
Loading

Design principle: No punishment, no streak anxiety. Missing a day costs nothing. Showing up always rewards something.


Privacy Architecture

flowchart TD
    Student["Student Data"] --> LocalDB["SQLite (on-device only)"]
    LocalDB --> AI["AI Context Builder"]
    AI --> Gemini["Gemini API\n(stateless, no storage)"]
    LocalDB --> CounselorView["Counselor View\n(anonymized only)"]

    CounselorView -- "shows" --> AnonId["Anonymous ID\n#A1C9"]
    CounselorView -- "NEVER shows" --> RealName["Real name / chat / journals"]
Loading
  • No backend in demo β€” all data stays on device
  • AI calls are stateless β€” Gemini receives context only for the current request
  • Counselor screens show only anonymous IDs derived from internal hashes
  • Reveal is always opt-in, mutual, and logged locally

Screen Inventory

Screen Role Description
LoginScreen Both Tenant selection, student anonymous entry, counselor org creation
HomeScreen Student Mood log, Ollie greeting, mood patterns link, profile modal, logout
ChatScreen Student Multi-session Ollie chat with sidebar, streaming replies
GroupsScreen Student Join/leave circles, daily prompts, messaging, reveal identities
MissionsScreen Student Daily quest board, counter missions, bonus unlock
LevelScreen Student XP progress, level perks, coin balance, closet
MoodCalendarScreen Student Calendar heatmap, distribution bar, DoW heatmap, weekly delta
CounselorPortalScreen Counselor Tab shell with logout
OverviewScreen Counselor Stats, weekly chart, stress sources, circles activity
StudentListScreen Counselor Search, filter, risk badges, mood icons
StudentDetailScreen Counselor Score cards, mood timeline, wellness log
RiskAlertScreen Counselor Alert list, action triage modal
CampusPulseScreen Counselor AI insight card, trend grid, warning signals
CultureScreen Counselor Campus culture, lingo, timings, calendar
SettingsScreen Counselor Knowledge bases, save

Roadmap

gantt
    title Otta Product Roadmap
    dateFormat YYYY-MM
    section Phase 1 β€” Core
        AI Companion (Ollie)           :done, 2026-01, 2026-03
        Mood Tracking + Calendar       :done, 2026-02, 2026-04
        Peer Circles                   :done, 2026-03, 2026-05
        Gamification                   :done, 2026-03, 2026-06
    section Phase 2 β€” Growth
        Voice-first Ollie              :2026-07, 2026-09
        Institution SSO / LMS          :2026-08, 2026-10
        Advanced risk models           :2026-09, 2026-11
    section Phase 3 β€” Scale
        Predictive burnout detection   :2027-01, 2027-04
        Cross-campus benchmark index   :2027-03, 2027-06
        White-label counselor platform :2027-05, 2027-09
    section Phase 4 β€” Vision
        Pan-India student network      :2027-10, 2028-06
Loading

Production Backend (planned)

flowchart TD
    App["Expo App"] --> API["REST API (FastAPI)"]
    API --> PG["PostgreSQL\n(mood, users, convos)"]
    API --> Redis["Redis\n(sessions, rate limits)"]
    API --> Gemini["Gemini API"]
    API --> NS["Notification Service\n(FCM/APNs)"]
    API --> AE["Analytics Engine"]
    AE --> CD["Counselor Dashboard"]
    PG --> PGV["pgvector\n(semantic mood search)"]
Loading

Why Otta Matters

Indian students in engineering colleges face compounding pressures β€” placements, academic competition, distance from family, and an environment that often rewards silence over vulnerability. The existing mental health infrastructure cannot scale to meet this demand.

Otta sits in the gap: not a replacement for counselors, but the bridge that gets students to safety before they need one. Every mood logged, every Ollie conversation, every circle message is a small act of self-awareness β€” and Otta makes those acts frictionless, private, and even rewarding.

The metric that matters most: students who feel heard don't wait until crisis. Otta exists to make that the default.


Built with Expo SDK 56 Β· Gemini Flash Β· React Native Β· SQLite Β· Ionicons

About

Campus-aware emotional companion for students. AI-powered mood tracking, anonymous peer support, and wellbeing intelligence - built with Expo React Native

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors