You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4.3 KiB

Architecture

Iron is an async Python modular monolith with a Vue single-page Web app.

System Overview

Browser UI
  |
FastAPI app
  |
Services
  |
Repositories
  |
SQLite metadata database
  |
Storage adapters: local directory, S3, WebDAV

Backend

Core stack:

  • FastAPI
  • SQLAlchemy 2.x async ORM
  • SQLite via aiosqlite
  • Alembic migrations
  • durable in-process jobs stored in SQLite

Important packages:

  • app/api/: route handlers and dependency wiring
  • app/services/: business logic
  • app/repositories/: database access
  • app/models/: SQLAlchemy entities
  • app/schemas/: API schemas
  • app/adapters/storage/: storage adapter protocol, registry, and backend implementations

Frontend

Core stack:

  • Vite
  • Vue 3
  • TypeScript
  • Pinia
  • OpenCloud design system

Source lives in frontend/. Built assets are emitted into app/web/dist/ and served by FastAPI at /app.

Data Model

Main tables:

  • users
  • auth_sessions
  • directories
  • file_entries
  • file_versions
  • blobs
  • blob_replicas
  • backends
  • upload_sessions
  • upload_session_parts
  • jobs
  • placement_policies
  • preview_artifacts
  • cache_entries

Design principles:

  • logical namespace is separate from physical storage placement
  • files have immutable content versions
  • physical content is represented as blobs and replicas
  • user-facing deletion uses recycle-bin semantics
  • jobs are durable and retryable
  • backend-specific configuration is validated before persistence and stays behind adapter boundaries

Upload And Read Path

Uploads use tus transport under /files.

Flow:

  1. create upload session
  2. append bytes with PATCH
  3. finalize through the API
  4. create file metadata, version, blob, and local replica
  5. enqueue replication or preview jobs when needed

Read path:

  1. resolve file and current version
  2. find the best local or cached blob
  3. if needed, materialize a ready remote replica into cache
  4. serve download, preview, or range stream

Browser File Access

JSON APIs use bearer-token authorization through the shared frontend API client.

Browser preview and download must not use naked /api/files/... media URLs in img, iframe, video, or window.open. Fetch file content with authorization, create an object URL, use it, then revoke it.

This is covered by the Playwright E2E flow.

Jobs

Jobs are stored in SQLite and executed by the in-process job loop.

Current job types include:

  • blob replication
  • preview artifact generation
  • backend health checks
  • full reconcile
  • file reconcile

Every job should be safe to retry.

Storage Backends

Supported backend types:

  • local_directory: a filesystem directory used for default local persistence and low-latency reads
  • s3: S3 protocol storage, including AWS S3, MinIO, and compatible object stores
  • webdav: WebDAV storage, including OpenList-managed cloud drive directories exposed through a dedicated root_path

Replica object keys are written into a structured application-owned layout such as objects/file/sha256/73/35/<hash>.blob. This keeps remote storage organized under a predictable object tree without trying to disguise replica content as user-authored media files. During the current development stage, Iron treats this layout as the only supported remote object format and does not preserve compatibility with earlier experimental paths.

Reserved object-tree namespaces:

  • objects/file/...: primary file blobs and replica payloads
  • objects/preview/<artifact_type>/...: generated previews such as inline_preview, thumbnail, and poster
  • objects/export/metadata/YYYY/MM/DD/...: metadata snapshot exports
  • objects/manifest/<scope>/...: future manifest-style control files such as placement or repair manifests

Backend config is normalized through typed schemas before it is stored. Public config and encrypted secret config are persisted separately. IRON_SECRET_KEY derives the encryption key for stored backend credentials. API responses include public config plus a list of configured secret fields so operators can identify a backend without exposing access keys, client secrets, or refresh tokens. Update requests can change public config and provide secret overrides; omitted secret fields keep their previous encrypted values. Disabled backends can be deleted only when they are no longer referenced by policies and no blob replicas remain stored on them.