Analyze and visualize astronomical observation schedules with an interactive web application.
TSI uses a modern client-server architecture:
┌──────────────────────────┐
│ Web Frontend (React+TS) │ ← Port 3000
│ - Plotly.js visualizations
│ - React Query for data fetching
│ - Tailwind CSS styling
└─────────────▲──────────┘
│ HTTP/JSON
▼
┌──────────────────────────┐
│ Rust Backend (axum) │ ← Port 8080
│ - REST API endpoints
│ - Business logic services
│ - PostgreSQL/Local repo
└─────────────▲──────────┘
│
▼
┌──────────────────────────┐
│ PostgreSQL Database │ ← Port 5432
└──────────────────────────┘
-
Configurable Imports: The backend normalizes uploaded payloads through a pluggable import adapter. The built-in adapter keeps the native TSI JSON format unchanged, and downstream integrators can swap in their own adapter without changing the frontend.
-
Sky Map: RA/Dec visualization with priority coloring and status filtering
-
Distributions: Histograms for priority, visibility, duration, and elevation
-
Visibility Map: Constraint-based visibility window visualization
-
Timeline: Month-by-month scheduled observation view with dark period overlays
-
Insights: Scheduling rates, correlations, and analytics
-
Trends: Time evolution of scheduling metrics
-
Compare: Side-by-side schedule comparison
-
Validation: Schedule integrity and constraint validation reports
TSI/
├── backend/ # Rust HTTP server (axum)
│ ├── src/
│ │ ├── bin/server.rs # Entry point
│ │ ├── http/ # HTTP handlers & routing
│ │ ├── services/ # Business logic
│ │ ├── db/ # Repository layer
│ │ └── models/ # Domain models
│ └── Cargo.toml
├── frontend/ # React SPA
│ ├── src/
│ │ ├── pages/ # Page components
│ │ ├── components/ # Reusable UI components
│ │ ├── api/ # API client
│ │ └── hooks/ # React Query hooks
│ └── package.json
├── docker/ # Docker configuration
│ ├── docker-compose.yml
│ ├── Dockerfile.backend
│ └── Dockerfile.frontend
├── data/ # Sample datasets
└── docs/ # Documentation
- Rust 1.75+ with
cargo - Node.js 20+ with
npm - Docker and Docker Compose (optional)
Backend:
cd backend
cargo run --bin tsi-serverServer starts at http://localhost:8080
Frontend:
cd frontend
npm install
npm run devFrontend starts at http://localhost:3000
cd docker
docker compose up --buildThis starts:
- PostgreSQL on port 5432
- Backend API on port 8080
- Frontend on port 3000
The default server wiring uses the native TSI JSON import adapter for uploads. Forks or embedded deployments can replace that backend adapter to normalize a different schedule schema before storage and analysis.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /v1/schedules |
List all schedules |
| POST | /v1/schedules |
Create a new schedule |
| GET | /v1/schedules/{id}/sky-map |
Sky map data |
| GET | /v1/schedules/{id}/distributions |
Distribution statistics |
| GET | /v1/schedules/{id}/visibility-map |
Visibility map |
| GET | /v1/schedules/{id}/timeline |
Timeline data |
| GET | /v1/schedules/{id}/insights |
Analytics insights |
| GET | /v1/schedules/{id}/trends |
Scheduling trends |
| GET | /v1/schedules/{id}/validation-report |
Validation report |
| GET | /v1/schedules/{id}/compare/{other} |
Compare schedules |
| Variable | Default | Description |
|---|---|---|
HOST |
0.0.0.0 |
Server bind address |
PORT |
8080 |
Server port |
DATABASE_URL |
- | PostgreSQL connection string |
RUST_LOG |
info |
Log level |
| Feature | Description |
|---|---|
local-repo |
In-memory repository (development) |
postgres-repo |
PostgreSQL repository (production) |
http-server |
HTTP server with axum |
Backend:
cd backend
cargo testFrontend:
cd frontend
npm run typecheck
npm run lintAGPL-3.0 — see LICENSE for details.
Built with Rust, React, TypeScript, Plotly.js, and modern web tooling.