# space-aditya/go_todo architecture

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

- Interactive diagram: https://gitdiagram.com/space-aditya/go_todo
- Repository: https://github.com/space-aditya/go_todo

## Overview

1. **Overall shape**
   - This is a two-tier todo application: a Go backend serves both the API and the built frontend assets, and a React/Vite SPA provides the UI.
   - Persistent state is stored in PostgreSQL in production, with an in-memory store available for simpler or test-style execution.

2. **Backend entrypoint and runtime**
   - The server starts from `cmd/server/main.go`.
   - The backend is a single Go process that owns HTTP routing, middleware, request handling, store selection, and static asset serving.

3. **HTTP/API boundary**
   - `internal/handler` contains the HTTP layer for todo operations.
   - This layer translates incoming requests into store calls and returns JSON/error responses; it is the boundary between transport concerns and domain/storage concerns.

4. **Middleware boundary**
   - `internal/middleware` holds cross-cutting HTTP behavior.
   - This is where request-level concerns such as logging, recovery, CORS, or similar wrapping behavior are centralized rather than duplicated in handlers.

5. **Domain model**
   - `internal/model` defines the core todo types and application errors.
   - The todo model is the shared contract between handlers, stores, and the frontend API shape.

6. **Storage abstraction**
   - `internal/store/store.go` defines the store interface used by the handlers.
   - There are two concrete implementations:
     - `internal/store/memory.go` for an in-process, non-persistent backend
     - `internal/store/postgres.go` for production persistence

7. **Persistence path**
   - In the PostgreSQL path, handlers call the store interface, which executes SQL against the database.
   - The schema is managed separately under `migrations/`, with at least one migration creating the todos table.

8. **Frontend application**
   - `internal/frontend` is a full React 19 + Vite application, with source under `src/` and a production build in `dist/`.
   - The frontend is componentized into form/list/item pieces and uses a custom hook plus API module to fetch and mutate todos.

9. **Frontend-to-backend data flow**
   - The React app does not talk to the database directly.
   - It calls backend HTTP endpoints through `internal/frontend/src/api/todos.ts`, and state is orchestrated in `useTodos.ts`, then rendered by `App.tsx` and the todo components.

10. **Frontend asset embedding**
   - `internal/frontend_embed.go` indicates the built frontend is embedded into the Go binary.
   - This means the same backend process can serve the SPA assets in production without a separate static server.

11. **Deployment model**
   - `Dockerfile` uses a multi-stage build: it builds the frontend, compiles the Go server, and packages both together.
   - `docker-compose.yml` wires the app together with PostgreSQL for a production-like local environment.

12. **Configuration and environment**
   - The README notes the backend is driven by environment variables such as `DATABASE_URL`, `LISTEN_ADDR`, and `APP_ENV`.
   - That suggests the runtime behavior changes based on deployment context, especially store selection and server binding.

13. **Testing boundaries**
   - Tests exist for handlers, middleware, model, and both store implementations.
   - This implies clear separation of concerns: HTTP behavior, domain validation/error handling, and persistence logic are each testable in isolation.

14. **Diagram-worthy summary**
   - The key architecture diagram should show: browser SPA → Go HTTP handlers → store interface → Postgres or memory store → database, with middleware wrapping the HTTP layer and embedded frontend assets served from the same backend process.

Main entry points: [`internal/frontend/src/App.tsx`](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/App.tsx) (App), [`internal/handler/handler.go`](https://github.com/space-aditya/go_todo/blob/main/internal/handler/handler.go) (Handlers), [`internal/store/store.go`](https://github.com/space-aditya/go_todo/blob/main/internal/store/store.go) (Store API), [`cmd/server/main.go`](https://github.com/space-aditya/go_todo/blob/main/cmd/server/main.go) (Server)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Frontend"]
  node_spa_main["SPA Entry<br/>react entry<br/>[main.tsx]"]
  node_app["App<br/>react shell<br/>[App.tsx]"]
  node_use_todos["useTodos<br/>state hook<br/>[useTodos.ts]"]
  node_todos_api["Todos API<br/>http client<br/>[todos.ts]"]
  node_todo_form["Todo Form<br/>ui component<br/>[TodoForm.tsx]"]
  node_todo_list["Todo List<br/>ui component<br/>[TodoList.tsx]"]
  node_todo_item["Todo Item<br/>ui component<br/>[TodoItem.tsx]"]
end

node_browser(("Browser<br/>client"))
node_server_main["Server<br/>go entrypoint<br/>[main.go]"]
node_middleware["Middleware<br/>http cross-cutting<br/>[middleware.go]"]
node_handler["Handlers<br/>http api<br/>[handler.go]"]
node_model["Model<br/>domain types<br/>[todo.go]"]
node_store_iface["Store API<br/>storage interface<br/>[store.go]"]
node_memory_store[("Memory Store<br/>in-memory storage<br/>[memory.go]")]
node_postgres_store[("Postgres Store<br/>sql persistence<br/>[postgres.go]")]
node_migrations["Migrations<br/>schema SQL"]
node_db[("PostgreSQL<br/>database")]
node_frontend_embed["Embed Assets<br/>go embed<br/>[frontend_embed.go]"]

node_browser -->|"loads SPA"| node_spa_main
node_spa_main -->|"renders"| node_app
node_app -->|"state"| node_use_todos
node_app -->|"composes"| node_todo_form
node_app -->|"composes"| node_todo_list
node_todo_list -->|"uses"| node_todo_item
node_use_todos -->|"calls"| node_todos_api
node_todos_api -->|"HTTP"| node_handler
node_server_main -->|"wraps"| node_middleware
node_server_main -->|"routes"| node_handler
node_middleware -.->|"wraps"| node_handler
node_handler -->|"uses"| node_store_iface
node_store_iface -->|"implements"| node_memory_store
node_store_iface -->|"implements"| node_postgres_store
node_postgres_store -->|"queries"| node_db
node_postgres_store -.->|"aligned with"| node_migrations
node_server_main -->|"serves"| node_frontend_embed
node_frontend_embed -.->|"packages"| node_app
node_handler -->|"returns"| node_model
node_store_iface -->|"stores"| node_model

click node_server_main "https://github.com/space-aditya/go_todo/blob/main/cmd/server/main.go"
click node_middleware "https://github.com/space-aditya/go_todo/blob/main/internal/middleware/middleware.go"
click node_handler "https://github.com/space-aditya/go_todo/blob/main/internal/handler/handler.go"
click node_model "https://github.com/space-aditya/go_todo/blob/main/internal/model/todo.go"
click node_store_iface "https://github.com/space-aditya/go_todo/blob/main/internal/store/store.go"
click node_memory_store "https://github.com/space-aditya/go_todo/blob/main/internal/store/memory.go"
click node_postgres_store "https://github.com/space-aditya/go_todo/blob/main/internal/store/postgres.go"
click node_migrations "https://github.com/space-aditya/go_todo/blob/main/migrations/000001_create_todos.up.sql"
click node_frontend_embed "https://github.com/space-aditya/go_todo/blob/main/internal/frontend_embed.go"
click node_spa_main "https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/main.tsx"
click node_app "https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/App.tsx"
click node_use_todos "https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/hooks/useTodos.ts"
click node_todos_api "https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/api/todos.ts"
click node_todo_form "https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/components/TodoForm.tsx"
click node_todo_list "https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/components/TodoList.tsx"
click node_todo_item "https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/components/TodoItem.tsx"

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_spa_main,node_app,node_use_todos,node_todos_api,node_todo_form,node_todo_list,node_todo_item toneBlue
class node_browser,node_server_main,node_middleware,node_handler,node_model,node_store_iface,node_memory_store,node_postgres_store,node_migrations,node_db,node_frontend_embed toneNeutral
```

## Components

### Frontend

React/Vite SPA and its API client

- [SPA Entry](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/main.tsx): react entry · Vite bootstrap for the frontend app · `internal/frontend/src/main.tsx`
- [App](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/App.tsx): react shell · Top-level todo UI and composition root · `internal/frontend/src/App.tsx`
- [useTodos](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/hooks/useTodos.ts): state hook · Coordinates todo fetching and mutations · `internal/frontend/src/hooks/useTodos.ts`
- [Todos API](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/api/todos.ts): http client · Frontend client for backend todo endpoints · `internal/frontend/src/api/todos.ts`
- [Todo Form](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/components/TodoForm.tsx): ui component · Creates new todos · `internal/frontend/src/components/TodoForm.tsx`
- [Todo List](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/components/TodoList.tsx): ui component · Renders todo collection · `internal/frontend/src/components/TodoList.tsx`
- [Todo Item](https://github.com/space-aditya/go_todo/blob/main/internal/frontend/src/components/TodoItem.tsx): ui component · Renders and updates a single todo · `internal/frontend/src/components/TodoItem.tsx`

### Other components

- **Browser**: client · User-facing SPA entrypoint
- [Server](https://github.com/space-aditya/go_todo/blob/main/cmd/server/main.go): go entrypoint · Bootstraps HTTP server, routing, store selection, and asset serving · `cmd/server/main.go`
- [Middleware](https://github.com/space-aditya/go_todo/blob/main/internal/middleware/middleware.go): http cross-cutting · Shared request wrappers such as logging and recovery · `internal/middleware/middleware.go`
- [Handlers](https://github.com/space-aditya/go_todo/blob/main/internal/handler/handler.go): http api · Todo HTTP boundary translating requests to store calls · `internal/handler/handler.go`
- [Model](https://github.com/space-aditya/go_todo/blob/main/internal/model/todo.go): domain types · Todo entities and application errors · `internal/model/todo.go`
- [Store API](https://github.com/space-aditya/go_todo/blob/main/internal/store/store.go): storage interface · Persistence contract used by handlers · `internal/store/store.go`
- [Memory Store](https://github.com/space-aditya/go_todo/blob/main/internal/store/memory.go): in-memory storage · Non-persistent store implementation · `internal/store/memory.go`
- [Postgres Store](https://github.com/space-aditya/go_todo/blob/main/internal/store/postgres.go): sql persistence · PostgreSQL-backed store implementation · `internal/store/postgres.go`
- [Migrations](https://github.com/space-aditya/go_todo/blob/main/migrations/000001_create_todos.up.sql): schema SQL · Database schema creation and evolution · `migrations/000001_create_todos.up.sql`
- **PostgreSQL**: database · Persistent production datastore
- [Embed Assets](https://github.com/space-aditya/go_todo/blob/main/internal/frontend_embed.go): go embed · Embeds built frontend into the Go binary · `internal/frontend_embed.go`

## Connections

- Browser → SPA Entry: loads SPA · Browser receives the React application
- SPA Entry → App: renders · SPA entry mounts the application shell
- App → useTodos: state · App delegates todo orchestration to the custom hook
- App → Todo Form: composes · App includes the creation form
- App → Todo List: composes · App includes the todo list
- Todo List → Todo Item: uses · List renders individual todo items
- useTodos → Todos API: calls · Hook fetches and mutates through the API client
- Todos API → Handlers: HTTP · Frontend talks to backend endpoints over HTTP
- Server → Middleware: wraps · Server wires middleware into the request pipeline
- Server → Handlers: routes · Server registers todo handlers
- Middleware → Handlers: wraps · Middleware surrounds the HTTP boundary
- Handlers → Store API: uses · Handlers depend on the persistence contract
- Store API → Memory Store: implements · In-memory backend satisfies the store API
- Store API → Postgres Store: implements · Postgres backend satisfies the store API
- Postgres Store → PostgreSQL: queries · SQL persistence targets PostgreSQL
- Postgres Store → Migrations: aligned with · Schema migration defines the todos table
- Server → Embed Assets: serves · Backend serves embedded production assets
- Embed Assets → App: packages · Built frontend is embedded into the server binary
- Handlers → Model: returns · Handlers serialize domain model and errors
- Store API → Model: stores · Store operations use the shared todo model
