# danskers/finances_api architecture

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

- Interactive diagram: https://gitdiagram.com/danskers/finances_api
- Repository: https://github.com/danskers/finances_api

## Overview

#### Purpose and Runtime
Finanzas Media is a server-rendered personal-finance application: users manage accounts, income, expenses, debts, monthly history, and optional receipt images. It runs as a Python FastAPI/ASGI service, normally launched with Uvicorn; its principal application entry point is `app/main.py`.

#### HTTP and Presentation Layer
`app/main.py` owns the FastAPI application, session-oriented routes, page rendering, and the primary request workflow. Jinja2 templates form the UI boundary rather than a separate frontend client:
- `templates/dashboard.html`
- `templates/transacciones.html`
- `templates/historial.html`

Requests render HTML forms/pages and mutate state through POST endpoints. Shared page structure and styling live in `templates/base.html` and `static/styles.css`.

#### Identity and Session Boundary
Authentication is local application logic, with registration/login/logout routed through `app/main.py`. Password hashing and verification, plus authentication-related mechanisms, are centralized in `app/security.py`. The app uses cookie sessions; protected finance operations must resolve the current user before accessing user-owned accounts or transactions. There is no separate identity provider indicated.

#### Finance Domain and Persistence
The relational core is modeled in `app/models.py`: `Usuario` owns `Cuenta` and `Transaccion`; each transaction belongs to both a user and account and records amount, type, category, optional subcategory, date/month, and optional receipt URL. Request/form data contracts are defined in `app/schemas.py`.

Persistence is local SQLite through SQLModel/SQLAlchemy:
- `app/database.py`
- `finanzas.db`

This creates a clear ownership boundary: account and transaction reads/writes should be scoped by `usuario_id`, while `cuenta_id` links movements to a funding source.

#### Primary Finance Flow
1. A visitor registers or logs in through `app/main.py`; session state identifies the user.
2. The user creates accounts, then submits transactions tied to a selected account.
3. The service derives/persists transaction month/date metadata in SQLite.
4. Dashboard, current-month transactions, search/history, and deletion routes query the scoped domain data and render templates.
5. Transaction deletion removes the database record; receipt-object lifecycle behavior is not established by the supplied structure.

#### Receipt Upload Integration
Receipt handling is separated into `app/routers/uploads.py`, with Supabase initialization/configuration in `app/supabase_client.py`. The upload boundary accepts an optional image, sends it from the backend to Supabase Storage’s public `facturas` bucket using a service-role credential, then records the resulting public URL in `Transaccion.factura_url`.

External dependencies are Supabase Storage for binary receipt storage and public retrieval; credentials come from environment configuration (`app/.env` exists locally). The service-role key is privileged and must remain server-only.

#### Deployment and Architectural Constraints
The intended hosting target is Render Web Service, serving the FastAPI process. Material runtime dependencies present in the repository environment include FastAPI, Uvicorn, Jinja2, SQLModel/SQLAlchemy, session/security libraries, and the Supabase Python client. SQLite (`finanzas.db`) is local-file persistence, so durability and multi-instance behavior depend on the hosting volume/process model; Supabase is used for storage, not shown as the application’s transactional database.

Main entry points: [`app/main.py`](https://github.com/danskers/finances_api/blob/main/app/main.py) (FastAPI application), [`templates/base.html`](https://github.com/danskers/finances_api/blob/main/templates/base.html) (Shared page layout), [`app/routers/uploads.py`](https://github.com/danskers/finances_api/blob/main/app/routers/uploads.py) (Receipt upload router), [`app/models.py`](https://github.com/danskers/finances_api/blob/main/app/models.py) (Finance models)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web application"]
  node_main["FastAPI application<br/>ASGI routes<br/>[main.py]"]
  node_security["Local authentication<br/>security module<br/>[security.py]"]
  node_base_template["Shared page layout<br/>Jinja template<br/>[base.html]"]
  node_dashboard["Dashboard page<br/>Jinja template<br/>[dashboard.html]"]
  node_transactions_page["Transactions page<br/>Jinja template<br/>[transacciones.html]"]
  node_history_page["History page<br/>Jinja template<br/>[historial.html]"]
  node_styles["Page styles<br/>static CSS<br/>[styles.css]"]
end

subgraph group_finance["Finance domain"]
  node_schemas["Form contracts<br/>request schemas<br/>[schemas.py]"]
  node_models["Finance models<br/>SQLModel models<br/>[models.py]"]
end

subgraph group_storage["Persistence &amp; uploads"]
  node_database["SQLite access<br/>database module<br/>[database.py]"]
  node_sqlite[("Finance database<br/>SQLite file<br/>[finanzas.db]")]
  node_uploads["Receipt upload router<br/>upload routes<br/>[uploads.py]"]
  node_supabase_client["Supabase client<br/>storage client<br/>[supabase_client.py]"]
end

node_browser(("User browser<br/>client"))
node_supabase[("Supabase Storage<br/>object storage")]
node_render{{"Render Web Service<br/>hosting runtime"}}

node_browser -->|"HTML forms and requests"| node_main
node_render -->|"hosts"| node_main
node_main -->|"registers and authenticates"| node_security
node_main -->|"validates form data"| node_schemas
node_main -->|"queries scoped finance data"| node_models
node_models -->|"persists through"| node_database
node_database -->|"reads and writes"| node_sqlite
node_main -->|"handles receipt submissions"| node_uploads
node_uploads -->|"uses"| node_supabase_client
node_supabase_client -->|"uploads to facturas bucket"| node_supabase
node_uploads -->|"stores receipt public URL"| node_models
node_main -->|"renders"| node_dashboard
node_main -->|"renders"| node_transactions_page
node_main -->|"renders"| node_history_page
node_dashboard -.->|"extends"| node_base_template
node_transactions_page -.->|"extends"| node_base_template
node_history_page -.->|"extends"| node_base_template
node_base_template -->|"loads"| node_styles

click node_main "https://github.com/danskers/finances_api/blob/main/app/main.py"
click node_security "https://github.com/danskers/finances_api/blob/main/app/security.py"
click node_base_template "https://github.com/danskers/finances_api/blob/main/templates/base.html"
click node_dashboard "https://github.com/danskers/finances_api/blob/main/templates/dashboard.html"
click node_transactions_page "https://github.com/danskers/finances_api/blob/main/templates/transacciones.html"
click node_history_page "https://github.com/danskers/finances_api/blob/main/templates/historial.html"
click node_styles "https://github.com/danskers/finances_api/blob/main/static/styles.css"
click node_schemas "https://github.com/danskers/finances_api/blob/main/app/schemas.py"
click node_models "https://github.com/danskers/finances_api/blob/main/app/models.py"
click node_database "https://github.com/danskers/finances_api/blob/main/app/database.py"
click node_sqlite "https://github.com/danskers/finances_api/blob/main/finanzas.db"
click node_uploads "https://github.com/danskers/finances_api/blob/main/app/routers/uploads.py"
click node_supabase_client "https://github.com/danskers/finances_api/blob/main/app/supabase_client.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_main,node_security,node_base_template,node_dashboard,node_transactions_page,node_history_page,node_styles toneBlue
class node_schemas,node_models toneAmber
class node_database,node_sqlite,node_uploads,node_supabase_client toneMint
class node_browser,node_supabase,node_render toneNeutral
```

## Components

### Web application

- [FastAPI application](https://github.com/danskers/finances_api/blob/main/app/main.py): ASGI routes · Owns sessions, page routes, and finance request workflows. · `app/main.py`
- [Local authentication](https://github.com/danskers/finances_api/blob/main/app/security.py): security module · Hashes and verifies passwords for local login. · `app/security.py`
- [Shared page layout](https://github.com/danskers/finances_api/blob/main/templates/base.html): Jinja template · `templates/base.html`
- [Dashboard page](https://github.com/danskers/finances_api/blob/main/templates/dashboard.html): Jinja template · `templates/dashboard.html`
- [Transactions page](https://github.com/danskers/finances_api/blob/main/templates/transacciones.html): Jinja template · `templates/transacciones.html`
- [History page](https://github.com/danskers/finances_api/blob/main/templates/historial.html): Jinja template · `templates/historial.html`
- [Page styles](https://github.com/danskers/finances_api/blob/main/static/styles.css): static CSS · `static/styles.css`

### Finance domain

- [Form contracts](https://github.com/danskers/finances_api/blob/main/app/schemas.py): request schemas · `app/schemas.py`
- [Finance models](https://github.com/danskers/finances_api/blob/main/app/models.py): SQLModel models · Usuario owns accounts and transactions; transactions link user and account. · `app/models.py`

### Persistence & uploads

- [SQLite access](https://github.com/danskers/finances_api/blob/main/app/database.py): database module · `app/database.py`
- [Finance database](https://github.com/danskers/finances_api/blob/main/finanzas.db): SQLite file · Local transactional persistence scoped by usuario_id. · `finanzas.db`
- [Receipt upload router](https://github.com/danskers/finances_api/blob/main/app/routers/uploads.py): upload routes · Uploads optional receipt images and returns public URLs. · `app/routers/uploads.py`
- [Supabase client](https://github.com/danskers/finances_api/blob/main/app/supabase_client.py): storage client · Initializes privileged backend storage access. · `app/supabase_client.py`

### Other components

- **User browser**: client · Uses server-rendered finance pages and forms.
- **Supabase Storage**: object storage · Public facturas bucket stores receipt images.
- **Render Web Service**: hosting runtime · Runs the Uvicorn-served FastAPI process.

## Connections

- User browser → FastAPI application: HTML forms and requests
- Render Web Service → FastAPI application: hosts
- FastAPI application → Local authentication: registers and authenticates
- FastAPI application → Form contracts: validates form data
- FastAPI application → Finance models: queries scoped finance data
- Finance models → SQLite access: persists through
- SQLite access → Finance database: reads and writes
- FastAPI application → Receipt upload router: handles receipt submissions
- Receipt upload router → Supabase client: uses
- Supabase client → Supabase Storage: uploads to facturas bucket
- Receipt upload router → Finance models: stores receipt public URL
- FastAPI application → Dashboard page: renders
- FastAPI application → Transactions page: renders
- FastAPI application → History page: renders
- Dashboard page → Shared page layout: extends
- Transactions page → Shared page layout: extends
- History page → Shared page layout: extends
- Shared page layout → Page styles: loads
