Skip to content

Commit 8cb9037

Browse files
mikemcdougallMike McDougall
andauthored
fix: resolve formatting and naming warnings (#241) (#246)
* refactor: split FeatureServer handlers and services (#228) * chore: commit all changes * Implement GIS crosscutting updates * Sync CODEX with CLAUDE * chore: update server, tests, and docs * chore: ignore cite session outputs * chore: remove cite session artifacts * fix: remove unused edit handler and ignore cite outputs * fix: resolve formatting and naming warnings (#241) * fix: align relationships seed schema (#241) * fix(ci): stabilize js integration setup --------- Co-authored-by: Mike McDougall <[email protected]>
1 parent a9772e4 commit 8cb9037

File tree

622 files changed

+63769
-29795
lines changed

Some content is hidden

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

622 files changed

+63769
-29795
lines changed

.devcontainer/devcontainer.json

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
{
22
"name": "Honua Server Development",
3-
"dockerComposeFile": "../docker-compose.yml",
3+
"dockerComposeFile": [
4+
"../docker-compose.yml",
5+
"docker-compose.emulators.yml"
6+
],
47
"service": "honua",
58
"workspaceFolder": "/workspace",
69
"shutdownAction": "stopCompose",
10+
"runServices": [
11+
"honua",
12+
"postgres",
13+
"localstack",
14+
"azurite"
15+
],
716

817
// Configure properties specific to VS Code
918
"customizations": {
@@ -60,13 +69,23 @@
6069
"DOTNET_CLI_TELEMETRY_OPTOUT": "1",
6170
"DOTNET_SKIP_FIRST_TIME_EXPERIENCE": "1",
6271
"DOTNET_NOLOGO": "1",
63-
"DOTNET_RUNNING_IN_CONTAINER": "true"
72+
"DOTNET_RUNNING_IN_CONTAINER": "true",
73+
"HONUA_TEST_S3_BUCKET": "honua-dev-storage",
74+
"HONUA_TEST_S3_REGION": "us-east-1",
75+
"HONUA_TEST_S3_ACCESS_KEY": "test",
76+
"HONUA_TEST_S3_SECRET_KEY": "test",
77+
"HONUA_TEST_S3_SERVICE_URL": "http://localstack:4566",
78+
"HONUA_TEST_S3_FORCE_PATH_STYLE": "true",
79+
"HONUA_TEST_AZURE_BLOB_CONTAINER": "honua-dev-storage",
80+
"HONUA_TEST_AZURE_BLOB_CONNECTION_STRING": "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNoGV2qg3Xg0P/hy0p2w1szG+S0mJr+vX2eWq2A==;BlobEndpoint=http://azurite:10000/devstoreaccount1;"
6481
},
6582

6683
// Port forwarding
6784
"forwardPorts": [
6885
8080, // Honua Server
6986
5432, // PostgreSQL
87+
4566, // Localstack
88+
10000, // Azurite Blob
7089
3000, // Grafana
7190
9090, // Prometheus
7291
3100 // Loki
@@ -80,6 +99,12 @@
8099
"5432": {
81100
"label": "PostgreSQL"
82101
},
102+
"4566": {
103+
"label": "Localstack (S3)"
104+
},
105+
"10000": {
106+
"label": "Azurite Blob"
107+
},
83108
"3000": {
84109
"label": "Grafana"
85110
},
@@ -147,4 +172,4 @@
147172
"dotnet restore Honua.sln && " +
148173
"echo 'Dependencies updated!'"
149174
]
150-
}
175+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
version: '3.8'
2+
3+
services:
4+
localstack:
5+
image: localstack/localstack:3.6.0
6+
environment:
7+
SERVICES: s3
8+
DEFAULT_REGION: us-east-1
9+
AWS_DEFAULT_REGION: us-east-1
10+
AWS_ACCESS_KEY_ID: test
11+
AWS_SECRET_ACCESS_KEY: test
12+
ports:
13+
- "4566:4566"
14+
volumes:
15+
- localstack_data:/var/lib/localstack
16+
17+
azurite:
18+
image: mcr.microsoft.com/azure-storage/azurite:3.31.0
19+
command: "azurite-blob --blobHost 0.0.0.0 --blobPort 10000 --location /data --loose"
20+
ports:
21+
- "10000:10000"
22+
volumes:
23+
- azurite_data:/data
24+
25+
volumes:
26+
localstack_data:
27+
azurite_data:

.github/workflows/ci.yml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,15 +286,28 @@ jobs:
286286
);
287287
288288
CREATE TABLE IF NOT EXISTS honua.relationships (
289+
id SERIAL PRIMARY KEY,
289290
layer_id INT NOT NULL REFERENCES honua.layers(layer_id) ON DELETE CASCADE,
290291
relationship_id INT NOT NULL,
291292
name TEXT NOT NULL,
292-
related_layer_id INT NOT NULL REFERENCES honua.layers(layer_id),
293+
related_layer_id INT NOT NULL REFERENCES honua.layers(layer_id) ON DELETE CASCADE,
293294
relationship_type TEXT NOT NULL,
294295
origin_foreign_key TEXT NOT NULL,
295296
destination_foreign_key TEXT NOT NULL,
296297
description TEXT,
297-
PRIMARY KEY (layer_id, relationship_id)
298+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
299+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
300+
CONSTRAINT relationships_layer_relationship_unique UNIQUE(layer_id, relationship_id),
301+
CONSTRAINT relationships_valid_ids CHECK(layer_id >= 0 AND related_layer_id >= 0 AND relationship_id > 0),
302+
CONSTRAINT relationships_valid_fields CHECK(
303+
LENGTH(name) > 0 AND LENGTH(name) <= 128 AND
304+
LENGTH(relationship_type) > 0 AND LENGTH(relationship_type) <= 64 AND
305+
LENGTH(origin_foreign_key) > 0 AND LENGTH(origin_foreign_key) <= 128 AND
306+
LENGTH(destination_foreign_key) > 0 AND LENGTH(destination_foreign_key) <= 128
307+
),
308+
CONSTRAINT relationships_valid_type CHECK(
309+
relationship_type IN ('esriRelRoleOrigin', 'esriRelRoleDestination', 'esriRelRoleAny')
310+
)
298311
);
299312
300313
CREATE TABLE IF NOT EXISTS features (
@@ -353,7 +366,7 @@ jobs:
353366
'Test Layer',
354367
'Default layer for integration tests',
355368
'features',
356-
'GeometryCollection',
369+
'Point',
357370
4326,
358371
true
359372
)
@@ -423,6 +436,8 @@ jobs:
423436
env:
424437
ConnectionStrings__DefaultConnection: "Host=localhost;Database=honua_test;Username=honua;Password=honua"
425438
ASPNETCORE_URLS: "http://localhost:5000"
439+
Security__ConnectionEncryption__MasterKey: "test-master-key-that-is-at-least-32-characters-long-for-security"
440+
Security__ConnectionEncryption__Salt: "dGVzdC1zYWx0LWZvci1lbmNyeXB0aW9uLXRlc3RpbmctcHVycG9zZXM="
426441

427442
- name: Install JavaScript test dependencies
428443
run: npm ci

.github/workflows/cite-conformance.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ jobs:
7777
exit 1
7878
fi
7979
80+
- name: Validate advertised conformance classes
81+
run: |
82+
bash ./scripts/validate-ogc-conformance.sh --results cite-results
83+
8084
- name: Parse CITE results
8185
id: parse-results
8286
run: |
@@ -223,4 +227,4 @@ jobs:
223227
echo "❌ OGC CITE conformance tests failed"
224228
echo "Failed tests: ${{ steps.parse-results.outputs.failed_tests }}"
225229
echo "Review the test results and fix conformance issues"
226-
exit 1
230+
exit 1

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,14 @@ docs/temp/
228228
*.local.json
229229
appsettings.Development.json
230230
!appsettings.Development.json.template
231+
cite-results/cite-session-*/
232+
cite-tiles-results/cite-tiles-session-*/
233+
cite-results/*
234+
!cite-results/cite-summary.md
235+
!cite-results/conformance.json
236+
cite-tiles-results/*
237+
!cite-tiles-results/cite-summary.md
238+
!cite-tiles-results/conformance.json
231239

232240
# Environment files (keep examples, ignore actual configs)
233241
.env
@@ -241,6 +249,9 @@ appsettings.Development.json
241249
.serena/
242250
.claude/plans/
243251

252+
# Local Python test environment
253+
.venv-tests/
254+
244255
# Benchmark artifacts
245256
benchmarks/**/BenchmarkDotNet.Artifacts/
246257

@@ -249,3 +260,8 @@ benchmarks/**/BenchmarkDotNet.Artifacts/
249260

250261
# Coverage
251262
coverage*/
263+
264+
# Local runtime/test artifacts
265+
tmp/
266+
src/Honua.Server/tmp/
267+
src/Honua.Server/attachments/

CLAUDE.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
Honua Server is a greenfield implementation of a geospatial feature server supporting multiple protocols (GeoServices REST, OGC API Features, OData v4, MVT). This is a **clean rewrite** — the legacy codebase exists as reference only.
88

9+
## MVP Deferrals (Operational Simplicity)
10+
11+
The MVP intentionally defers enterprise/operational features to reduce complexity:
12+
- No app-level rate limiting; enforce at the edge (nginx/ALB/WAF).
13+
- No secure-connection allowlist or connection audit trail; secure connections are encrypted or secret references only.
14+
- No security compliance framework, audit log storage, or compliance dashboards/monitoring.
15+
916
## Critical Rules
1017

1118
### Legacy Code Reference Policy
@@ -88,6 +95,12 @@ Query_WithWhereClause_ReturnsFilteredFeatures()
8895
Query_InvalidSyntax_Returns400WithErrorDetails()
8996
```
9097

98+
**Scale Tests (Multi-Node + Redis)**:
99+
- Start the scale stack: `docker compose -f docker-compose.scale-test.yml up --build --scale honua=3`
100+
- Set env vars (inside the devcontainer): `HONUA_SCALE_TEST_BASE_URL=http://localhost:8080`, `HONUA_SCALE_TEST_REDIS=localhost:6379`
101+
- Run scale tests only: `dotnet test tests/Honua.Server.Tests/Honua.Server.Tests.csproj --filter Category=Scale`
102+
- Scale tests expect `docker/nginx/scale-test.conf` to emit `X-Instance-ID` for `/rest/`, `/ogc/`, and `/odata/`
103+
91104
### Architecture Enforcement
92105

93106
#### BLOCKING VIOLATIONS (must fix before merge)
@@ -122,7 +135,7 @@ public class FeaturesController : ControllerBase // BLOCKING - No controllers a
122135
public static void MapFeatureServerEndpoints(this WebApplication app)
123136
{
124137
app.MapGet("/rest/services/{id}/FeatureServer/{layerId}/query",
125-
async (int id, int layerId, IFeatureStore store) => { });
138+
async (int id, int layerId, IFeatureReader reader) => { });
126139
}
127140
```
128141

@@ -134,7 +147,7 @@ public class PostgresConnection { } // BLOCKING - Should be internal
134147
135148
// CORRECT: Proper encapsulation
136149
internal class FeatureRepository { } // OK - Implementation details are internal
137-
public interface IFeatureStore { } // OK - Abstractions can be public
150+
public interface IFeatureReader { } // OK - Abstractions can be public
138151
```
139152

140153
**4. Missing documentation**
@@ -180,7 +193,7 @@ src/Honua.Server/Features/
180193
```csharp
181194
// WARNING: Too many dependencies (endpoint limit: 5, handler limit: 4)
182195
public class QueryHandler(
183-
IFeatureStore store, // 1
196+
IFeatureReader reader, // 1
184197
ILayerCatalog catalog, // 2
185198
ILogger<QueryHandler> log, // 3
186199
IValidator validator, // 4
@@ -204,13 +217,13 @@ class A : B : C : D { } // WARNING: >3 levels, consider composition
204217
```csharp
205218
// GOOD: Proper dependency direction
206219
// Honua.Core defines interface
207-
public interface IFeatureStore { }
220+
public interface IFeatureReader { }
208221

209222
// Honua.Postgres implements interface
210-
internal class PostgresFeatureStore : IFeatureStore { }
223+
internal class PostgresFeatureStore : IFeatureReader { }
211224

212225
// Honua.Server uses interface
213-
public static async Task<IResult> QueryFeatures(IFeatureStore store) { }
226+
public static async Task<IResult> QueryFeatures(IFeatureReader reader) { }
214227
```
215228

216229
**2. Vertical slice organization**

CODEX.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
Honua Server is a greenfield implementation of a geospatial feature server supporting multiple protocols (GeoServices REST, OGC API Features, OData v4, MVT). This is a **clean rewrite** — the legacy codebase exists as reference only.
88

9+
## MVP Deferrals (Operational Simplicity)
10+
11+
The MVP intentionally defers enterprise/operational features to reduce complexity:
12+
- No app-level rate limiting; enforce at the edge (nginx/ALB/WAF).
13+
- No secure-connection allowlist or connection audit trail; secure connections are encrypted or secret references only.
14+
- No security compliance framework, audit log storage, or compliance dashboards/monitoring.
15+
916
## Critical Rules
1017

1118
### Legacy Code Reference Policy
@@ -88,6 +95,12 @@ Query_WithWhereClause_ReturnsFilteredFeatures()
8895
Query_InvalidSyntax_Returns400WithErrorDetails()
8996
```
9097

98+
**Scale Tests (Multi-Node + Redis)**:
99+
- Start the scale stack: `docker compose -f docker-compose.scale-test.yml up --build --scale honua=3`
100+
- Set env vars (inside the devcontainer): `HONUA_SCALE_TEST_BASE_URL=http://localhost:8080`, `HONUA_SCALE_TEST_REDIS=localhost:6379`
101+
- Run scale tests only: `dotnet test tests/Honua.Server.Tests/Honua.Server.Tests.csproj --filter Category=Scale`
102+
- Scale tests expect `docker/nginx/scale-test.conf` to emit `X-Instance-ID` for `/rest/`, `/ogc/`, and `/odata/`
103+
91104
### Architecture Enforcement
92105

93106
#### BLOCKING VIOLATIONS (must fix before merge)
@@ -122,7 +135,7 @@ public class FeaturesController : ControllerBase // BLOCKING - No controllers a
122135
public static void MapFeatureServerEndpoints(this WebApplication app)
123136
{
124137
app.MapGet("/rest/services/{id}/FeatureServer/{layerId}/query",
125-
async (int id, int layerId, IFeatureStore store) => { });
138+
async (int id, int layerId, IFeatureReader reader) => { });
126139
}
127140
```
128141

@@ -134,7 +147,7 @@ public class PostgresConnection { } // BLOCKING - Should be internal
134147
135148
// CORRECT: Proper encapsulation
136149
internal class FeatureRepository { } // OK - Implementation details are internal
137-
public interface IFeatureStore { } // OK - Abstractions can be public
150+
public interface IFeatureReader { } // OK - Abstractions can be public
138151
```
139152

140153
**4. Missing documentation**
@@ -180,7 +193,7 @@ src/Honua.Server/Features/
180193
```csharp
181194
// WARNING: Too many dependencies (endpoint limit: 5, handler limit: 4)
182195
public class QueryHandler(
183-
IFeatureStore store, // 1
196+
IFeatureReader reader, // 1
184197
ILayerCatalog catalog, // 2
185198
ILogger<QueryHandler> log, // 3
186199
IValidator validator, // 4
@@ -204,13 +217,13 @@ class A : B : C : D { } // WARNING: >3 levels, consider composition
204217
```csharp
205218
// GOOD: Proper dependency direction
206219
// Honua.Core defines interface
207-
public interface IFeatureStore { }
220+
public interface IFeatureReader { }
208221

209222
// Honua.Postgres implements interface
210-
internal class PostgresFeatureStore : IFeatureStore { }
223+
internal class PostgresFeatureStore : IFeatureReader { }
211224

212225
// Honua.Server uses interface
213-
public static async Task<IResult> QueryFeatures(IFeatureStore store) { }
226+
public static async Task<IResult> QueryFeatures(IFeatureReader reader) { }
214227
```
215228

216229
**2. Vertical slice organization**

0 commit comments

Comments
 (0)