Skip to content

Commit c08daf5

Browse files
authored
Merge pull request #286 from SpatioCore/dev-api
Added maximum request-size-limit + Health-Enpoint + Parsing `source_links` into our own Link-Structure
2 parents acaa3cc + 37b9fad commit c08daf5

20 files changed

Lines changed: 1244 additions & 74 deletions

‎api/.env.example‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ NODE_ENV=development
55

66
# Database Configuration (Debian Server)
77
# Option 1: Use DATABASE_URL (PostgreSQL connection string)
8-
# The api-user is stac_api (read-only) (stac_crawler for crawler-group)
8+
# The api-user is stac_api (read-only)
99
DATABASE_URL=postgresql://stac_api:[PASSWORD]@atlas.stacindex.org:5432/stac_db
1010

1111
# Option 2: Use individual variables (currently active)
1212
DB_HOST=atlas.stacindex.org
13-
DB_PORT=5433 # 5432 for production
13+
DB_PORT=5430 # 5432 for production
1414
DB_NAME=stac_db
1515
DB_USER=stac_api
1616
DB_PASSWORD= # Add stac_api password here (api_password)
@@ -33,3 +33,12 @@ LOG_LEVEL=debug
3333
API_TITLE=STAC Atlas
3434
API_DESCRIPTION=A centralized platform for managing, indexing, and providing STAC Collection metadata
3535
API_VERSION=1.0.0
36+
37+
# Request Size Limits
38+
# MAX_URL_LENGTH: Maximum URL length including query parameters (default: 1MB)
39+
# MAX_HEADER_SIZE: Maximum total size of all HTTP headers (default: 100KB)
40+
# MAX_BODY_SIZE: Maximum request body size for POST/PUT (default: 10MB)
41+
# Formats: "100KB", "1MB", "10MB", etc.
42+
MAX_URL_LENGTH=1MB
43+
MAX_HEADER_SIZE=100KB
44+
MAX_BODY_SIZE=10MB

‎api/__tests__/buildCollectionSearchQuery.aggregates.test.js‎

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ describe('buildCollectionSearchQuery - aggregated fields', () => {
77
// Core collection fields should be prefixed with 'c.'
88
expect(sql).toMatch(/c\.id/);
99
expect(sql).toMatch(/c\.stac_version/);
10-
expect(sql).toMatch(/c\.type/);
1110
expect(sql).toMatch(/c\.title/);
1211
expect(sql).toMatch(/c\.description/);
1312
expect(sql).toMatch(/c\.license/);
@@ -30,7 +29,6 @@ describe('buildCollectionSearchQuery - aggregated fields', () => {
3029
expect(sql).toMatch(/prov\.providers/);
3130
expect(sql).toMatch(/a\.assets/);
3231
expect(sql).toMatch(/s\.summaries/);
33-
expect(sql).toMatch(/cl\.last_crawled/);
3432
});
3533

3634
test('FROM clause uses collection alias c', () => {
@@ -94,13 +92,6 @@ describe('buildCollectionSearchQuery - aggregated fields', () => {
9492
expect(sql).toMatch(/WHERE cs\.collection_id = c\.id/);
9593
});
9694

97-
test('includes LATERAL JOIN for last_crawled timestamp', () => {
98-
const { sql } = buildCollectionSearchQuery({ limit: 10, token: 0 });
99-
100-
expect(sql).toMatch(/MAX\(clc\.last_crawled\) AS last_crawled/);
101-
expect(sql).toMatch(/FROM crawllog_collection clc/);
102-
expect(sql).toMatch(/WHERE clc\.collection_id = c\.id/);
103-
});
10495
});
10596

10697
describe('WHERE clauses use collection alias c', () => {
@@ -214,7 +205,7 @@ describe('buildCollectionSearchQuery - aggregated fields', () => {
214205
// Count LEFT JOIN LATERAL occurrences (should be 6: kw, ext, prov, a, s, cl)
215206
const leftJoinLateralCount = (sql.match(/LEFT JOIN LATERAL/gi) || []).length;
216207

217-
expect(leftJoinLateralCount).toBe(6);
208+
expect(leftJoinLateralCount).toBe(5);
218209
});
219210
});
220211
});

‎api/__tests__/buildCollectionSearchQuery.integration.test.js‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ describe('Integration: Collection Search with Aggregated Fields', () => {
4848
expect(firstRow).toHaveProperty('providers');
4949
expect(firstRow).toHaveProperty('assets');
5050
expect(firstRow).toHaveProperty('summaries');
51-
expect(firstRow).toHaveProperty('last_crawled');
5251
}
5352
});
5453
});
@@ -138,19 +137,6 @@ describe('Integration: Collection Search with Aggregated Fields', () => {
138137
}
139138
});
140139
});
141-
142-
test('last_crawled should be timestamp or null', async () => {
143-
const { sql, values } = buildCollectionSearchQuery({ limit: 10, token: 0 });
144-
const result = await query(sql, values);
145-
146-
result.rows.forEach(row => {
147-
if (row.last_crawled !== null) {
148-
// Should be a valid Date or parseable timestamp
149-
const date = new Date(row.last_crawled);
150-
expect(date.toString()).not.toBe('Invalid Date');
151-
}
152-
});
153-
});
154140
});
155141

156142
describe('Filter Compatibility with Aggregated Fields', () => {
@@ -179,7 +165,6 @@ describe('Integration: Collection Search with Aggregated Fields', () => {
179165
result.rows.forEach(row => {
180166
expect(row).toHaveProperty('stac_extensions');
181167
expect(row).toHaveProperty('summaries');
182-
expect(row).toHaveProperty('last_crawled');
183168
});
184169
});
185170

@@ -212,7 +197,6 @@ describe('Integration: Collection Search with Aggregated Fields', () => {
212197
expect(row).toHaveProperty('providers');
213198
expect(row).toHaveProperty('assets');
214199
expect(row).toHaveProperty('summaries');
215-
expect(row).toHaveProperty('last_crawled');
216200
});
217201
});
218202
});

0 commit comments

Comments
 (0)