# sruinz/svrx-pinry architecture

> Architecture diagram of the GitHub repository sruinz/svrx-pinry, 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/sruinz/svrx-pinry
- Repository: https://github.com/sruinz/svrx-pinry

## Overview

SVRx Pinry is a self-hosted image board: users browse and search pins, create pins from uploads or collected web images, organize them into boards and tags, and can export selected content as background ZIP jobs. The Vue SPA is the main interface to Django APIs; Django manages accounts, pin/board data, media assets, SSO, and exports. The README documents additional browsing and account capabilities, but sampled source excerpts are limited, so only high-level subsystem connections are shown where implementation wiring was not available.

Main entry points: [`pinry-spa/src/components/api.js`](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/components/api.js) (API client), [`core/views.py`](https://github.com/sruinz/svrx-pinry/blob/main/core/views.py) (Django API), [`exports/services/worker.py`](https://github.com/sruinz/svrx-pinry/blob/main/exports/services/worker.py) (Export worker), [`pinry-spa/src/views/Pins4Board.vue`](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/views/Pins4Board.vue) (Pin and board screens)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interface["Web interface"]
  node_spa["Vue application<br/>[main.js]"]
  node_router["Views and routes<br/>[index.js]"]
  node_api_client["API client<br/>[api.js]"]
  node_search_ui["Search interface<br/>[SearchPanel.vue]"]
  node_pin_ui["Pin and board screens<br/>[Pins4Board.vue]"]
  node_export_ui["Export interface<br/>[ExportDialog.vue]"]
end

subgraph group_content["Pins and organization"]
  node_api["Django API<br/>[views.py]"]
  node_pin_services["Pin and board services<br/>[pin_import.py]"]
  node_models["Pin and board models<br/>[models.py]"]
  node_db[("Application database")]
end

subgraph group_identity["Accounts and SSO"]
  node_accounts["Account management<br/>[views.py]"]
  node_sso["SSO flows<br/>[flows.py]"]
  node_sso_client["Provider client<br/>[client.py]"]
end

subgraph group_media["Media lifecycle"]
  node_media_api["Media API services<br/>[media_storage.py]"]
  node_image_app["Image lifecycle<br/>[media_cleanup.py]"]
  node_media_store[("Image files")]
end

subgraph group_exports["Exports"]
  node_export_api["Export endpoints<br/>[views.py]"]
  node_export_jobs["Export jobs<br/>[jobs.py]"]
  node_export_worker["Export worker<br/>[worker.py]"]
  node_export_files["ZIP artifacts<br/>[archive.py]"]
end

node_user(("User"))
node_idp["Identity provider"]

node_user -->|"uses"| node_spa
node_spa -->|"mounts"| node_router
node_router -->|"routes"| node_pin_ui
node_pin_ui -->|"offers search"| node_search_ui
node_pin_ui -->|"requests data"| node_api_client
node_search_ui -->|"requests results"| node_api_client
node_api_client -->|"calls"| node_api
node_api -->|"invokes"| node_pin_services
node_pin_services -->|"updates"| node_models
node_models -->|"reads and writes"| node_db
node_api -->|"serves account actions"| node_accounts
node_accounts -->|"starts SSO"| node_sso
node_sso -->|"exchanges credentials"| node_sso_client
node_sso_client -.->|"authenticates"| node_idp
node_api -->|"handles media"| node_media_api
node_media_api -->|"publishes assets"| node_media_store
node_image_app -->|"manages files"| node_media_store
node_export_ui -->|"requests export"| node_api_client
node_api_client -->|"calls export endpoints"| node_export_api
node_export_api -->|"creates jobs"| node_export_jobs
node_export_worker -->|"claims jobs"| node_export_jobs
node_export_worker -->|"captures pin data"| node_models
node_export_worker -->|"builds archive"| node_export_files

click node_spa "https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/main.js"
click node_router "https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/router/index.js"
click node_api_client "https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/components/api.js"
click node_search_ui "https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/components/search/SearchPanel.vue"
click node_pin_ui "https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/views/Pins4Board.vue"
click node_api "https://github.com/sruinz/svrx-pinry/blob/main/core/views.py"
click node_pin_services "https://github.com/sruinz/svrx-pinry/blob/main/core/services/pin_import.py"
click node_models "https://github.com/sruinz/svrx-pinry/blob/main/core/models.py"
click node_accounts "https://github.com/sruinz/svrx-pinry/blob/main/users/views.py"
click node_sso "https://github.com/sruinz/svrx-pinry/blob/main/users/sso/flows.py"
click node_sso_client "https://github.com/sruinz/svrx-pinry/blob/main/users/sso/client.py"
click node_media_api "https://github.com/sruinz/svrx-pinry/blob/main/core/services/media_storage.py"
click node_image_app "https://github.com/sruinz/svrx-pinry/blob/main/django_images/services/media_cleanup.py"
click node_export_ui "https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/components/export/ExportDialog.vue"
click node_export_api "https://github.com/sruinz/svrx-pinry/blob/main/exports/views.py"
click node_export_jobs "https://github.com/sruinz/svrx-pinry/blob/main/exports/services/jobs.py"
click node_export_worker "https://github.com/sruinz/svrx-pinry/blob/main/exports/services/worker.py"
click node_export_files "https://github.com/sruinz/svrx-pinry/blob/main/exports/services/archive.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_spa,node_router,node_api_client,node_search_ui,node_pin_ui,node_export_ui,node_user toneBlue
class node_api,node_pin_services,node_models,node_db toneAmber
class node_accounts,node_sso,node_sso_client toneMint
class node_media_api,node_image_app,node_media_store toneRose
class node_export_api,node_export_jobs,node_export_worker,node_export_files,node_idp toneIndigo
```

## Components

### Web interface

- [Vue application](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/main.js): `pinry-spa/src/main.js`
- [Views and routes](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/router/index.js): `pinry-spa/src/router/index.js`
- [API client](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/components/api.js): `pinry-spa/src/components/api.js`
- [Search interface](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/components/search/SearchPanel.vue): `pinry-spa/src/components/search/SearchPanel.vue`
- [Pin and board screens](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/views/Pins4Board.vue): `pinry-spa/src/views/Pins4Board.vue`
- [Export interface](https://github.com/sruinz/svrx-pinry/blob/main/pinry-spa/src/components/export/ExportDialog.vue): `pinry-spa/src/components/export/ExportDialog.vue`

### Pins and organization

- [Django API](https://github.com/sruinz/svrx-pinry/blob/main/core/views.py): `core/views.py`
- [Pin and board services](https://github.com/sruinz/svrx-pinry/blob/main/core/services/pin_import.py): `core/services/pin_import.py`
- [Pin and board models](https://github.com/sruinz/svrx-pinry/blob/main/core/models.py): `core/models.py`
- **Application database**

### Accounts and SSO

- [Account management](https://github.com/sruinz/svrx-pinry/blob/main/users/views.py): `users/views.py`
- [SSO flows](https://github.com/sruinz/svrx-pinry/blob/main/users/sso/flows.py): `users/sso/flows.py`
- [Provider client](https://github.com/sruinz/svrx-pinry/blob/main/users/sso/client.py): `users/sso/client.py`

### Media lifecycle

- [Media API services](https://github.com/sruinz/svrx-pinry/blob/main/core/services/media_storage.py): `core/services/media_storage.py`
- [Image lifecycle](https://github.com/sruinz/svrx-pinry/blob/main/django_images/services/media_cleanup.py): `django_images/services/media_cleanup.py`
- **Image files**

### Exports

- [Export endpoints](https://github.com/sruinz/svrx-pinry/blob/main/exports/views.py): `exports/views.py`
- [Export jobs](https://github.com/sruinz/svrx-pinry/blob/main/exports/services/jobs.py): `exports/services/jobs.py`
- [Export worker](https://github.com/sruinz/svrx-pinry/blob/main/exports/services/worker.py): `exports/services/worker.py`
- [ZIP artifacts](https://github.com/sruinz/svrx-pinry/blob/main/exports/services/archive.py): `exports/services/archive.py`

### Other components

- **User**
- **Identity provider**

## Connections

- User → Vue application: uses
- Vue application → Views and routes: mounts
- Views and routes → Pin and board screens: routes
- Pin and board screens → Search interface: offers search
- Pin and board screens → API client: requests data
- Search interface → API client: requests results
- API client → Django API: calls
- Django API → Pin and board services: invokes
- Pin and board services → Pin and board models: updates
- Pin and board models → Application database: reads and writes
- Django API → Account management: serves account actions
- Account management → SSO flows: starts SSO
- SSO flows → Provider client: exchanges credentials
- Provider client → Identity provider: authenticates
- Django API → Media API services: handles media
- Media API services → Image files: publishes assets
- Image lifecycle → Image files: manages files
- Export interface → API client: requests export
- API client → Export endpoints: calls export endpoints
- Export endpoints → Export jobs: creates jobs
- Export worker → Export jobs: claims jobs
- Export worker → Pin and board models: captures pin data
- Export worker → ZIP artifacts: builds archive
