From 243c351e0eca2eefabf5069b7200410b5974e1b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Hoffmann?= Date: Tue, 2 Dec 2025 07:42:54 +0100 Subject: [PATCH 01/13] added `.env` --- db/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/db/.gitignore b/db/.gitignore index e69de29..2eea525 100644 --- a/db/.gitignore +++ b/db/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file From 40422c957f746ae80659d8248398321301b13443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Hoffmann?= Date: Tue, 2 Dec 2025 07:54:00 +0100 Subject: [PATCH 02/13] added environment for docker-compose.yml now every connection-details are inside an `.env`. There is an `example.env` for better understanding which need to be set as connection details --- db/docker-compose.yml | 10 ++++++---- db/example.env | 7 +++++++ 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 db/example.env diff --git a/db/docker-compose.yml b/db/docker-compose.yml index 4c74f91..12c20f8 100644 --- a/db/docker-compose.yml +++ b/db/docker-compose.yml @@ -3,14 +3,16 @@ services: image: postgis/postgis:16-3.4 container_name: stac_db restart: always + env_file: + - .env environment: - POSTGRES_DB: stac_db - POSTGRES_USER: stac_user - POSTGRES_PASSWORD: stac_password + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - - "5432:5432" + - "${DB_PORT}:5432" volumes: - stac_data:/var/lib/postgresql/data diff --git a/db/example.env b/db/example.env new file mode 100644 index 0000000..e175b0b --- /dev/null +++ b/db/example.env @@ -0,0 +1,7 @@ +# PostgreSQL Database Configuration +POSTGRES_DB= # stac_db is the database we are running on +POSTGRES_USER= # add postgres_user here +POSTGRES_PASSWORD= # add postgres_password here + +# Database Port (host:container) +DB_PORT= # 5432 / 5433 (at the moment both are available) \ No newline at end of file From b02ad17ca68d168ea940ea978e81e2286cf7a810 Mon Sep 17 00:00:00 2001 From: SonkeHoffmann Date: Tue, 2 Dec 2025 13:04:49 +0100 Subject: [PATCH 03/13] added description of how to use the `.env` and `example.env` in the `README.md` --- db/README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/db/README.md b/db/README.md index da1c603..435aea0 100644 --- a/db/README.md +++ b/db/README.md @@ -59,11 +59,12 @@ Comprehensive indexing for optimal query performance: ```bash cd ./db/ docker-compose up +``` ### Connection Details - **Host**: `atlas.stacindex.org` -- **Port**: `5432` +- **Port**: `5432` and `5433` ## Port Configuration @@ -71,15 +72,18 @@ This project exposes the database service on a port that can be changed. Update The database uses port mapping in the format `HOST:CONTAINER`: - **`5432:5432`** means: - - Left side (`5432`): Port on your local machine (host) + - Left side (`5432`): Port on your local machine (host) (must be changed in the `.env`) - Right side (`5432`): Port inside the Docker container -What to change in the Docker Compose file +What to change the environment parameters in the Docker Compose file - Open the `docker-compose.yml`. -- Locate the `ports:` and change the host side: +- Locate e.g. `ports:` and change the host side: - Format: `":"` - Example: change `5432:5432` to `15432:5432` to expose the container's 5432 on host port 15432. -- TODO: If the compose file references environment variables (e.g. `${DB_PORT}`), change the value in the corresponding `.env` file. +- If the compose file references environment variables (e.g. `${DB_PORT}`), change the value in the corresponding `.env` file. +**Important**: Do not modify the `docker-compose.yml` file directly. Instead, update the port configuration in the `.env` file by changing the `DB_PORT`, `POSTGRES_DB`, `POSTGRES_USER` and `POSTGRES_PASSWORD` variable, then restart the service with `docker-compose up`. +- The change in the `.env` does not count for the , you can change that directly in the `docker-compose.yml` if needed. +- There is an `example.env` provided that can be renamed into `.env` and then modified. ## Initialization Scripts From 9005ccc49b9d2fdc3c9d4edca6ee173cfccdd726 Mon Sep 17 00:00:00 2001 From: SonkeHoffmann Date: Tue, 2 Dec 2025 13:15:30 +0100 Subject: [PATCH 04/13] changed a few things e.g. DB_PORT --> ${DB_PORT} --- db/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/README.md b/db/README.md index 435aea0..c9e4f69 100644 --- a/db/README.md +++ b/db/README.md @@ -79,9 +79,9 @@ What to change the environment parameters in the Docker Compose file - Open the `docker-compose.yml`. - Locate e.g. `ports:` and change the host side: - Format: `":"` -- Example: change `5432:5432` to `15432:5432` to expose the container's 5432 on host port 15432. +- Example: change `5432:5432` to `5433:5432` to expose the container's 5432 on host port 5433. - If the compose file references environment variables (e.g. `${DB_PORT}`), change the value in the corresponding `.env` file. -**Important**: Do not modify the `docker-compose.yml` file directly. Instead, update the port configuration in the `.env` file by changing the `DB_PORT`, `POSTGRES_DB`, `POSTGRES_USER` and `POSTGRES_PASSWORD` variable, then restart the service with `docker-compose up`. +**Important**: Do not modify the `docker-compose.yml` file directly. Instead, update the port configuration in the `.env` file by changing the `${DB_PORT}`, `${POSTGRES_DB}`, `${POSTGRES_USER}` and `${POSTGRES_PASSWORD}` variable, then restart the service with `docker-compose up`. - The change in the `.env` does not count for the , you can change that directly in the `docker-compose.yml` if needed. - There is an `example.env` provided that can be renamed into `.env` and then modified. From eee44db375229e10651b25aed9a53072994ad195 Mon Sep 17 00:00:00 2001 From: SonkeHoffmann Date: Tue, 2 Dec 2025 13:17:35 +0100 Subject: [PATCH 05/13] now, everthing should be done. my god, help. sorry --- db/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/README.md b/db/README.md index c9e4f69..6ddad08 100644 --- a/db/README.md +++ b/db/README.md @@ -82,7 +82,7 @@ What to change the environment parameters in the Docker Compose file - Example: change `5432:5432` to `5433:5432` to expose the container's 5432 on host port 5433. - If the compose file references environment variables (e.g. `${DB_PORT}`), change the value in the corresponding `.env` file. **Important**: Do not modify the `docker-compose.yml` file directly. Instead, update the port configuration in the `.env` file by changing the `${DB_PORT}`, `${POSTGRES_DB}`, `${POSTGRES_USER}` and `${POSTGRES_PASSWORD}` variable, then restart the service with `docker-compose up`. -- The change in the `.env` does not count for the , you can change that directly in the `docker-compose.yml` if needed. +- The change in the `.env` does not count for the ``, you can change that directly in the `docker-compose.yml` if needed. - There is an `example.env` provided that can be renamed into `.env` and then modified. ## Initialization Scripts From aecce7e06f5f86920c7890ce315bb6c5bdd10db5 Mon Sep 17 00:00:00 2001 From: SonkeHoffmann Date: Tue, 2 Dec 2025 13:20:57 +0100 Subject: [PATCH 06/13] layout issues fixed --- db/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/db/README.md b/db/README.md index 6ddad08..0e83708 100644 --- a/db/README.md +++ b/db/README.md @@ -81,6 +81,7 @@ What to change the environment parameters in the Docker Compose file - Format: `":"` - Example: change `5432:5432` to `5433:5432` to expose the container's 5432 on host port 5433. - If the compose file references environment variables (e.g. `${DB_PORT}`), change the value in the corresponding `.env` file. + **Important**: Do not modify the `docker-compose.yml` file directly. Instead, update the port configuration in the `.env` file by changing the `${DB_PORT}`, `${POSTGRES_DB}`, `${POSTGRES_USER}` and `${POSTGRES_PASSWORD}` variable, then restart the service with `docker-compose up`. - The change in the `.env` does not count for the ``, you can change that directly in the `docker-compose.yml` if needed. - There is an `example.env` provided that can be renamed into `.env` and then modified. From 7a885ce0e85cc1dcf8a9cce20f272069ab0e426d Mon Sep 17 00:00:00 2001 From: Robin Tammo Gummels Date: Tue, 2 Dec 2025 14:16:36 +0100 Subject: [PATCH 07/13] Fixed Typo/incomplete Sentence in README.md --- db/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/README.md b/db/README.md index 0e83708..05e1542 100644 --- a/db/README.md +++ b/db/README.md @@ -75,7 +75,7 @@ The database uses port mapping in the format `HOST:CONTAINER`: - Left side (`5432`): Port on your local machine (host) (must be changed in the `.env`) - Right side (`5432`): Port inside the Docker container -What to change the environment parameters in the Docker Compose file +How to change the environment parameters in the Docker Compose file - Open the `docker-compose.yml`. - Locate e.g. `ports:` and change the host side: - Format: `":"` From a4ed54f7973d1e9bcecb29571e9d663a7aa9f30d Mon Sep 17 00:00:00 2001 From: SonkeHoffmann Date: Thu, 4 Dec 2025 13:16:40 +0100 Subject: [PATCH 08/13] added `stac_id` for collections --- db/init/03_tables_collections.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/db/init/03_tables_collections.sql b/db/init/03_tables_collections.sql index 0fd6197..e5e2c0f 100644 --- a/db/init/03_tables_collections.sql +++ b/db/init/03_tables_collections.sql @@ -6,6 +6,7 @@ CREATE TABLE collection ( id SERIAL PRIMARY KEY, stac_version TEXT, + stac_id INTEGER, type TEXT, title TEXT, description TEXT, From 0bd589ed2efc168ab5f0d02a20c892b3db796ee1 Mon Sep 17 00:00:00 2001 From: SonkeHoffmann Date: Thu, 4 Dec 2025 13:20:38 +0100 Subject: [PATCH 09/13] all IDs are now written in the newer PostgrSQL standart: ```SQL id SERIAL PRIMARY KEY, ``` changed to ```SQL id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, ``` --- db/init/02_tables_catalog.sql | 10 +++++----- db/init/03_tables_collections.sql | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/db/init/02_tables_catalog.sql b/db/init/02_tables_catalog.sql index 9078d24..a44355f 100644 --- a/db/init/02_tables_catalog.sql +++ b/db/init/02_tables_catalog.sql @@ -3,7 +3,7 @@ -- Main catalog table: Stores STAC catalog metadata including version, type, title, and description -- Each catalog represents a STAC catalog endpoint that has been discovered and indexed CREATE TABLE catalog ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, stac_version TEXT, type TEXT, title TEXT, @@ -15,7 +15,7 @@ CREATE TABLE catalog ( -- Catalog links table: Stores related links for catalogs (e.g., self, root, child, item links) -- Links define the navigation structure between STAC resources CREATE TABLE catalog_links ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, catalog_id INTEGER REFERENCES catalog(id) ON DELETE CASCADE, rel TEXT, href TEXT, @@ -26,21 +26,21 @@ CREATE TABLE catalog_links ( -- Keywords lookup table: Stores unique searchable keywords -- Used by both catalogs and collections for categorization and search CREATE TABLE keywords ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, keyword TEXT UNIQUE ); -- STAC extensions lookup table: Stores unique STAC extension identifiers -- Extensions provide additional standardized fields beyond core STAC spec CREATE TABLE stac_extensions ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, stac_extension TEXT UNIQUE ); -- Crawl log for catalogs: Tracks when each catalog was last crawled for updates -- Used to schedule re-crawling and maintain freshness of catalog data CREATE TABLE crawllog_catalog ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, catalog_id INTEGER REFERENCES catalog(id) ON DELETE CASCADE, last_crawled TIMESTAMP ); diff --git a/db/init/03_tables_collections.sql b/db/init/03_tables_collections.sql index e5e2c0f..3d0fff0 100644 --- a/db/init/03_tables_collections.sql +++ b/db/init/03_tables_collections.sql @@ -4,7 +4,7 @@ -- Collections group related STAC items and define their common properties -- full_json: Complete JSONB representation the whole collection CREATE TABLE collection ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, stac_version TEXT, stac_id INTEGER, type TEXT, @@ -28,7 +28,7 @@ CREATE TABLE collection ( -- represent ranges (min/max), sets of values, or JSON schemas -- Used to describe the range of values found in collection items CREATE TABLE collection_summaries ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, collection_id INTEGER REFERENCES collection(id) ON DELETE CASCADE, name TEXT, kind TEXT, @@ -41,14 +41,14 @@ CREATE TABLE collection_summaries ( -- Providers lookup table: Stores unique data provider names -- Providers are organizations or entities that produce, host, or process the data CREATE TABLE providers ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, provider TEXT UNIQUE ); -- Assets table: Stores downloadable assets (data files, thumbnails, metadata files, etc.) -- Assets are the actual data products or resources associated with collections CREATE TABLE assets ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, name TEXT, href TEXT, type TEXT, @@ -60,7 +60,7 @@ CREATE TABLE assets ( -- Used to schedule re-crawling and maintain freshness of collection data -- (same usecase as the crawllog for catalogs) CREATE TABLE crawllog_collection ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY, collection_id INTEGER REFERENCES collection(id) ON DELETE CASCADE, last_crawled TIMESTAMP ); From 49dd72001b2edb88f6fc89d94fc615212967edb7 Mon Sep 17 00:00:00 2001 From: SonkeHoffmann Date: Thu, 4 Dec 2025 13:32:36 +0100 Subject: [PATCH 10/13] changed `extend` to `extent`. --- db/init/03_tables_collections.sql | 6 +++--- db/init/05_indexes.sql | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/db/init/03_tables_collections.sql b/db/init/03_tables_collections.sql index 3d0fff0..733bb08 100644 --- a/db/init/03_tables_collections.sql +++ b/db/init/03_tables_collections.sql @@ -14,9 +14,9 @@ CREATE TABLE collection ( created_at TIMESTAMP DEFAULT now(), updated_at TIMESTAMP DEFAULT now(), - spatial_extend GEOMETRY(POLYGON, 4326), - temporal_extend_start TIMESTAMP, - temporal_extend_end TIMESTAMP, + spatial_extent GEOMETRY(POLYGON, 4326), + temporal_extent_start TIMESTAMP, + temporal_extent_end TIMESTAMP, is_api BOOLEAN DEFAULT FALSE, is_active BOOLEAN DEFAULT TRUE, diff --git a/db/init/05_indexes.sql b/db/init/05_indexes.sql index 76a750f..9349b88 100644 --- a/db/init/05_indexes.sql +++ b/db/init/05_indexes.sql @@ -25,10 +25,10 @@ CREATE INDEX idx_crawllog_catalog_last ON crawllog_catalog (last_crawled); -- Basic collection lookups CREATE INDEX idx_collection_title ON collection (title); -CREATE INDEX idx_collection_temp ON collection (temporal_extend_start, temporal_extend_end); +CREATE INDEX idx_collection_temp ON collection (temporal_extent_start, temporal_extent_end); CREATE INDEX idx_collection_active ON collection (is_active); -CREATE INDEX idx_collection_spatial ON collection USING GIST (spatial_extend); +CREATE INDEX idx_collection_spatial ON collection USING GIST (spatial_extent); CREATE INDEX idx_collection_fulltext ON collection USING GIN (to_tsvector('simple', coalesce(title,'') || ' ' || coalesce(description,''))); From 0b396e3138d8ee4390d967f6916ce2d940207443 Mon Sep 17 00:00:00 2001 From: RobinGummels Date: Sun, 14 Dec 2025 11:33:40 +0100 Subject: [PATCH 11/13] Changed language used in `./api/README.md` from german to english. I wanted to thsi anyway at some point, but this is now more like a Test-commit to see if the CI/CD Pipeline triggers... --- api/README.md | 138 +++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/api/README.md b/api/README.md index aff0ae1..96d89e2 100644 --- a/api/README.md +++ b/api/README.md @@ -1,88 +1,88 @@ # STAC Atlas API -STAC-konforme API fΓΌr die Verwaltung und Bereitstellung von STAC Collection Metadaten. +STAC-compliant API for managing and serving STAC Collection metadata. -## πŸš€ Schnellstart +## πŸš€ Quick Start -### Voraussetzungen +### Prerequisites - Node.js >= 22.0.0 -- PostgreSQL mit PostGIS Extension -- npm oder yarn +- PostgreSQL with PostGIS extension +- npm or yarn ### Installation ```bash -# Dependencies installieren +# Install dependencies npm install -# Umgebungsvariablen konfigurieren +# Configure environment variables cp .env.example .env -# .env bearbeiten und DATABASE_URL etc. anpassen +# Edit .env and set DATABASE_URL etc. ``` -### Entwicklung +### Development ```bash -# Development Server mit Auto-Reload starten +# Start development server with auto-reload npm run dev -# Oder Production Server +# Or start production server npm start ``` -Die API lΓ€uft dann auf `http://localhost:3000` +The API will be available at `http://localhost:3000`. ### Tests ```bash -# Alle Tests ausfΓΌhren +# Run all tests npm test -# Tests im Watch-Mode +# Run tests in watch mode npm run test:watch ``` -### Code-QualitΓ€t +### Code Quality ```bash # Linting npm run lint -# Automatisches Fixing +# Automatic fixing npm run lint:fix -# Code formatieren +# Code formatting npm run format ``` ## CI/CD Pipeline -This Project uses GitHub Actions for Continous Integration: +This project uses GitHub Actions for Continuous Integration: -- **Automatic Tests** at every push and pull request -- **Branch Protection** prevent merges if tests failed -- **Code Quality Checks** (ESLint, Tests, Build-Validation) -- **Test Coverage Reports** as artifacts +- **Automated tests** on every push and pull request +- **Branch protection** prevents merges if tests fail +- **Code quality checks** (ESLint, tests, build validation) +- **Test coverage reports** as artifacts **Status:** ![CI Status](https://github.com/SpatioCore/STAC-Atlas/workflows/API%20CI%2FCD%20Pipeline/badge.svg?branch=dev-api) -## πŸ“‹ API Endpunkte +## πŸ“‹ API Endpoints ### Core Endpoints -| Methode | Endpoint | Beschreibung | +| Method | Endpoint | Description | |---------|----------|--------------| -| GET | `/` | Landing Page (STAC Catalog Root) | -| GET | `/conformance` | Conformance Classes | -| GET | `/collections` | Liste aller Collections (mit Filterung) | -| POST | `/collections` | Collection Search mit CQL2 | -| GET | `/collections/:id` | Einzelne Collection abrufen | -| GET | `/collections-queryables` | Queryable Properties Schema | +| GET | `/` | Landing page (STAC catalog root) | +| GET | `/conformance` | Conformance classes | +| GET | `/collections` | List all collections (with filtering) | +| POST | `/collections` | Collection search with CQL2 | +| GET | `/collections/:id` | Retrieve a single collection | +| GET | `/collections-queryables` | Queryable properties schema | ### Query Parameters (GET /collections) -Die Collection Search API unterstΓΌtzt folgende Query-Parameter: +The collection search API supports the following query parameters: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| @@ -93,7 +93,7 @@ Die Collection Search API unterstΓΌtzt folgende Query-Parameter: | `sortby` | String | No | Sort by field: `+/-field` (title, id, license, created, updated) | | `token` | Integer | No | Pagination token (offset, default: 0) | -**Beispiele:** +**Examples:** ```bash # Free-text search GET /collections?q=sentinel @@ -105,45 +105,45 @@ GET /collections?bbox=-10,40,10,50&datetime=2020-01-01/2021-12-31 GET /collections?limit=20&sortby=-created&token=2 ``` -πŸ“– **Detaillierte Dokumentation:** Siehe [docs/collection-search-parameters.md](docs/collection-search-parameters.md) +πŸ“– **Detailed documentation:** See [docs/collection-search-parameters.md](docs/collection-search-parameters.md) -### API Dokumentation +### API Documentation -- **Swagger UI**: `http://localhost:3000/api-docs` (wenn `docs/openapi.yaml` existiert) +- **Swagger UI**: `http://localhost:3000/api-docs` (if `docs/openapi.yaml` exists) - **OpenAPI Spec**: `docs/openapi.yaml` -## πŸ—οΈ Projektstruktur +## πŸ—οΈ Project Structure ``` api/ β”œβ”€β”€ bin/ -β”‚ └── www # Server-Startskript +β”‚ └── www # Server start script β”œβ”€β”€ config/ -β”‚ └── conformanceURIS.js # STAC Conformance URIs +β”‚ └── conformanceURIS.js # STAC conformance URIs β”œβ”€β”€ data/ β”‚ └── collections.js # Test collections β”œβ”€β”€ docs/ -β”‚ └── collection-search-parameters.md # Query Parameter Dokumentation +β”‚ └── collection-search-parameters.md # Query parameter documentation β”œβ”€β”€ middleware/ -β”‚ └── validateCollectionSearch.js # Query Parameter Validation +β”‚ └── validateCollectionSearch.js # Query parameter validation β”œβ”€β”€ routes/ -β”‚ β”œβ”€β”€ index.js # Landing Page (/) -β”‚ β”œβ”€β”€ conformance.js # Conformance Classes -β”‚ β”œβ”€β”€ collections.js # Collections Endpoints -β”‚ └── queryables.js # Queryables Schema +β”‚ β”œβ”€β”€ index.js # Landing page (/) +β”‚ β”œβ”€β”€ conformance.js # Conformance classes +β”‚ β”œβ”€β”€ collections.js # Collections endpoints +β”‚ └── queryables.js # Queryables schema β”œβ”€β”€ validators/ -β”‚ └── collectionSearchParams.js # Parameter Validators +β”‚ └── collectionSearchParams.js # Parameter validators β”œβ”€β”€ __tests__/ -β”‚ └── api.test.js # API Tests +β”‚ └── api.test.js # API tests β”œβ”€β”€ app.js # Express App Setup β”œβ”€β”€ package.json -β”œβ”€β”€ .env.example # Beispiel-Umgebungsvariablen +β”œβ”€β”€ .env.example # Example environment variables └── README.md ``` -## πŸ”§ Konfiguration +## πŸ”§ Configuration -Alle Konfigurationen erfolgen ΓΌber Umgebungsvariablen (`.env`): +All configuration is managed via environment variables (`.env`): ```env PORT=3000 @@ -154,46 +154,46 @@ CORS_ORIGIN=* ## πŸ§ͺ STAC Conformance -Diese API implementiert: +This API implements: - βœ… STAC API Core (v1.0.0) - βœ… OGC API Features Core - βœ… STAC Collections - βœ… Collection Search Extension -- 🚧 CQL2 Basic Filtering (in Entwicklung) -- 🚧 CQL2 Advanced Operators (in Entwicklung) +- 🚧 CQL2 Basic Filtering (in development) +- 🚧 CQL2 Advanced Operators (in development) -## πŸ“¦ NΓ€chste Schritte +## πŸ“¦ Next Steps ### TODO -- [ ] Datenbank-Integration (PostgreSQL + PostGIS) +- [ ] Database integration (PostgreSQL + PostGIS) - [ ] Implement q (full-text search with TSVector) - [ ] Implement bbox (PostGIS spatial queries) - [ ] Implement datetime (temporal overlap queries) - [ ] Implement sortby (ORDER BY in SQL) -- [ ] CQL2-Parser Integration (cql2-rs via WASM) -- [ ] Controller-Layer implementieren -- [ ] Service-Layer fΓΌr Business Logic -- [ ] OpenAPI Dokumentation vervollstΓ€ndigen -- [ ] Erweiterte Tests (Integration, E2E) +- [ ] CQL2 parser integration (cql2-rs via WASM) +- [ ] Implement controller layer +- [ ] Service layer for business logic +- [ ] Complete OpenAPI documentation +- [ ] Advanced tests (integration, E2E) - [ ] Unit tests for validators - [ ] Integration tests for filtered queries -- [ ] Docker Setup -- [ ] CI/CD Pipeline +- [ ] Docker setup +- [ ] CI/CD pipeline -### Implementierungsplan (siehe bid.md) +### Implementation Plan (see bid.md) -1. βœ… **AP-01**: Projekt-Skeleton & Infrastruktur -2. βœ… **AP-02**: Query Parameter Validation (q, bbox, datetime, limit, sortby, token) -3. 🚧 **AP-03**: STAC-Core Endpunkte (Basis vorhanden) -4. 🚧 **AP-04**: Collection Search – Filter-Implementierung (DB-Integration pending) -5. ⏳ **AP-05**: CQL2-Filtering Integration +1. βœ… **AP-01**: Project skeleton & infrastructure +2. βœ… **AP-02**: Query parameter validation (q, bbox, datetime, limit, sortby, token) +3. 🚧 **AP-03**: STAC core endpoints (baseline implemented) +4. 🚧 **AP-04**: Collection search – filter implementation (DB integration pending) +5. ⏳ **AP-05**: CQL2 filtering integration -## πŸ“„ Lizenz +## πŸ“„ License Apache-2.0 ## πŸ‘₯ Team -STAC Atlas API Team - Robin (Teamleiter), Jonas, George, Vincent +STAC Atlas API Team β€” Robin (Team lead), Jonas, George, Vincent From 9e9bc3090c3b1fe51fdd002809f5846872a11157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Hoffmann?= Date: Sat, 3 Jan 2026 19:30:07 +0100 Subject: [PATCH 12/13] added triggering function for an auto-update search_vector, both for collections and catalogs. The search_vector includes title, description and keywords --- db/init/02_tables_catalog.sql | 64 ++++++++++++++++++++++++++++++- db/init/03_tables_collections.sql | 64 ++++++++++++++++++++++++++++++- db/init/05_indexes.sql | 8 ++-- 3 files changed, 130 insertions(+), 6 deletions(-) diff --git a/db/init/02_tables_catalog.sql b/db/init/02_tables_catalog.sql index a44355f..3098cd3 100644 --- a/db/init/02_tables_catalog.sql +++ b/db/init/02_tables_catalog.sql @@ -9,7 +9,8 @@ CREATE TABLE catalog ( title TEXT, description TEXT, created_at TIMESTAMP DEFAULT now(), - updated_at TIMESTAMP DEFAULT now() + updated_at TIMESTAMP DEFAULT now(), + search_vector tsvector ); -- Catalog links table: Stores related links for catalogs (e.g., self, root, child, item links) @@ -44,3 +45,64 @@ CREATE TABLE crawllog_catalog ( catalog_id INTEGER REFERENCES catalog(id) ON DELETE CASCADE, last_crawled TIMESTAMP ); + +-- ======================================== +-- FULL-TEXT SEARCH TRIGGERS +-- ======================================== + +-- Trigger function to auto-update search_vector when catalog is inserted or updated +-- Includes title, description, and all associated keywords for comprehensive search +CREATE OR REPLACE FUNCTION update_catalog_search_vector() +RETURNS TRIGGER AS $$ +BEGIN + NEW.search_vector := to_tsvector('simple', + coalesce(NEW.title, '') || ' ' || + coalesce(NEW.description, '') || ' ' || + coalesce( + ( + SELECT string_agg(k.keyword, ' ') + FROM catalog_keywords ck + JOIN keywords k ON k.id = ck.keyword_id + WHERE ck.catalog_id = NEW.id + ), + '' + ) + ); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER catalog_search_vector_update +BEFORE INSERT OR UPDATE ON catalog +FOR EACH ROW +EXECUTE FUNCTION update_catalog_search_vector(); + +-- Trigger function to update search_vector when keywords are added/removed +-- Ensures search index stays in sync with keyword changes +CREATE OR REPLACE FUNCTION update_catalog_search_vector_on_keyword_change() +RETURNS TRIGGER AS $$ +BEGIN + UPDATE catalog + SET search_vector = to_tsvector('simple', + coalesce(title, '') || ' ' || + coalesce(description, '') || ' ' || + coalesce( + ( + SELECT string_agg(k.keyword, ' ') + FROM catalog_keywords ck + JOIN keywords k ON k.id = ck.keyword_id + WHERE ck.catalog_id = catalog.id + ), + '' + ) + ) + WHERE id = COALESCE(NEW.catalog_id, OLD.catalog_id); + + RETURN COALESCE(NEW, OLD); +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER catalog_keywords_update_vector +AFTER INSERT OR DELETE ON catalog_keywords +FOR EACH ROW +EXECUTE FUNCTION update_catalog_search_vector_on_keyword_change(); diff --git a/db/init/03_tables_collections.sql b/db/init/03_tables_collections.sql index 733bb08..1f72ab7 100644 --- a/db/init/03_tables_collections.sql +++ b/db/init/03_tables_collections.sql @@ -21,7 +21,8 @@ CREATE TABLE collection ( is_api BOOLEAN DEFAULT FALSE, is_active BOOLEAN DEFAULT TRUE, - full_json JSONB + full_json JSONB, + search_vector tsvector ); -- Collection summaries: Stores summaries for collection properties @@ -64,3 +65,64 @@ CREATE TABLE crawllog_collection ( collection_id INTEGER REFERENCES collection(id) ON DELETE CASCADE, last_crawled TIMESTAMP ); + +-- ======================================== +-- FULL-TEXT SEARCH TRIGGERS +-- ======================================== + +-- Trigger function to auto-update search_vector when collection is inserted or updated +-- Includes title, description, and all associated keywords for comprehensive search +CREATE OR REPLACE FUNCTION update_collection_search_vector() +RETURNS TRIGGER AS $$ +BEGIN + NEW.search_vector := to_tsvector('simple', + coalesce(NEW.title, '') || ' ' || + coalesce(NEW.description, '') || ' ' || + coalesce( + ( + SELECT string_agg(k.keyword, ' ') + FROM collection_keywords ck + JOIN keywords k ON k.id = ck.keyword_id + WHERE ck.collection_id = NEW.id + ), + '' + ) + ); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER collection_search_vector_update +BEFORE INSERT OR UPDATE ON collection +FOR EACH ROW +EXECUTE FUNCTION update_collection_search_vector(); + +-- Trigger function to update search_vector when keywords are added/removed +-- Ensures search index stays in sync with keyword changes +CREATE OR REPLACE FUNCTION update_collection_search_vector_on_keyword_change() +RETURNS TRIGGER AS $$ +BEGIN + UPDATE collection + SET search_vector = to_tsvector('simple', + coalesce(title, '') || ' ' || + coalesce(description, '') || ' ' || + coalesce( + ( + SELECT string_agg(k.keyword, ' ') + FROM collection_keywords ck + JOIN keywords k ON k.id = ck.keyword_id + WHERE ck.collection_id = collection.id + ), + '' + ) + ) + WHERE id = COALESCE(NEW.collection_id, OLD.collection_id); + + RETURN COALESCE(NEW, OLD); +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER collection_keywords_update_vector +AFTER INSERT OR DELETE ON collection_keywords +FOR EACH ROW +EXECUTE FUNCTION update_collection_search_vector_on_keyword_change(); diff --git a/db/init/05_indexes.sql b/db/init/05_indexes.sql index 9349b88..7c0d74a 100644 --- a/db/init/05_indexes.sql +++ b/db/init/05_indexes.sql @@ -9,8 +9,8 @@ CREATE INDEX idx_catalog_title ON catalog (title); CREATE INDEX idx_catalog_updated_at ON catalog (updated_at); -CREATE INDEX idx_catalog_fulltext ON catalog -USING GIN (to_tsvector('simple', coalesce(title,'') || ' ' || coalesce(description,''))); +-- Full-text search index on computed search_vector column (includes title, description, and keywords) +CREATE INDEX idx_catalog_search_vector ON catalog USING GIN (search_vector); CREATE INDEX idx_catalog_links_catalog_id ON catalog_links (catalog_id); CREATE INDEX idx_catalog_keywords_catalog ON catalog_keywords (catalog_id); @@ -30,8 +30,8 @@ CREATE INDEX idx_collection_active ON collection (is_active); CREATE INDEX idx_collection_spatial ON collection USING GIST (spatial_extent); -CREATE INDEX idx_collection_fulltext ON collection -USING GIN (to_tsvector('simple', coalesce(title,'') || ' ' || coalesce(description,''))); +-- Full-text search index on computed search_vector column (includes title, description, and keywords) +CREATE INDEX idx_collection_search_vector ON collection USING GIN (search_vector); CREATE INDEX idx_collection_jsonb ON collection USING GIN (full_json); From b7d51a26d0df836df4333148ddf2e3f9535fa71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Hoffmann?= Date: Sat, 3 Jan 2026 19:41:50 +0100 Subject: [PATCH 13/13] changed the CI-Pipeline. Now also Changes in the /db will be acceped by the Pipeline --- .github/workflows/api-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/api-ci.yml b/.github/workflows/api-ci.yml index 5394698..1b49ad6 100644 --- a/.github/workflows/api-ci.yml +++ b/.github/workflows/api-ci.yml @@ -9,6 +9,7 @@ on: - main paths: - 'api/**' + - 'db/**' - '.github/workflows/api-ci.yml' pull_request: branches: @@ -17,6 +18,7 @@ on: - main paths: - 'api/**' + - 'db/**' - '.github/workflows/api-ci.yml' jobs: