# xiaoran132/story-editor architecture

> Architecture diagram of the GitHub repository xiaoran132/story-editor, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/xiaoran132/story-editor
- Repository: https://github.com/xiaoran132/story-editor

## Overview

Story Editor is an AI-powered interactive-fiction platform with two implemented user journeys: authors generate and refine a story before publishing; players stream generated turns, make choices, and revisit branches. Go is the business and persistence boundary, while the Python Agent generates narrative output using per-request LLM settings supplied by Go. The README documents the main capabilities and service boundaries; some internal wiring is inferred only where that documentation is explicit, since most handler and graph source was not sampled.

Main entry points: [`backend/main.go`](https://github.com/xiaoran132/story-editor/blob/main/backend/main.go) (HTTP routes), [`agent/app/graph/story_graph.py`](https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py) (Generation pipeline), [`backend/internal/repository`](https://github.com/xiaoran132/story-editor/tree/main/backend/internal/repository) (Repositories), [`backend/internal/service/play.go`](https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/play.go) (Play service)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web experience"]
  node_web["Next.js application"]
  node_editor["Story editor<br/>[StoryEditor.tsx]"]
  node_playui["Play interface"]
  node_authstore["Login state<br/>[authStore.ts]"]
  node_api["API client<br/>[api.ts]"]
end

subgraph group_backend["Go application"]
  node_routes["HTTP routes<br/>[main.go]"]
  node_auth["JWT middleware<br/>[auth.go]"]
  node_storysvc["Story service<br/>[story.go]"]
  node_playsvc["Play service<br/>[play.go]"]
  node_llmsvc["LLM settings and billing<br/>[llm.go]"]
  node_agentclient["Agent client<br/>[agent_client.go]"]
  node_repositories["Repositories"]
end

subgraph group_agent["AI generation"]
  node_pipeline["Generation pipeline<br/>[story_graph.py]"]
  node_writer["Streaming writer<br/>[story_graph.py]"]
  node_structurer["Turn structurer<br/>[story_graph.py]"]
  node_review["Optional review<br/>[story_graph.py]"]
end

subgraph group_integrations["Data and models"]
  node_postgres[("PostgreSQL")]
  node_llm{{"OpenAI-compatible LLM"}}
end

node_author(("Author or player"))

node_author -->|"uses"| node_web
node_web -->|"manages login"| node_authstore
node_editor -->|"requests authoring"| node_api
node_playui -->|"requests turns"| node_api
node_api -->|"calls API"| node_routes
node_routes -->|"protects routes"| node_auth
node_routes -->|"dispatches story"| node_storysvc
node_routes -->|"dispatches play"| node_playsvc
node_routes -->|"dispatches LLM settings"| node_llmsvc
node_storysvc -->|"reads and writes"| node_repositories
node_playsvc -->|"reads and writes"| node_repositories
node_llmsvc -->|"reads and writes"| node_repositories
node_repositories -->|"persists data"| node_postgres
node_playsvc -->|"requests generation"| node_agentclient
node_agentclient -->|"sends requests"| node_pipeline
node_pipeline -->|"streams prose"| node_writer
node_pipeline -->|"generates turn data"| node_structurer
node_pipeline -.->|"may invoke"| node_review
node_writer -->|"generates text"| node_llm
node_structurer -->|"generates metadata"| node_llm
node_review -.->|"checks output"| node_llm
node_llmsvc -->|"tests and probes"| node_llm
node_agentclient -->|"streams SSE"| node_playui

click node_web "https://github.com/xiaoran132/story-editor/tree/main/frontend/src/app"
click node_editor "https://github.com/xiaoran132/story-editor/blob/main/frontend/src/components/editor/StoryEditor.tsx"
click node_playui "https://github.com/xiaoran132/story-editor/tree/main/frontend/src/components/play"
click node_authstore "https://github.com/xiaoran132/story-editor/blob/main/frontend/src/store/authStore.ts"
click node_api "https://github.com/xiaoran132/story-editor/blob/main/frontend/src/lib/api.ts"
click node_routes "https://github.com/xiaoran132/story-editor/blob/main/backend/main.go"
click node_auth "https://github.com/xiaoran132/story-editor/blob/main/backend/internal/middleware/auth.go"
click node_storysvc "https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/story.go"
click node_playsvc "https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/play.go"
click node_llmsvc "https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/llm.go"
click node_agentclient "https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/agent_client.go"
click node_repositories "https://github.com/xiaoran132/story-editor/tree/main/backend/internal/repository"
click node_pipeline "https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py"
click node_writer "https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py"
click node_structurer "https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py"
click node_review "https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py"

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_web,node_editor,node_playui,node_authstore,node_api toneBlue
class node_routes,node_auth,node_storysvc,node_playsvc,node_llmsvc,node_agentclient,node_repositories toneAmber
class node_pipeline,node_writer,node_structurer,node_review toneMint
class node_postgres,node_llm toneRose
class node_author toneIndigo
```

## Components

### Web experience

- [Next.js application](https://github.com/xiaoran132/story-editor/tree/main/frontend/src/app): `frontend/src/app`
- [Story editor](https://github.com/xiaoran132/story-editor/blob/main/frontend/src/components/editor/StoryEditor.tsx): `frontend/src/components/editor/StoryEditor.tsx`
- [Play interface](https://github.com/xiaoran132/story-editor/tree/main/frontend/src/components/play): `frontend/src/components/play`
- [Login state](https://github.com/xiaoran132/story-editor/blob/main/frontend/src/store/authStore.ts): `frontend/src/store/authStore.ts`
- [API client](https://github.com/xiaoran132/story-editor/blob/main/frontend/src/lib/api.ts): `frontend/src/lib/api.ts`

### Go application

- [HTTP routes](https://github.com/xiaoran132/story-editor/blob/main/backend/main.go): `backend/main.go`
- [JWT middleware](https://github.com/xiaoran132/story-editor/blob/main/backend/internal/middleware/auth.go): `backend/internal/middleware/auth.go`
- [Story service](https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/story.go): `backend/internal/service/story.go`
- [Play service](https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/play.go): `backend/internal/service/play.go`
- [LLM settings and billing](https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/llm.go): `backend/internal/service/llm.go`
- [Agent client](https://github.com/xiaoran132/story-editor/blob/main/backend/internal/service/agent_client.go): `backend/internal/service/agent_client.go`
- [Repositories](https://github.com/xiaoran132/story-editor/tree/main/backend/internal/repository): `backend/internal/repository`

### AI generation

- [Generation pipeline](https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py): `agent/app/graph/story_graph.py`
- [Streaming writer](https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py): `agent/app/graph/story_graph.py`
- [Turn structurer](https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py): `agent/app/graph/story_graph.py`
- [Optional review](https://github.com/xiaoran132/story-editor/blob/main/agent/app/graph/story_graph.py): `agent/app/graph/story_graph.py`

### Data and models

- **PostgreSQL**
- **OpenAI-compatible LLM**

### Other components

- **Author or player**

## Connections

- Author or player → Next.js application: uses
- Next.js application → Login state: manages login
- Story editor → API client: requests authoring
- Play interface → API client: requests turns
- API client → HTTP routes: calls API
- HTTP routes → JWT middleware: protects routes
- HTTP routes → Story service: dispatches story
- HTTP routes → Play service: dispatches play
- HTTP routes → LLM settings and billing: dispatches LLM settings
- Story service → Repositories: reads and writes
- Play service → Repositories: reads and writes
- LLM settings and billing → Repositories: reads and writes
- Repositories → PostgreSQL: persists data
- Play service → Agent client: requests generation
- Agent client → Generation pipeline: sends requests
- Generation pipeline → Streaming writer: streams prose
- Generation pipeline → Turn structurer: generates turn data
- Generation pipeline → Optional review: may invoke
- Streaming writer → OpenAI-compatible LLM: generates text
- Turn structurer → OpenAI-compatible LLM: generates metadata
- Optional review → OpenAI-compatible LLM: checks output
- LLM settings and billing → OpenAI-compatible LLM: tests and probes
- Agent client → Play interface: streams SSE
