# cokice/japanese-analyzer architecture

> Architecture diagram of the GitHub repository cokice/japanese-analyzer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/cokice/japanese-analyzer
- Repository: https://github.com/cokice/japanese-analyzer

## Overview

#### Purpose and runtime
A Next.js 15 / React 19 application for Chinese learners to analyze Japanese sentences: token-level readings and grammar, Chinese translations, word explanations, OCR, TTS, and contextual AI chat. The primary browser entry is `app/page.tsx`; global shell/theme styling begins at `app/layout.tsx` and `app/globals.css`. It runs as a Node/Next server locally, in Docker, or on Vercel.

#### Client composition and interaction state
The page composes input, analysis output, translation, word-detail, and chat experiences from `app/components/InputSection.tsx`, `app/components/AnalysisResult.tsx`, `app/components/TranslationSection.tsx`, and `app/components/AIChat.tsx`. `app/components/SettingsModal.tsx` holds provider/model and user API-key choices in browser-local state; the server retains default keys. Clicked tokens drive the word-detail flow through `app/hooks/useWordDetail.ts` and `app/components/WordDetailPanel.tsx`.

#### Analysis pipeline
Sentence submission uses the client API layer at `app/services/api.ts` to invoke `app/api/analyze/route.ts`. The route is the central AI-backed analysis boundary: it selects a configured text provider/model, calls it through shared proxy/config mechanisms, and returns structured sentence analysis for rendering. Client-side Japanese segmentation and presentation transformations are supported by `app/utils/japaneseChunking.ts` and `app/utils/markdown.ts`.

#### Provider abstraction and AI service boundary
Provider resolution, default server credentials, user-supplied credentials, model choice, and endpoint URLs are centralized in `app/api/_utils/providerConfig.ts`; OpenAI-compatible upstream requests are brokered by `app/api/_utils/openaiProxy.ts`. Available model definitions are surfaced to the UI through `app/lib/aiModels.ts`. Text functions—including analysis, translation, word detail, reasoning summaries, and chat—are separate route boundaries at `app/api/analyze/route.ts`, `app/api/translate/route.ts`, and `app/api/chat/route.ts`, with Gemini and DeepSeek as external services.

#### Multimodal and speech stages
Image-to-text is isolated at `app/api/image-to-text/route.ts` and is Gemini-only. Speech generation is isolated at `app/api/tts/route.ts`, supporting Edge TTS by default and Gemini TTS when configured. Reasoning stream/summarization UI state is handled in `app/components/ReasoningStream.tsx` and `app/utils/reasoningSummary.ts`, backed by `app/api/reasoning-summary/route.ts`.

#### Access control and analytics
Optional password gating is implemented via `app/api/auth/route.ts` and server-side session checks in `app/api/_utils/sessionAuth.ts`, using the `CODE` environment variable. Optional Umami analytics is loaded through a local proxy endpoint at `app/api/umami/script/route.ts`; client event emission is in `app/utils/analytics.ts`. The design avoids sending input content or API keys in analytics events.

#### Deployment and infrastructure
Server defaults come from environment variables for DeepSeek, Gemini, optional access code, and Umami. Container deployment is defined by `Dockerfile`, `docker-compose.yml`, and `docker-compose.hub.yml`; Docker Hub CI is in `.github/workflows/docker.yml`. `vercel.json` supports Vercel deployment. External runtime dependencies are DeepSeek’s OpenAI-compatible API, Gemini’s OpenAI-compatible API, Edge TTS, and optionally a hosted Umami instance.

Main entry points: [`app/page.tsx`](https://github.com/cokice/japanese-analyzer/blob/master/app/page.tsx) (Learning workspace), [`app/services/api.ts`](https://github.com/cokice/japanese-analyzer/blob/master/app/services/api.ts) (Client API layer), [`app/api/_utils/providerConfig.ts`](https://github.com/cokice/japanese-analyzer/blob/master/app/api/_utils/providerConfig.ts) (Provider configuration), [`app/api/image-to-text/route.ts`](https://github.com/cokice/japanese-analyzer/blob/master/app/api/image-to-text/route.ts) (OCR and TTS)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Browser client"]
  node_shell["App shell and theme<br/>Next.js layout<br/>[layout.tsx]"]
  node_page["Learning workspace<br/>React page<br/>[page.tsx]"]
  node_input["Sentence input<br/>React component<br/>[InputSection.tsx]"]
  node_results["Analysis and translation<br/>React components<br/>[AnalysisResult.tsx]"]
  node_chat_ui["Contextual chat<br/>React component<br/>[AIChat.tsx]"]
  node_settings["Provider settings<br/>browser state<br/>[SettingsModal.tsx]"]
  node_word_detail["Word detail flow<br/>hook and panel<br/>[useWordDetail.ts]"]
  node_client_api["Client API layer<br/>API client<br/>[api.ts]"]
  node_reasoning_ui["Reasoning stream<br/>UI state"]
  node_analytics["Privacy-safe analytics<br/>client events<br/>[analytics.ts]"]
end

subgraph group_api["Next.js API"]
  node_analyze{{"Sentence analysis<br/>API route<br/>[route.ts]"}}
  node_text_routes{{"Translation and chat<br/>API routes<br/>[route.ts]"}}
  node_provider_config["Provider configuration<br/>server config<br/>[providerConfig.ts]"]
  node_proxy["OpenAI-compatible proxy<br/>upstream broker<br/>[openaiProxy.ts]"]
  node_multimodal{{"OCR and TTS<br/>API routes<br/>[route.ts]"}}
  node_auth["Optional access gate<br/>API and session auth<br/>[route.ts]"]
  node_umami_proxy["Umami script proxy<br/>API route<br/>[route.ts]"]
end

subgraph group_ai["AI providers"]
  node_providers(("DeepSeek and Gemini<br/>external AI APIs"))
  node_edge_tts(("Edge TTS<br/>external speech service"))
end

subgraph group_deploy["Deployment"]
  node_runtime["Next.js runtime<br/>Node deployment"]
  node_docker_ci["Docker Hub CI<br/>GitHub Actions<br/>[docker.yml]"]
  node_vercel["Vercel deployment<br/>deployment config<br/>[vercel.json]"]
end

node_shell -->|"hosts"| node_page
node_page -->|"composes"| node_input
node_page -->|"renders"| node_results
node_page -->|"composes"| node_chat_ui
node_page -->|"configures"| node_settings
node_results -->|"token clicks"| node_word_detail
node_input -->|"submits"| node_client_api
node_client_api -->|"analysis request"| node_analyze
node_client_api -->|"translation and chat"| node_text_routes
node_chat_ui -->|"shows reasoning"| node_reasoning_ui
node_settings -->|"supplies choices"| node_client_api
node_analyze -->|"selects provider"| node_provider_config
node_text_routes -->|"selects provider"| node_provider_config
node_provider_config -->|"configures"| node_proxy
node_proxy -->|"brokers requests"| node_providers
node_multimodal -->|"Gemini OCR/TTS"| node_providers
node_multimodal -->|"default speech"| node_edge_tts
node_auth -.->|"permits access"| node_page
node_analytics -->|"loads and emits"| node_umami_proxy
node_runtime -.->|"built and published"| node_docker_ci
node_vercel -.->|"deploys"| node_runtime

click node_shell "https://github.com/cokice/japanese-analyzer/blob/master/app/layout.tsx"
click node_page "https://github.com/cokice/japanese-analyzer/blob/master/app/page.tsx"
click node_input "https://github.com/cokice/japanese-analyzer/blob/master/app/components/InputSection.tsx"
click node_results "https://github.com/cokice/japanese-analyzer/blob/master/app/components/AnalysisResult.tsx"
click node_chat_ui "https://github.com/cokice/japanese-analyzer/blob/master/app/components/AIChat.tsx"
click node_settings "https://github.com/cokice/japanese-analyzer/blob/master/app/components/SettingsModal.tsx"
click node_word_detail "https://github.com/cokice/japanese-analyzer/blob/master/app/hooks/useWordDetail.ts"
click node_client_api "https://github.com/cokice/japanese-analyzer/blob/master/app/services/api.ts"
click node_reasoning_ui "https://github.com/cokice/japanese-analyzer/blob/master/app/components/ReasoningStream.tsx"
click node_analytics "https://github.com/cokice/japanese-analyzer/blob/master/app/utils/analytics.ts"
click node_analyze "https://github.com/cokice/japanese-analyzer/blob/master/app/api/analyze/route.ts"
click node_text_routes "https://github.com/cokice/japanese-analyzer/blob/master/app/api/translate/route.ts"
click node_provider_config "https://github.com/cokice/japanese-analyzer/blob/master/app/api/_utils/providerConfig.ts"
click node_proxy "https://github.com/cokice/japanese-analyzer/blob/master/app/api/_utils/openaiProxy.ts"
click node_multimodal "https://github.com/cokice/japanese-analyzer/blob/master/app/api/image-to-text/route.ts"
click node_auth "https://github.com/cokice/japanese-analyzer/blob/master/app/api/auth/route.ts"
click node_umami_proxy "https://github.com/cokice/japanese-analyzer/blob/master/app/api/umami/script/route.ts"
click node_runtime "https://github.com/cokice/japanese-analyzer/blob/master/Dockerfile"
click node_docker_ci "https://github.com/cokice/japanese-analyzer/blob/master/.github/workflows/docker.yml"
click node_vercel "https://github.com/cokice/japanese-analyzer/blob/master/vercel.json"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_shell,node_page,node_input,node_results,node_chat_ui,node_settings,node_word_detail,node_client_api,node_reasoning_ui,node_analytics toneBlue
class node_analyze,node_text_routes,node_provider_config,node_proxy,node_multimodal,node_auth,node_umami_proxy toneAmber
class node_providers,node_edge_tts toneMint
class node_runtime,node_docker_ci,node_vercel toneRose
```

## Components

### Browser client

- [App shell and theme](https://github.com/cokice/japanese-analyzer/blob/master/app/layout.tsx): Next.js layout · `app/layout.tsx`
- [Learning workspace](https://github.com/cokice/japanese-analyzer/blob/master/app/page.tsx): React page · Primary sentence-learning entry point. · `app/page.tsx`
- [Sentence input](https://github.com/cokice/japanese-analyzer/blob/master/app/components/InputSection.tsx): React component · `app/components/InputSection.tsx`
- [Analysis and translation](https://github.com/cokice/japanese-analyzer/blob/master/app/components/AnalysisResult.tsx): React components · `app/components/AnalysisResult.tsx`
- [Contextual chat](https://github.com/cokice/japanese-analyzer/blob/master/app/components/AIChat.tsx): React component · `app/components/AIChat.tsx`
- [Provider settings](https://github.com/cokice/japanese-analyzer/blob/master/app/components/SettingsModal.tsx): browser state · Stores model and user API-key choices locally. · `app/components/SettingsModal.tsx`
- [Word detail flow](https://github.com/cokice/japanese-analyzer/blob/master/app/hooks/useWordDetail.ts): hook and panel · Clicked tokens open word explanations. · `app/hooks/useWordDetail.ts`
- [Client API layer](https://github.com/cokice/japanese-analyzer/blob/master/app/services/api.ts): API client · `app/services/api.ts`
- [Reasoning stream](https://github.com/cokice/japanese-analyzer/blob/master/app/components/ReasoningStream.tsx): UI state · `app/components/ReasoningStream.tsx`
- [Privacy-safe analytics](https://github.com/cokice/japanese-analyzer/blob/master/app/utils/analytics.ts): client events · Excludes input content and API keys. · `app/utils/analytics.ts`

### Next.js API

- [Sentence analysis](https://github.com/cokice/japanese-analyzer/blob/master/app/api/analyze/route.ts): API route · Central structured AI analysis boundary. · `app/api/analyze/route.ts`
- [Translation and chat](https://github.com/cokice/japanese-analyzer/blob/master/app/api/translate/route.ts): API routes · Separate text-function route boundaries. · `app/api/translate/route.ts`
- [Provider configuration](https://github.com/cokice/japanese-analyzer/blob/master/app/api/_utils/providerConfig.ts): server config · Resolves credentials, models, and upstream endpoints. · `app/api/_utils/providerConfig.ts`
- [OpenAI-compatible proxy](https://github.com/cokice/japanese-analyzer/blob/master/app/api/_utils/openaiProxy.ts): upstream broker · `app/api/_utils/openaiProxy.ts`
- [OCR and TTS](https://github.com/cokice/japanese-analyzer/blob/master/app/api/image-to-text/route.ts): API routes · Gemini OCR; Edge or Gemini speech generation. · `app/api/image-to-text/route.ts`
- [Optional access gate](https://github.com/cokice/japanese-analyzer/blob/master/app/api/auth/route.ts): API and session auth · Checks CODE-backed server sessions. · `app/api/auth/route.ts`
- [Umami script proxy](https://github.com/cokice/japanese-analyzer/blob/master/app/api/umami/script/route.ts): API route · `app/api/umami/script/route.ts`

### AI providers

- **DeepSeek and Gemini**: external AI APIs · OpenAI-compatible text services; Gemini also provides OCR and optional TTS.
- **Edge TTS**: external speech service

### Deployment

- [Next.js runtime](https://github.com/cokice/japanese-analyzer/blob/master/Dockerfile): Node deployment · Runs locally, in Docker, or on Vercel. · `Dockerfile`
- [Docker Hub CI](https://github.com/cokice/japanese-analyzer/blob/master/.github/workflows/docker.yml): GitHub Actions · `.github/workflows/docker.yml`
- [Vercel deployment](https://github.com/cokice/japanese-analyzer/blob/master/vercel.json): deployment config · `vercel.json`

## Connections

- App shell and theme → Learning workspace: hosts
- Learning workspace → Sentence input: composes
- Learning workspace → Analysis and translation: renders
- Learning workspace → Contextual chat: composes
- Learning workspace → Provider settings: configures
- Analysis and translation → Word detail flow: token clicks
- Sentence input → Client API layer: submits
- Client API layer → Sentence analysis: analysis request
- Client API layer → Translation and chat: translation and chat
- Contextual chat → Reasoning stream: shows reasoning
- Provider settings → Client API layer: supplies choices
- Sentence analysis → Provider configuration: selects provider
- Translation and chat → Provider configuration: selects provider
- Provider configuration → OpenAI-compatible proxy: configures
- OpenAI-compatible proxy → DeepSeek and Gemini: brokers requests
- OCR and TTS → DeepSeek and Gemini: Gemini OCR/TTS
- OCR and TTS → Edge TTS: default speech
- Optional access gate → Learning workspace: permits access
- Privacy-safe analytics → Umami script proxy: loads and emits
- Next.js runtime → Docker Hub CI: built and published
- Vercel deployment → Next.js runtime: deploys
