Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
rust:
name: Build and Test Rust Service
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable

- name: Build Rust service
working-directory: ./service
run: cargo build --verbose

- name: Run Rust tests
working-directory: ./service
run: cargo test --verbose

- name: Check Rust formatting
working-directory: ./service
run: cargo fmt --check

- name: Run Clippy
working-directory: ./service
run: cargo clippy -- -D warnings

- name: Generate OpenAPI spec
working-directory: ./service
run: cargo run --bin generate-openapi

bindings:
name: Build TypeScript Bindings
runs-on: ubuntu-latest
needs: rust

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable

- name: Generate OpenAPI spec
working-directory: ./service
run: |
cargo build --release --bin generate-openapi
cargo run --release --bin generate-openapi
cp openapi.json ../openapi/

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: bindings/package-lock.json

- name: Install bindings dependencies
working-directory: ./bindings
run: npm ci

- name: Build bindings
working-directory: ./bindings
run: npm run build

- name: Run bindings tests
working-directory: ./bindings
run: npm test

frontend:
name: Build and Test Angular Frontend
runs-on: ubuntu-latest
needs: bindings

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable

- name: Generate OpenAPI spec
working-directory: ./service
run: |
cargo build --release --bin generate-openapi
cargo run --release --bin generate-openapi
cp openapi.json ../openapi/

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json

- name: Build bindings first
working-directory: ./bindings
run: |
npm ci
npm run build

- name: Install frontend dependencies
working-directory: ./frontend
run: npm ci

- name: Build frontend
working-directory: ./frontend
run: npm run build

- name: Run frontend tests
working-directory: ./frontend
run: npm test -- --watch=false --browsers=ChromeHeadless
46 changes: 46 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Rust
# Generated by Cargo
# will have compiled files and executables
debug
Expand All @@ -19,3 +20,48 @@ target
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Node.js / TypeScript / Angular
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Compiled TypeScript
dist/
dist-ssr/
*.tsbuildinfo

# Angular specific
.angular/
.angular-cache/

# Environment variables
.env
.env.local
.env.*.local

# Editor directories and files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# OS files
Thumbs.db

# Coverage
coverage/
*.lcov
.nyc_output

# Build artifacts
build/
out/

# OpenAPI generated files (keep source, ignore generated)
bindings/src/schema.ts
132 changes: 132 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Architecture

## Overview

BioIS is structured as a monorepo with three main components:

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β”‚ Angular Frontend (TypeScript) β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”‚ HTTP/REST
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β”‚ TypeScript OpenAPI Client β”‚
β”‚ (Auto-generated from spec) β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”‚ Type-safe API calls
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β”‚ Rust Service (Axum + utoipa) β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ OpenAPI/Swagger UI β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Biodiversity Indicators API β”‚ β”‚
β”‚ β”‚ - Health check β”‚ β”‚
β”‚ β”‚ - List indicators β”‚ β”‚
β”‚ β”‚ - Calculate indicators β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## Components

### 1. Rust Service (`service/`)

The backend service built with:
- **Axum**: Modern, ergonomic web framework
- **utoipa**: OpenAPI spec generation from Rust code
- **utoipa-swagger-ui**: Embedded Swagger UI for API documentation
- **tokio**: Async runtime

Key features:
- Type-safe API definitions
- Automatic OpenAPI spec generation
- Built-in Swagger UI at `/swagger-ui`
- CORS enabled for development

### 2. TypeScript Bindings (`bindings/`)

Auto-generated TypeScript client using:
- **openapi-typescript**: Generates TypeScript types from OpenAPI spec
- **openapi-fetch**: Type-safe fetch client

Benefits:
- Full type safety from backend to frontend
- Compile-time error detection
- Auto-completion in IDEs
- Single source of truth (OpenAPI spec)

### 3. Angular Frontend (`frontend/`)

Modern Angular application using:
- Angular 19+ with standalone components
- Signal-based state management
- TypeScript
- Responsive CSS

Features:
- Interactive UI for biodiversity calculations
- Service layer using generated TypeScript client
- Form validation
- Error handling

## Data Flow

1. **Development Time:**
- Rust code defines API with utoipa annotations
- OpenAPI spec is generated from Rust code
- TypeScript types are generated from OpenAPI spec
- Angular code uses typed client for API calls

2. **Runtime:**
- User interacts with Angular UI
- Angular calls TypeScript client methods
- TypeScript client makes HTTP requests to Rust service
- Rust service processes requests and returns JSON
- TypeScript client parses response with type safety
- Angular UI displays results

## Build Process

```bash
# 1. Build Rust service (generates binary)
cd service && cargo build

# 2. Generate OpenAPI spec (from Rust code)
cargo run --bin generate-openapi

# 3. Generate TypeScript client (from OpenAPI spec)
cd ../bindings && npm run generate

# 4. Build Angular app (using TypeScript client)
cd ../frontend && npm run build
```

## Testing Strategy

- **Rust**: Unit tests with cargo test
- **TypeScript Bindings**: Basic smoke tests
- **Angular**: Component and service tests with Jasmine/Karma
- **Integration**: CI pipeline tests entire build chain

## Future Enhancements

- [ ] Add geoengine API integration
- [ ] Add georust/ogcapi for OGC API Features support
- [ ] Add database for storing calculation results
- [ ] Add authentication/authorization
- [ ] Add real biodiversity calculation algorithms
- [ ] Add Docker support for deployment
- [ ] Add more comprehensive tests
Loading
Loading