Skip to content

Architecture

Christian Beier edited this page Aug 18, 2026 · 3 revisions

Architectural style

Xolmis follows a layered, module-centric desktop architecture:

  • Presentation layer with Lazarus forms and dialogs.
  • Application layer with module controllers, filters, and search orchestration.
  • Domain/data access layer with records and repositories.
  • SQL provider layer that abstracts backend-specific SQL generation.
  • Persistence layer with SQLDB connections and relational databases.
  • IO and reporting subsystems integrated as plugins and templates.

The architecture is mostly monolithic in deployment (single desktop app), with clear internal separation by units/folders.

High-level structure

flowchart TB
  User[User]
  Main[Main Form\nsource/ufrm_main.pp]
  Grid[Custom Grid Screen\nsource/screens/ufrm_customgrid.pp]
  Modules[Module Controllers\nsource/modules/*.pp]
  Services[Domain Services\nsource/data/data_services.pp]
  Repos[Repositories\nsource/models/*.pp]
  Provider[Unified SQL Provider\nsource/data/data_providers.pp]
  SQLUnits[Backend SQL Units\nsource/providers/*.pp]
  DB[(SQLite)]
  IO[Import/Export Core\nsource/io/*.pp]
  Reports[Report Preview + Templates\nsource/screens/ufrm_printpreview.pp + reports/*.lrf]

  User --> Main --> Grid
  Grid --> Modules
  Modules --> Repos
  Modules --> Services
  Services --> Repos
  Repos --> Provider --> SQLUnits --> DB
  Main --> IO
  Grid --> Reports
Loading

Source organization (macro)

Main architecture folders under source:

  • source/models: records and repositories (31 Pascal files found).
  • source/modules: module controllers and submodules (24 files).
  • source/data: shared data abstractions, schema, management, filters, search, providers facade, services (22 files).
  • source/providers: backend-aware SQL builders per domain (22 files).
  • source/io: import/export core plus format handlers (20 files).
  • source/data_modules: runtime datasets, connections, and data wiring (14 files).
  • source/screens: reusable, feature-rich screens such as custom grid and print preview (16 files).
  • source/dialogs: operation dialogs (import, export, settings, admin, etc.) (81 files).

Startup and runtime bootstrap

Entry point:

  • source/Xolmis.lpr initializes settings, theme, splash screen, data modules, and main form.

Core runtime objects:

  • TDMM (source/data_modules/udm_main.pp): central data module, SQL connectors/transations, system DB access, app-wide datasets, global provider initialization.
  • TfrmMain (source/ufrm_main.pp): shell/navigation surface and actions.
  • TfrmCustomGrid (source/screens/ufrm_customgrid.pp): operational workspace for data modules (grid, filters, media, summary, map, print actions).

Layers and responsibilities

1) Presentation layer

Main units:

  • source/ufrm_main.pp
  • source/screens/ufrm_customgrid.pp
  • source/dialogs/*.pp
  • source/screens/ufrm_printpreview.pp

Responsibilities:

  • Navigation and command dispatch (actions/menus/buttons).
  • User interactions for CRUD, filtering, import/export, and reporting.
  • Visual features (dark mode handling, map plugins, media panels, child grids).

2) Application layer (module controllers)

Main units:

  • source/modules/modules_core.pp
  • source/modules/modules_*.pp (bands, sightings, sampling, etc.)

Responsibilities:

  • Module behavior encapsulation per table/domain.
  • Grid column configuration, canvas rendering rules, and UI flags.
  • Search and quick-filter composition.
  • Submodule composition for parent-child datasets.

3) Domain and repositories

Main units:

  • source/models/models_record_types.pp
  • source/models/models_*.pp

Responsibilities:

  • Base entity model (TXolmisRecord) with audit and lifecycle fields.
  • Repository contract (TXolmisRepository) for CRUD/hydration/access patterns.
  • Domain-specific repositories (bands, captures, nests, sightings, taxonomy, etc.).

4) SQL provider abstraction

Main units:

  • source/data/data_providers.pp
  • source/providers/providers_*.pp

Responsibilities:

  • Interface-based SQL contract per domain table group.
  • Unified provider facade (ISQLProvider / TSQLProvider).
  • Backend-aware SQL strings for table creation and CRUD/find/list operations.

Supported backends in code:

  • SQLite
  • Firebird
  • PostgreSQL
  • MariaDB

5) Data management and schema

Main units:

  • source/data/data_management.pp
  • source/data/data_schema.pp
  • source/data/data_types.pp

Responsibilities:

  • Database creation and migration orchestration (SCHEMA_VERSION present in data_management).
  • Table/view creation and metadata seeding.
  • Common types and aliases used by search/filter/sort/query builders.

6) IO subsystem (imports and exports)

Main units:

  • source/io/io_core.pp
  • source/io/io_*.pp (csv, dbf, json, ods, xlsx, xml, etc.)
  • source/dialogs/udlg_import.pp
  • source/dialogs/udlg_export.pp

Responsibilities:

  • Importer/exporter registries by extension and probing.
  • Field mapping/transformation pipeline (TFieldMapper).
  • Import/export options with progress and cancellation support.
  • Wizard-based import flow and configurable export flow.

7) Reporting subsystem

Main units:

  • source/screens/ufrm_printpreview.pp
  • source/data_modules/udm_reports.pp
  • reports/*.lrf

Responsibilities:

  • LazReport preview, pagination, print, and PDF export.
  • Dedicated report datasets and field display translation.
  • External report templates (.lrf) for domain reports.

Main dependency direction

flowchart LR
  UI[Presentation\nforms/screens/dialogs]
  MOD[Modules\ncontrollers]
  SVC[Services]
  REP[Repositories]
  PROV[SQL Provider Facade]
  SQL[Backend SQL Units]
  DB[(Database)]

  UI --> MOD
  MOD --> SVC
  MOD --> REP
  SVC --> REP
  REP --> PROV --> SQL --> DB
Loading

Main runtime flows

Flow A: open a module and load records

sequenceDiagram
  participant U as User
  participant Main as Main Form
  participant Grid as Custom Grid
  participant Mod as Module Controller
  participant Repo as Repository
  participant Prov as SQL Provider
  participant DB as Database

  U->>Main: Open module action
  Main->>Grid: Create/show module screen
  Grid->>Mod: Initialize controller
  Mod->>Repo: Request list/search
  Repo->>Prov: Request SQL for scenario
  Prov->>DB: Execute SQL via SQLDB
  DB-->>Repo: Result set
  Repo-->>Grid: Hydrated dataset
  Grid-->>U: Render rows, summary, filters
Loading

Flow B: import data (wizard)

sequenceDiagram
  participant U as User
  participant Dlg as Import Dialog
  participant Core as io_core
  participant Mapper as TFieldMapper
  participant Repo as Repository
  participant DB as Database

  U->>Dlg: Choose file + mapping options
  Dlg->>Core: Resolve importer and parse rows
  Core->>Mapper: Apply transforms and mapping
  Mapper-->>Dlg: Normalized row
  Dlg->>Repo: Persist mapped record(s)
  Repo->>DB: Insert/Update
  DB-->>Dlg: Commit/result
  Dlg-->>U: Progress + final log
Loading

Flow C: print/preview report

sequenceDiagram
  participant U as User
  participant Grid as Custom Grid
  participant Preview as Print Preview
  participant Rep as LazReport
  participant DS as Report DataSets

  U->>Grid: Trigger print/report action
  Grid->>Preview: Open report preview
  Preview->>Rep: Load .lrf template
  Preview->>DS: Bind master/details sources
  Rep-->>Preview: Prepare pages
  Preview-->>U: Show preview / print / export PDF
Loading

Architectural strengths observed

  • Strong separation by folder and role (modules, models, providers, data, io, screens/dialogs).
  • Reusable module-controller pattern for many domains.
  • Backend SQL abstraction centralized through a unified provider facade.
  • Import/export designed as extensible registry-driven components.
  • Reporting decoupled through external templates and a dedicated preview screen.

Clone this wiki locally