docs
Architecture
Cross-layer architecture for the Tauri, React, and Python stack.
Architecture
Consolidated architecture reference for the Tauri + Python astrology browser.
Overview
- Frontends: React UI (
apps/web-react/) and an alternate Svelte UI (apps/web-svelte/). Both call Tauri through@tauri-apps/api/core; see frontend-react and frontend-svelte. UI themes and i18n workflow: ui-conventions. - Backend: Tauri (Rust) commands orchestrate workspace and computation.
- Compute: Python sidecar (CLI) performs astrology calculations.
- Storage: YAML for metadata + DuckDB/Parquet for positions-only data.
- Aspects: Computed on demand from stored positions (not persisted).
- Shared assets: repo-root
static/is the source of truth for app-shell logos/icons and astrology glyph sets used by both frontends.
Core Principles
- YAML Compatibility: Workspace/charts remain compatible with the Python package.
- Hybrid Storage: YAML for metadata; DuckDB + Parquet for positions.
- Python Sidecar: Heavy computation stays in Python; async from Tauri.
- Query-Optimized: Structure for fast position queries; derive aspects at query time.
- Precision Support: JPL supports seconds/microseconds as needed.
Workspace Layout
workspace/
├── workspace.yaml # Workspace metadata
├── charts/ # Chart definitions
│ ├── chart_001.yaml
│ └── chart_002.yaml
├── subjects/ # Subject definitions
│ └── subject_001.yaml
└── data/
├── workspace.db # DuckDB (positions, relations, metadata)
└── positions/ # Parquet files for positions
├── chart_001/
└── chart_002/
Storage Model (Positions-Only)
- Positions are the single source of truth.
- Aspects are derived on demand in the query layer (Rust/Python).
- Parquet is used for large time ranges; DuckDB for active queries.
DuckDB Core Table
CREATE TABLE computed_positions (
chart_id TEXT NOT NULL,
datetime TIMESTAMP NOT NULL, -- Microsecond precision supported
object_id TEXT NOT NULL,
-- Ecliptic coordinates (always available)
longitude REAL NOT NULL,
latitude REAL,
-- Equatorial (JPL: always computed)
declination REAL,
right_ascension REAL,
distance REAL,
-- Topocentric (JPL with location)
altitude REAL,
azimuth REAL,
-- Physical (JPL for planets)
apparent_magnitude REAL,
phase_angle REAL,
elongation REAL,
light_time REAL,
-- Motion
speed REAL,
retrograde BOOLEAN,
-- Engine metadata
engine TEXT,
ephemeris_file TEXT,
-- Flags for populated columns
has_equatorial BOOLEAN DEFAULT FALSE,
has_topocentric BOOLEAN DEFAULT FALSE,
has_physical BOOLEAN DEFAULT FALSE,
PRIMARY KEY (chart_id, datetime, object_id)
);
JPL Column Rules
- For JPL:
declination,right_ascension,distanceare always computed. - For non‑JPL: those columns are
NULL. - Use
has_equatorial,has_topocentric,has_physicalto filter.
Backend routing (Rust → Python / Rust)
- All frontend actions go through Tauri: the UI only calls
invoke('<command>', ...). There is no direct frontend → Python path. - Compute router (env
KEFER_COMPUTE_BACKEND):Auto(default): Python primary, Rust fallback. Try Python first; on failure, fall back to Rust whenKEFER_PYTHON_FALLBACKis not disabled.Python: use Python only.Rust: use Rust only (no fallback).
- Rust implements workspace I/O, storage (DuckDB), and in-memory chart building; Python is used for Swiss Ephemeris / JPL when available.
Data Flows
Chart Creation
React UI → Tauri command → write YAML → Python compute_positions → store DuckDB
Transit Computation
React UI → Tauri command → Python compute positions over range → store DuckDB
UI derives aspects from loaded positions when needed
Integration Points (frontend)
Current:
apps/web-react/src/lib/tauri/— types andinvokehelpers (openWorkspaceFolder,saveWorkspace, etc.).apps/web-react/src/app/App.tsx— workspace open/save from the sidebar; extend with chart editors and data views.apps/web-svelte/src/— alternate Svelte workspace with the more advanced panel/radix/transits UI.static/app-shell/— shared app-shell logos and icon sets (default,modern) for both frontends.static/glyphs/— shared glyph families (default,classic) for both frontends.
To add (React):
- Time navigation state/hooks and panels (see time-navigation for design).
- Tables, radix chart canvas, and aspect grids as React components; use shared glyph assets from repo root
static/.
UI system guidance
- Prefer the shared shadcn-style primitive layers before building bespoke UI controls.
- React uses the existing shadcn/Radix-style component set under
apps/web-react/src/app/components/ui/. - Svelte uses the shared UI primitives under
apps/web-svelte/src/lib/components/ui/, built around Bits UI and the same token-first styling approach. - When adjusting visual design, prefer variants, theme tokens, spacing, and shared wrappers over one-off duplicated component implementations.
Tauri Commands (High-Level)
Invoked from frontend today:read, write, open_folder_dialog, load_workspace, save_workspace, get_workspace_defaults, get_chart_details, init_storage, compute_chart, compute_chart_from_data, compute_transit_series, create_chart, update_chart, query_positions, compute_aspects, query_radix_relative.
Registered but not yet used from UI (reserved for future wiring):store_positions, store_relation, query_timestamps, create_workspace, delete_workspace, delete_chart.
Time Navigation
- Seconds/minutes/hours/days stepping (default 1 hour).
- Quick navigation: first, prev, next, last, now.
- Time shift (Astrolab): years/months/days/hours/minutes/seconds.
UI View Modes
- Radix View: circular chart, houses, aspects (derived).
- Table View: positions table with optional JPL columns.
- Statistics View: aggregated counts.
- Interpretations View: text-based meanings.
Performance Notes
- Batch computation with pre‑initialized engines.
- DuckDB for hot data; Parquet partitioned by date for long ranges.
- Cache recent computations in memory for UI responsiveness.
Implementation Checklist
- Preserve i18n/theming.
- Add time navigation store + UI.
- Update DuckDB schema for optional JPL columns + flags.
- Ensure Python CLI returns JPL columns.
- Wire UI views to position queries; derive aspects on demand.