Skip to content

Commit 7165ba5

Browse files
Merge pull request #4 from geo-engine/openapi
feat: add NDVI process endpoint and OpenAPI documentation
2 parents 66590e3 + e730440 commit 7165ba5

File tree

149 files changed

+30348
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+30348
-2
lines changed

.github/copilot-instructions.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copilot Instructions
2+
3+
This BioIS monorepo is written in Rust, SQL, TypeScript and Python.
4+
5+
## Repository Structure
6+
7+
| Path | Description |
8+
| -------------- | ----------------------------------------------- |
9+
| `README.md` | Project Documentation |
10+
| `LICENSE` | License File |
11+
| `.github/` | GitHub Configuration |
12+
| `justfile` | Justfile for task automation |
13+
| `backend/` | Rust API Code |
14+
| `frontend/` | TypeScript Angular Frontend Code |
15+
| `api-client/` | OpenAPI client code generated from the API spec |
16+
| `test-client/` | Snippet-based test client for testing the API |
17+
18+
- Commit messages and pull request titles should be in the conventional commit format of `<type>(<scope>): <description>`, where:
19+
- `<type>` is one of `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`.
20+
- `<scope>` is a noun describing the section of the codebase affected (e.g., `backend`, `frontend`, `api`).
21+
- `<description>` is a short summary of the change.
22+
- Diagrams should be created using Mermaid syntax and included in the relevant Markdown files for documentation purposes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
applyTo: "api-client/**/*"
3+
---
4+
5+
# Copilot Instructions
6+
7+
- Never modify the `typescript` directory manually.
8+
It is generated from the OpenAPI specification in `openapi.json` using the OpenAPI Generator.
9+
To regenerate the API client, run `just generate-api-client` from the project root.
10+
- The OpenAPI Generator configuration is defined in `config.yaml`.
11+
If you need to change the generated code, modify the configuration and regenerate the client.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
applyTo: "backend/**/*.rs, backend/**/*.sql"
3+
---
4+
5+
# Copilot Instructions
6+
7+
## Coding Style
8+
9+
### Rust
10+
11+
- Follow the Rust API guidelines for naming conventions, error handling, and documentation.
12+
- Use `snake_case` for variable and function names, and `PascalCase` for struct and enum names.
13+
- Ensure that all public functions and types have documentation comments using `///`.
14+
- Use `Result<T>` (from anyhow) for error handling and define custom error types where appropriate.
15+
- Use `camelCase` for JSON field names when serializing/deserializing with serde, and use `#[serde(rename_all = "camelCase")]` on structs to enforce this convention.
16+
- Never use `unwrap()` or `expect()` in production code. Instead, propagate errors using the `?` operator or handle them gracefully.
17+
- Start test function names with `it_` and use descriptive names that indicate what the test is verifying.
18+
19+
### SQL
20+
21+
- The SQL dialect used in this project is PostgreSQL. Follow the PostgreSQL SQL style guide for formatting and conventions.
22+
- For SQL queries, use uppercase for SQL keywords (e.g., SELECT, FROM, WHERE) and lowercase for table and column names.
23+
- SQLFluff is used for linting SQL files. Ensure that your SQL code adheres to the configured SQLFluff rules.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
applyTo: "frontend/**"
3+
---
4+
5+
You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices.
6+
7+
## TypeScript Best Practices
8+
9+
- Use strict type checking
10+
- Prefer type inference when the type is obvious
11+
- Avoid the `any` type; use `unknown` when type is uncertain
12+
13+
## Angular Best Practices
14+
15+
- Always use standalone components over NgModules
16+
- Must NOT set `standalone: true` inside Angular decorators. It's the default in Angular v20+.
17+
- Use signals for state management
18+
- Implement lazy loading for feature routes
19+
- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead
20+
- Use `NgOptimizedImage` for all static images.
21+
- `NgOptimizedImage` does not work for inline base64 images.
22+
23+
## Accessibility Requirements
24+
25+
- It MUST pass all AXE checks.
26+
- It MUST follow all WCAG AA minimums, including focus management, color contrast, and ARIA attributes.
27+
28+
### Components
29+
30+
- Keep components small and focused on a single responsibility
31+
- Use `input()` and `output()` functions instead of decorators
32+
- Use `computed()` for derived state
33+
- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator
34+
- Prefer inline templates for small components
35+
- Prefer Reactive forms instead of Template-driven ones
36+
- Do NOT use `ngClass`, use `class` bindings instead
37+
- Do NOT use `ngStyle`, use `style` bindings instead
38+
- When using external templates/styles, use paths relative to the component TS file.
39+
40+
## State Management
41+
42+
- Use signals for local component state
43+
- Use `computed()` for derived state
44+
- Keep state transformations pure and predictable
45+
- Do NOT use `mutate` on signals, use `update` or `set` instead
46+
47+
## Templates
48+
49+
- Keep templates simple and avoid complex logic
50+
- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch`
51+
- Use the async pipe to handle observables
52+
- Do not assume globals like (`new Date()`) are available.
53+
- Do not write arrow functions in templates (they are not supported).
54+
55+
## Services
56+
57+
- Design services around a single responsibility
58+
- Use the `providedIn: 'root'` option for singleton services
59+
- Use the `inject()` function instead of constructor injection

.github/workflows/ci.yml

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
merge_group:
6+
push:
7+
branches:
8+
- main # For generating code coverage on main branch
9+
# Allows you to run this workflow manually from the Actions tab
10+
workflow_dispatch:
11+
12+
jobs:
13+
lint-backend:
14+
name: Lint Backend
15+
16+
runs-on: ubuntu-24.04
17+
container: quay.io/geoengine/devcontainer:latest
18+
19+
permissions:
20+
contents: read
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v6
25+
- uses: extractions/setup-just@v3
26+
- name: Init rustup toolchain
27+
run: rustup show
28+
- name: setup rust build cache
29+
uses: Swatinem/rust-cache@v2
30+
with:
31+
# An explicit cache key that is used instead of the automatic `job`-based
32+
# cache key and is thus stable across jobs.
33+
# Default: empty
34+
shared-key: ""
35+
36+
# An additional cache key that is added alongside the automatic `job`-based
37+
# cache key and can be used to further differentiate jobs.
38+
# Default: empty
39+
key: ci_test_
40+
- name: Rustfmt
41+
run: just lint-backend-rustfmt
42+
- name: Clippy
43+
run: just lint-backend-clippy
44+
- name: SQLFluff
45+
run: just lint-backend-sqlfluff
46+
- name: Start PostgreSQL
47+
run: |
48+
service postgresql start
49+
psql postgres://geoengine:geoengine@localhost -c "CREATE DATABASE biois;"
50+
- name: Diesel Check
51+
run: |
52+
just install-diesel-cli
53+
just lint-backend-diesel-cli
54+
env:
55+
DATABASE_URL: postgres://geoengine:geoengine@localhost/biois
56+
57+
lint-api-client:
58+
name: Lint API Client
59+
60+
runs-on: ubuntu-24.04
61+
container: quay.io/geoengine/devcontainer:latest
62+
63+
permissions:
64+
contents: read
65+
66+
steps:
67+
- name: Checkout code
68+
uses: actions/checkout@v6
69+
- uses: extractions/setup-just@v3
70+
- name: Start PostgreSQL
71+
run: |
72+
service postgresql start
73+
psql postgres://geoengine:geoengine@localhost -c "CREATE DATABASE biois;"
74+
- name: Install Java (OpenAPI Generator requires Java to run)
75+
run: |
76+
# deleted in devcontainer image, but required by java installer
77+
mkdir -p /usr/share/man/man1
78+
apt-get update
79+
apt-get install -y openjdk-21-jre-headless
80+
- name: Lint OpenAPI specification
81+
run: |
82+
just lint-openapi-spec
83+
- name: Idempotency of OpenAPI doc generation
84+
run: |
85+
just generate-openapi-spec
86+
just check-no-changes-in-git-repo
87+
- name: Idempotency of API client code generation
88+
run: |
89+
just build-api-client
90+
just check-no-changes-in-git-repo
91+
- name: Check API client for build errors
92+
run: just lint-api-client
93+
94+
lint-frontend:
95+
name: Lint Frontend
96+
97+
runs-on: ubuntu-24.04
98+
container: quay.io/geoengine/devcontainer:latest
99+
100+
permissions:
101+
contents: read
102+
103+
steps:
104+
- name: Checkout code
105+
uses: actions/checkout@v6
106+
- uses: extractions/setup-just@v3
107+
- name: Install dependencies
108+
run: |
109+
just install-api-client-deps
110+
just install-frontend-deps
111+
- name: Code Format
112+
run: just lint-frontend-fmt
113+
- name: Lints
114+
run: just lint-frontend-code
115+
116+
test-backend:
117+
name: Test Backend
118+
119+
runs-on: ubuntu-24.04
120+
container: quay.io/geoengine/devcontainer:latest
121+
122+
permissions:
123+
contents: read
124+
125+
outputs:
126+
coverage-artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }}
127+
128+
steps:
129+
- name: Checkout code
130+
uses: actions/checkout@v6
131+
- uses: extractions/setup-just@v3
132+
- name: Init rustup toolchain
133+
run: rustup show
134+
135+
- name: Start PostgreSQL
136+
run: |
137+
service postgresql start
138+
psql postgres://geoengine:geoengine@localhost -c "CREATE DATABASE biois;"
139+
- name: setup rust build cache
140+
uses: Swatinem/rust-cache@v2
141+
with:
142+
# An explicit cache key that is used instead of the automatic `job`-based
143+
# cache key and is thus stable across jobs.
144+
# Default: empty
145+
shared-key: ""
146+
147+
# An additional cache key that is added alongside the automatic `job`-based
148+
# cache key and can be used to further differentiate jobs.
149+
# Default: empty
150+
key: ci_test_
151+
- name: Test
152+
run: |
153+
just install-llvm-cov
154+
just test-backend-with-coverage "/lcov.info"
155+
- id: upload-artifact
156+
uses: actions/upload-artifact@v6
157+
with:
158+
name: lcov-report-backend-${{ github.run_id }}-${{ github.run_attempt }}
159+
path: /lcov.info
160+
compression-level: 9
161+
retention-days: 1
162+
if-no-files-found: error
163+
164+
test-frontend:
165+
name: Test Frontend
166+
167+
runs-on: ubuntu-24.04
168+
container: quay.io/geoengine/devcontainer:latest
169+
170+
permissions:
171+
contents: read
172+
173+
outputs:
174+
coverage-artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }}
175+
176+
steps:
177+
- name: Checkout code
178+
uses: actions/checkout@v6
179+
- uses: extractions/setup-just@v3
180+
- name: Install dependencies
181+
run: |
182+
just install-api-client-deps
183+
just install-frontend-deps
184+
- name: Build
185+
run: just build-frontend
186+
187+
- name: Test
188+
run: just test-frontend
189+
190+
- id: upload-artifact
191+
uses: actions/upload-artifact@v6
192+
with:
193+
name: lcov-report-frontend-${{ github.run_id }}-${{ github.run_attempt }}
194+
path: frontend/coverage/BioIS/lcov.info
195+
compression-level: 9
196+
retention-days: 1
197+
if-no-files-found: error
198+
199+
upload-coverage:
200+
name: Upload Coverage Report
201+
202+
runs-on: ubuntu-24.04
203+
204+
permissions:
205+
contents: read
206+
207+
needs:
208+
- test-backend
209+
- test-frontend
210+
steps:
211+
- name: Checkout code
212+
uses: actions/checkout@v6
213+
- name: Download Backend Coverage Report
214+
uses: actions/download-artifact@v7
215+
with:
216+
artifact-ids: ${{ needs.test-backend.outputs.coverage-artifact-id }}
217+
path: backend/
218+
- name: Modify lcov paths
219+
run: |
220+
sed -i 's|SF:/__w/BioIS/BioIS/|SF:|' backend/lcov.info
221+
- name: Download Frontend Coverage Report
222+
uses: actions/download-artifact@v7
223+
with:
224+
artifact-ids: ${{ needs.test-frontend.outputs.coverage-artifact-id }}
225+
path: frontend/
226+
- name: Upload coverage to Coveralls
227+
uses: coverallsapp/github-action@v2
228+
with:
229+
github-token: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: "Lint PR"
2+
on:
3+
pull_request:
4+
types:
5+
- opened
6+
- edited
7+
8+
jobs:
9+
title:
10+
name: Title
11+
if: github.event.action == 'opened' || github.event.changes.title.from
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: geo-engine/conventional-pr-title@v1
15+
with:
16+
types: |-
17+
build
18+
ci
19+
docs
20+
feat
21+
fix
22+
perf
23+
refactor
24+
test
25+
scopes: |-
26+
api-client
27+
backend
28+
frontend

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,9 @@ target
1919
# and can be added to the global gitignore or merged into this file. For a more nuclear
2020
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
2121
#.idea/
22+
23+
.env
24+
Settings.toml
25+
26+
api-client/typescript/node_modules
27+
api-client/typescript/package-lock.json

0 commit comments

Comments
 (0)