# nitianji415/tj-sylva architecture

> Architecture diagram of the GitHub repository nitianji415/tj-sylva, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-24). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nitianji415/tj-sylva
- Repository: https://github.com/nitianji415/tj-sylva

## Overview

1. **Overall shape**
   This repo is a single Python application that bundles a backend API and a static browser UI. The backend is a FastAPI service; the frontend is plain HTML/CSS/JS served from `static/`. The core product concept is a “left-side AI conversation + right-side growing knowledge tree” workflow.

2. **Primary runtime boundary**
   Requests enter through FastAPI in `app/main.py`, with route modules in `app/routers/` splitting the API by domain: auth, sessions, messages, nodes, prompts, settings, web search, and health. `app.py` / `server.py` are convenience entrypoints for local launch, while Docker runs the same app inside the `app` service.

3. **Layering inside the backend**
   The backend is organized in a fairly standard API → service → persistence stack:
   - `app/routers/*` handles HTTP/SSE endpoints and auth guards
   - `app/services/*` contains business logic and external integrations
   - `app/db/models.py` defines SQLAlchemy ORM entities
   - `app/schemas/*` defines request/response contracts
   - `app/core/*` holds config and SSE helpers  
   This is the main boundary to preserve if drawing the architecture.

4. **Core domain subsystem: knowledge growth**
   `app/services/knowledge.py` is the central orchestration layer. It manages the learning loop that creates sessions, streams assistant replies, grows tree nodes, subdivides topics, and keeps messages/nodes in sync. The README and routes indicate that session creation can also generate an initial “knowledge map,” so the session is not just chat history; it is the root container for the tree.

5. **Data model and persistence**
   The persistent model is PostgreSQL by default, with Alembic migrations under `alembic/versions/`. The main entities implied by the routes and migrations are sessions, messages, nodes, prompts, settings, peeks, and LLM usage/events. Structural evolution is important here: features like collapsed nodes, prerequisite IDs, highlights, search sources, context summary, and usage tracking were added incrementally via migrations.

6. **LLM integration boundary**
   `app/services/ai.py` is the single LLM client wrapper. The project intentionally uses one OpenAI Chat Completions–compatible interface, so provider changes happen via `LLM_BASE_URL` rather than code changes. If the model call fails, the system falls back to local logic in `app/services/topics.py`, which is important architecturally because the app remains usable even when the LLM path is degraded.

7. **Search subsystem**
   Web search is separate from the LLM path. `app/services/web_search.py` and `app/services/web_search_daemon.py` talk to a local `open-webSearch` daemon by default, with `anysearch` as an alternate provider and `off` as a full disable. This means search is an external capability with its own service boundary, not embedded in the main app process.

8. **Authentication and settings**
   Auth is JWT-based through `app/services/auth.py` and `app/routers/auth.py`. Runtime settings are editable by admins via `app/routers/settings.py`, and sensitive values such as LLM API keys are encrypted before being stored in the database. `SETTINGS_SECRET`, `JWT_SECRET`, and `ADMIN_PASSWORD` are therefore architectural secrets, not just configuration details.

9. **UI interaction model**
   The frontend is not a separate SPA framework; it is a server-served static client in `static/` that talks to the API directly. The user experience depends heavily on streaming responses: `app/core/sse.py` and the message/session streaming routes support token-like live updates and progressive tree growth, rather than a request/response-only flow.

10. **Domain features exposed through routes**
    The route surface maps closely to product features:
    - sessions: create, list, preview topics, grow children, fetch tree/messages
    - messages: stream answers, peeks, follow-up questions
    - nodes: edit status, collapse state, and subdivision actions
    - prompts/settings: tune model behavior and runtime defaults
    - web search: query external search sources  
    This is useful for a diagram because each route group corresponds to a visible user workflow.

11. **Deployment topology**
    The Docker Compose setup defines three services: `app`, `postgres`, and `open-websearch`. The app listens on port `8765` and serves both backend API and frontend assets. The search daemon is optional in development but is part of the default Docker-based production topology.

12. **Testing and operational support**
    Tests under `tests/` cover health, sessions, nodes, peeks, intent/search query behavior, and context optimization, indicating the system is organized around end-user learning flows rather than generic CRUD. There is also a migration script for moving an old SQLite dataset into Postgres, showing the project has a real persistence upgrade path and not just greenfield storage.

13. **What to emphasize in a diagram**
    A good architecture diagram for this repo should center on: browser UI → FastAPI routes → service layer → PostgreSQL, with side integrations to the LLM provider and the search daemon. The most important internal seam is that the service layer owns business logic, while routers stay thin and schemas enforce the API contract.

Main entry points: [`app/main.py`](https://github.com/nitianji415/tj-sylva/blob/main/app/main.py) (FastAPI App), [`app/services/knowledge.py`](https://github.com/nitianji415/tj-sylva/blob/main/app/services/knowledge.py) (Knowledge), [`app/db/models.py`](https://github.com/nitianji415/tj-sylva/blob/main/app/db/models.py) (ORM Models), [`app/routers/sessions.py`](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/sessions.py) (Sessions)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client"]
  node_static_index["Browser UI<br/>static client<br/>[index.html]"]
  node_static_appjs["UI Logic<br/>frontend script<br/>[app.js]"]
end

subgraph group_api["API"]
  node_main_app["FastAPI App<br/>api entrypoint<br/>[main.py]"]
  node_router_sessions["Sessions<br/>route module<br/>[sessions.py]"]
  node_router_messages["Messages<br/>route module<br/>[messages.py]"]
  node_router_nodes["Nodes<br/>route module<br/>[nodes.py]"]
  node_router_prompts["Prompts<br/>route module<br/>[prompts.py]"]
  node_router_settings["Settings<br/>route module<br/>[settings.py]"]
  node_router_auth["Auth<br/>route module<br/>[auth.py]"]
  node_router_search["Web Search<br/>route module<br/>[web_search.py]"]
  node_router_health["Health<br/>route module<br/>[health.py]"]
  node_schemas["API Schemas<br/>pydantic schemas<br/>[session.py]"]
  node_core_config["Config<br/>[config.py]"]
  node_core_sse["SSE<br/>stream helper<br/>[sse.py]"]
end

subgraph group_domain["Domain"]
  node_svc_knowledge{{"Knowledge<br/>orchestrator<br/>[knowledge.py]"}}
  node_svc_ai["LLM Client<br/>llm adapter<br/>[ai.py]"]
  node_svc_topics["Topic Fallback<br/>local reasoning<br/>[topics.py]"]
  node_svc_auth["Auth Service<br/>jwt service<br/>[auth.py]"]
  node_svc_websearch["Search Service<br/>search adapter<br/>[web_search.py]"]
end

subgraph group_persistence["Persistence"]
  node_db_models[("ORM Models<br/>sqlalchemy models<br/>[models.py]")]
  node_alembic_versions["Migrations"]
end

subgraph group_integrations["Integrations"]
  node_svc_wsdaemon["Search Daemon<br/>daemon client"]
end

subgraph group_deploy["Deploy"]
  node_compose["Compose Stack<br/>deployment<br/>[docker-compose.yml]"]
  node_migrate_script["SQLite Migrator<br/>ops script"]
end

node_static_index -->|"loads"| node_static_appjs
node_static_appjs -->|"calls API"| node_main_app
node_main_app -->|"mounts"| node_router_sessions
node_main_app -->|"mounts"| node_router_messages
node_main_app -->|"mounts"| node_router_nodes
node_main_app -->|"mounts"| node_router_prompts
node_main_app -->|"mounts"| node_router_settings
node_main_app -->|"mounts"| node_router_auth
node_main_app -->|"mounts"| node_router_search
node_main_app -->|"mounts"| node_router_health
node_router_sessions -->|"orchestrates"| node_svc_knowledge
node_router_messages -->|"streams through"| node_svc_knowledge
node_router_nodes -->|"mutates tree"| node_svc_knowledge
node_router_prompts -->|"validates"| node_schemas
node_router_settings -->|"validates"| node_schemas
node_router_auth -->|"delegates"| node_svc_auth
node_router_search -->|"delegates"| node_svc_websearch
node_svc_knowledge -->|"uses"| node_svc_ai
node_svc_knowledge -.->|"fallbacks to"| node_svc_topics
node_svc_knowledge -->|"persists"| node_db_models
node_svc_auth -->|"stores users"| node_db_models
node_svc_websearch -->|"queries"| node_svc_wsdaemon
node_router_sessions -->|"streams"| node_core_sse
node_router_messages -->|"streams"| node_core_sse
node_db_models -->|"evolved by"| node_alembic_versions
node_main_app -->|"reads config"| node_core_config
node_compose -->|"runs"| node_main_app
node_compose -->|"runs"| node_svc_wsdaemon
node_migrate_script -.->|"transfers data"| node_db_models

click node_static_index "https://github.com/nitianji415/tj-sylva/blob/main/static/index.html"
click node_static_appjs "https://github.com/nitianji415/tj-sylva/blob/main/static/app.js"
click node_main_app "https://github.com/nitianji415/tj-sylva/blob/main/app/main.py"
click node_router_sessions "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/sessions.py"
click node_router_messages "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/messages.py"
click node_router_nodes "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/nodes.py"
click node_router_prompts "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/prompts.py"
click node_router_settings "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/settings.py"
click node_router_auth "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/auth.py"
click node_router_search "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/web_search.py"
click node_router_health "https://github.com/nitianji415/tj-sylva/blob/main/app/routers/health.py"
click node_svc_knowledge "https://github.com/nitianji415/tj-sylva/blob/main/app/services/knowledge.py"
click node_svc_ai "https://github.com/nitianji415/tj-sylva/blob/main/app/services/ai.py"
click node_svc_topics "https://github.com/nitianji415/tj-sylva/blob/main/app/services/topics.py"
click node_svc_auth "https://github.com/nitianji415/tj-sylva/blob/main/app/services/auth.py"
click node_svc_websearch "https://github.com/nitianji415/tj-sylva/blob/main/app/services/web_search.py"
click node_svc_wsdaemon "https://github.com/nitianji415/tj-sylva/blob/main/app/services/web_search_daemon.py"
click node_db_models "https://github.com/nitianji415/tj-sylva/blob/main/app/db/models.py"
click node_alembic_versions "https://github.com/nitianji415/tj-sylva/blob/main/alembic/versions/20260517_0001_initial.py"
click node_schemas "https://github.com/nitianji415/tj-sylva/blob/main/app/schemas/session.py"
click node_core_config "https://github.com/nitianji415/tj-sylva/blob/main/app/core/config.py"
click node_core_sse "https://github.com/nitianji415/tj-sylva/blob/main/app/core/sse.py"
click node_compose "https://github.com/nitianji415/tj-sylva/blob/main/docker-compose.yml"
click node_migrate_script "https://github.com/nitianji415/tj-sylva/blob/main/scripts/migrate_sqlite_to_postgres.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_static_index,node_static_appjs toneBlue
class node_main_app,node_router_sessions,node_router_messages,node_router_nodes,node_router_prompts,node_router_settings,node_router_auth,node_router_search,node_router_health,node_schemas,node_core_config,node_core_sse toneAmber
class node_svc_knowledge,node_svc_ai,node_svc_topics,node_svc_auth,node_svc_websearch toneMint
class node_db_models,node_alembic_versions toneRose
class node_svc_wsdaemon toneIndigo
class node_compose,node_migrate_script toneTeal
```

## Components

### Client

Static browser UI served by the app

- [Browser UI](https://github.com/nitianji415/tj-sylva/blob/main/static/index.html): static client · Served HTML entrypoint for the browser interface · `static/index.html`
- [UI Logic](https://github.com/nitianji415/tj-sylva/blob/main/static/app.js): frontend script · Client-side interaction layer for the static UI · `static/app.js`

### API

FastAPI entrypoint and route layer

- [FastAPI App](https://github.com/nitianji415/tj-sylva/blob/main/app/main.py): api entrypoint · Application startup and router wiring · `app/main.py`
- [Sessions](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/sessions.py): route module · Session creation, tree access, and session workflow endpoints · `app/routers/sessions.py`
- [Messages](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/messages.py): route module · Streaming replies, peeks, and follow-up message endpoints · `app/routers/messages.py`
- [Nodes](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/nodes.py): route module · Node editing, collapse state, and subdivision actions · `app/routers/nodes.py`
- [Prompts](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/prompts.py): route module · Prompt template and model-behavior endpoints · `app/routers/prompts.py`
- [Settings](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/settings.py): route module · Admin runtime settings endpoints · `app/routers/settings.py`
- [Auth](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/auth.py): route module · JWT login and auth endpoints · `app/routers/auth.py`
- [Web Search](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/web_search.py): route module · Search query endpoints and search-provider access · `app/routers/web_search.py`
- [Health](https://github.com/nitianji415/tj-sylva/blob/main/app/routers/health.py): route module · Service liveness and readiness endpoint · `app/routers/health.py`
- [API Schemas](https://github.com/nitianji415/tj-sylva/blob/main/app/schemas/session.py): pydantic schemas · Request and response contracts shared across routes · `app/schemas/session.py`
- [Config](https://github.com/nitianji415/tj-sylva/blob/main/app/core/config.py): runtime config · Environment-backed settings and secrets · `app/core/config.py`
- [SSE](https://github.com/nitianji415/tj-sylva/blob/main/app/core/sse.py): stream helper · Server-sent events helpers for live response streaming · `app/core/sse.py`

### Domain

Business logic and external capability adapters

- [Knowledge](https://github.com/nitianji415/tj-sylva/blob/main/app/services/knowledge.py): orchestrator · Core learning loop that streams answers and grows the tree · `app/services/knowledge.py`
- [LLM Client](https://github.com/nitianji415/tj-sylva/blob/main/app/services/ai.py): llm adapter · Chat-completions compatible model wrapper · `app/services/ai.py`
- [Topic Fallback](https://github.com/nitianji415/tj-sylva/blob/main/app/services/topics.py): local reasoning · Local topic and subdivision logic when LLM calls degrade · `app/services/topics.py`
- [Auth Service](https://github.com/nitianji415/tj-sylva/blob/main/app/services/auth.py): jwt service · JWT issuing and validation logic · `app/services/auth.py`
- [Search Service](https://github.com/nitianji415/tj-sylva/blob/main/app/services/web_search.py): search adapter · Search orchestration and provider selection · `app/services/web_search.py`

### Persistence

ORM models and database schema evolution

- [ORM Models](https://github.com/nitianji415/tj-sylva/blob/main/app/db/models.py): sqlalchemy models · Persistent entities for sessions, messages, nodes, prompts, settings, and usage · `app/db/models.py`
- [Migrations](https://github.com/nitianji415/tj-sylva/blob/main/alembic/versions/20260517_0001_initial.py): schema migrations · Database evolution for new learning and search features · `alembic/versions/20260517_0001_initial.py`

### Integrations

External providers and optional daemons

- [Search Daemon](https://github.com/nitianji415/tj-sylva/blob/main/app/services/web_search_daemon.py): daemon client · Client for the local open-websearch daemon · `app/services/web_search_daemon.py`

### Deploy

Container and migration support

- [Compose Stack](https://github.com/nitianji415/tj-sylva/blob/main/docker-compose.yml): deployment · App, Postgres, and search daemon runtime topology · `docker-compose.yml`
- [SQLite Migrator](https://github.com/nitianji415/tj-sylva/blob/main/scripts/migrate_sqlite_to_postgres.py): ops script · Utility for moving legacy SQLite data into PostgreSQL · `scripts/migrate_sqlite_to_postgres.py`

## Connections

- Browser UI → UI Logic: loads · The browser shell is driven by client-side JavaScript
- UI Logic → FastAPI App: calls API · The UI talks directly to the FastAPI backend
- FastAPI App → Sessions: mounts · Session routes are registered under the application
- FastAPI App → Messages: mounts · Message routes are registered under the application
- FastAPI App → Nodes: mounts · Node routes are registered under the application
- FastAPI App → Prompts: mounts · Prompt routes are registered under the application
- FastAPI App → Settings: mounts · Settings routes are registered under the application
- FastAPI App → Auth: mounts · Auth routes are registered under the application
- FastAPI App → Web Search: mounts · Web search routes are registered under the application
- FastAPI App → Health: mounts · Health routes are registered under the application
- Sessions → Knowledge: orchestrates · Session endpoints delegate to the knowledge-growth workflow
- Messages → Knowledge: streams through · Message endpoints trigger the learning loop and live updates
- Nodes → Knowledge: mutates tree · Node actions are coordinated through the knowledge subsystem
- Prompts → API Schemas: validates · Prompt routes use shared API contracts
- Settings → API Schemas: validates · Settings routes use shared API contracts
- Auth → Auth Service: delegates · Auth routes delegate login and token handling
- Web Search → Search Service: delegates · Search routes forward queries to the search adapter
- Knowledge → LLM Client: uses · Primary path for model-driven responses
- Knowledge → Topic Fallback: fallbacks to · Local logic keeps the workflow usable when model calls fail
- Knowledge → ORM Models: persists · Knowledge growth reads and writes sessions, messages, and nodes
- Auth Service → ORM Models: stores users · Auth state depends on persisted account and secret data
- Search Service → Search Daemon: queries · Search service talks to the external daemon/provider boundary
- Sessions → SSE: streams · Session APIs use SSE for progressive updates
- Messages → SSE: streams · Message APIs emit live assistant events
- ORM Models → Migrations: evolved by · Schema changes are captured through migrations
- FastAPI App → Config: reads config · Application startup depends on runtime settings
- Compose Stack → FastAPI App: runs · Containerized app service launches the FastAPI process
- Compose Stack → Search Daemon: runs · Compose includes the optional search daemon
- SQLite Migrator → ORM Models: transfers data · Legacy SQLite data is reshaped into the current schema
