# Student App Roadmap — From Google AI Studio Prototype to Production App

> Goal: turn a Google AI Studio prompt/app prototype into a production-ready **Android** app that’s privacy-preserving, accessible, and Play-Store-compliant.

---

## 0) North Star

* **Software-only, user-content app** (no bundled datasets).
* **Local-first posture**; network optional for AI calls.
* **Safety & consent** embedded (non-coercive prompts, visible controls).
* **Permissive license:** BSD-3 for code; trademarks reserved.

---

## 1) Extract from Google AI Studio

1. **Inventory** your AI Studio project:

   * System/instruction prompts, tool definitions, examples, evaluation sets.
   * Safety settings/filters (e.g., content categories you toggled).
2. **Template** the prompts:

   * Create `prompts/` with `system.md`, `user_guidelines.md`, `eval_cases.yaml`.
   * Convert AI Studio examples into unit tests (see §10).
3. **Define I/O schema:**

   * `ChatMessage(user|assistant|tool, text, meta)`
   * `ModelConfig(modelId, temperature, topK, maxTokens)`
   * `SafetyEvent(kind, details, timestamp)`

---

## 2) Architecture (Android)

**Single-activity** app with **Jetpack Compose** UI and **MVVM**:

```
app/
  ├─ ui/                 # Compose screens & components
  ├─ data/               # repositories, DTOs
  ├─ domain/             # use-cases (SendMessage, LoadHistory)
  ├─ ai/                 # LLMClient, Safety, PromptTemplates
  ├─ platform/           # storage, network, permissions
  └─ di/                 # Hilt modules
```

Key modules:

* `ai/LLMClient`: wraps cloud SDK + optional on-device model; supports **streaming**.
* `ai/Safety`: pre-/post-filters, consent prompts, redaction helpers.
* `platform/storage`: encrypted local store (Room + EncryptedFile / EncryptedSharedPreferences).
* `platform/network`: Retrofit/OkHttp (or Ktor) with retry & circuit breaker.

---

## 3) Model strategy

* **Cloud path:** call Gemini (or your chosen LLM) via HTTPS with server-issued tokens (see §5).
* **On-device path (optional):** use Android’s on-device model runtime where available; provide a **fallback** to cloud.
* **Switchable at runtime:** a simple setting in **Developer Options** or **Settings → AI Engine**.

---

## 4) Project setup

* **minSdk**: 24+ (or higher if using newer APIs); **compileSdk**: latest.
* **Kotlin, Jetpack Compose, Hilt** for DI.
* Add modules: `:core:ai`, `:core:design`, `:feature:chat`, `:feature:settings`.

**Gradle (root snippets)**

```gradle
plugins { id "com.android.application" version "<latest>"; id "org.jetbrains.kotlin.android" }
android { compileSdk <latest>; defaultConfig { minSdk 24; targetSdk <latest>; } }
```

---

## 5) Keys & backend proxy (critical)

**Never ship raw API keys in the APK.**

* Deploy a tiny **edge proxy** (Cloud Run / Functions / your backend) that:

  * Verifies app attestation (e.g., Play Integrity API / App Attest)
  * Exchanges a short-lived token for your AI provider request
  * Applies rate limits and logs **metadata only** (no prompts unless opted-in)
* The app requests a **short-lived token** and then calls the model.

---

## 6) Data & privacy

* **Local storage**: conversations in Room DB; toggle for **Erase after 24h**.
* **Exports**: share text/JSON on demand; redact by default.
* **No analytics by default**; if added, keep to coarse metrics and off by default.
* **Permissions**: microphone (for voice) is opt-in with clear explainer; no background mic.

---

## 7) Safety & consent

* **Pre-flight:** show consent sheet before enabling voice/biometrics; allow “Not now.”
* **Runtime:** if model or user input hits sensitive thresholds, **Offer Pause** / “Continue with context removed.”
* **Post-session:** surface what protections fired (transparency log stored locally).

---

## 8) UI (Compose) — minimal chat

```kotlin
@Composable
fun ChatScreen(vm: ChatViewModel = hiltViewModel()) {
  val state by vm.state.collectAsState()
  Column(Modifier.fillMaxSize().padding(16.dp)) {
    LazyColumn(Modifier.weight(1f)) {
      items(state.messages) { m -> MessageBubble(m) }
    }
    OutlinedTextField(
      value = state.input, onValueChange = vm::onInput,
      modifier = Modifier.fillMaxWidth(), label = { Text("Say something…") })
    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
      Button(onClick = vm::send) { Text("Send") }
    }
  }
}
```

**ViewModel sketch**

```kotlin
@HiltViewModel
class ChatViewModel @Inject constructor(
  private val llm: LLMClient,
  private val safety: SafetyInterceptor,
  private val repo: ChatRepository
) : ViewModel() {
  private val _state = MutableStateFlow(ChatState())
  val state: StateFlow<ChatState> = _state

  fun onInput(text: String) { _state.update { it.copy(input = text) } }

  fun send() = viewModelScope.launch {
    val userMsg = Message.user(_state.value.input)
    repo.append(userMsg)
    _state.update { it.copy(input = "") }

    llm.stream(userMsg, history = repo.history())
      .onEach { token -> repo.append(Message.assistant(token, streaming = true)) }
      .catch { e -> repo.append(Message.system("Error: ${e.message}")) }
      .onCompletion { repo.finalizeAssistantMessage() }
      .launchIn(this)
  }
}
```

---

## 9) LLM client (cloud) — outline

```kotlin
interface LLMClient {
  fun stream(
    userMsg: Message,
    history: List<Message>,
    cfg: ModelConfig = ModelConfig()
  ): Flow<String>
}
```

Implement with your provider’s SDK or plain HTTPS streaming (SSE/WS). Add:

* **retry/backoff**, **timeout**
* **token accounting** (max output tokens)
* **redaction hooks** (PPI filters) before sending

---

## 10) Testing & evaluation

* **Prompt regression tests:** use your AI Studio examples as test cases.
* **Unit tests:** repositories, safety interceptors, prompt templating.
* **UI tests:** Compose testing; ensure TalkBack labels present.
* **Offline tests:** verify graceful fallback when network unavailable.

---

## 11) Accessibility

* Compose **semantics** for screen readers, large tap targets, dynamic font scaling.
* Reduce motion setting respected; haptics optional.

---

## 12) Play Store compliance

* **Data safety form:** declare on-device storage; no sharing by default.
* **Sensitive permissions:** mic rationale and feature-level gate.
* **Generative AI disclosures:** clearly label AI output; provide reporting/feedback.
* **Privacy Policy URL:** even if local-first, publish a concise policy.

---

## 13) CI/CD

* GitHub Actions/GitLab: build, unit tests, lint, assemble release.
* Sign with Play App Signing; enable **versionCode** auto-bump.
* Generate an **OSS notices** file at build (Gradle task) and embed in the app.

---

## 14) Release checklist

* [ ] App icon & adaptive assets
* [ ] Splash + onboarding (consent, privacy)
* [ ] Settings: model selection (cloud / on-device), data retention, export/delete
* [ ] Licenses & Attributions screen (BSD-3 + third-party)
* [ ] Offline handling & empty states
* [ ] Backup/restore policy (opt-out of system backups if privacy-sensitive)
* [ ] Crash handling (user-visible, no silent uploads by default)

---

## 15) Phased rollout plan

* **Phase 1 — Local MVP:** text chat, cloud model via proxy, local history, safety prompts.
* **Phase 2 — Streaming + Voice:** token streaming UI, push-to-talk, basic TTS.
* **Phase 3 — On-device model option:** A/B with cloud, battery & latency profiling.
* **Phase 4 — Hardening:** instrumentation, accessibility audits, store listing.

---

## 16) Deliverables

* Android Studio project with modules above
* `docs/`:

  * `PROMPTS.md` (from AI Studio)
  * `SAFETY.md` (what’s blocked; thresholds)
  * `PRIVACY.md` (local-first statement)
  * `OSS_NOTICES.md` generation guide

---

## 17) Nice-to-have add-ons

* **Conversation export** (JSON/Markdown)
* **Devtools panel** (inspect prompts, latency, token counts)
* **Red team mode** (test safety triggers on device)

---

## 18) Risks & mitigations

* **Key abuse:** mitigate with proxy + attestation + rate-limits
* **Token cost spikes:** hard caps + warnings
* **SDK drift:** wrap provider API behind `LLMClient` interface
* **Store rejections:** proactive disclosures; minimal permissions

---

## 19) Minimal dependency list (pick equivalents if you prefer)

* Kotlin, Coroutines/Flow, Jetpack Compose, Hilt
* OkHttp/Retrofit (HTTP) or Ktor
* Room (local DB) + Security Crypto for encrypted files
* TTS/STT: Android Speech Services (optional)

---

### Appendix: Network call sketch (pseudocode HTTPS)

```kotlin
suspend fun LLMClientImpl.stream(...): Flow<String> = flow {
  val token = backend.getShortLivedToken()
  val req = Request.Builder()
    .url("https://<your-edge>/v1/chat:stream")
    .header("Authorization", "Bearer $token")
    .post(jsonBody(userMsg, history, cfg))
    .build()
  client.newCall(req).execute().use { resp ->
    resp.body?.source()?.let { src ->
      while (!src.exhausted()) emit(src.readUtf8LineStrict())
    }
  }
}
```

*This roadmap avoids provider-specific code so you can swap SDKs. When you choose the exact SDK (Gemini, etc.), we can drop in real dependencies and sample calls.*
