Prepare GeoIntel for public release
Managed validation / Managed repository validation (pull_request) Successful in 1m46s
GeoIntel release gates / Compile, test, contracts and builds (pull_request) Successful in 1m51s
GeoIntel release gates / Python and npm vulnerability policy (pull_request) Successful in 20s
GeoIntel release gates / Production AI image, SBOM and container scan (pull_request) Successful in 15m3s
GeoIntel release gates / Deploy exact gated revision to Unraid (pull_request) Skipped

This commit is contained in:
Jens
2026-08-31 21:33:10 +02:00
parent dcd67b11d1
commit 2cdf9c99c6
195 changed files with 595 additions and 207595 deletions
+13
View File
@@ -269,6 +269,19 @@ def guest_login(
status_code=status.HTTP_403_FORBIDDEN,
)
client_host = _client_host(request)
retry_after = AuthService.consume_guest_request(
f"guest-login:{client_host}",
max_requests=settings.guest_login_requests_per_minute,
)
if retry_after:
raise AppError(
code="GUEST_LOGIN_RATE_LIMITED",
message="Too many guest sessions were requested. Try again later.",
details={"retry_after_seconds": retry_after},
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
)
demo = DemoWorkflowService.seed(db)
token = AuthService.create_session_token(
settings.guest_display_name,
+7
View File
@@ -10,6 +10,7 @@ from fastapi import UploadFile
from sqlalchemy.orm import Session
from app.core.config import get_settings
from app.core.errors import AppError
from app.core.public_demo import is_public_demo_project
from app.db.session import get_db
from app.models import Area, Project
from app.schemas import (
@@ -163,6 +164,12 @@ async def upload_dataset(
source_version: str | None = Form(None),
db: Session = Depends(get_db),
):
if is_public_demo_project(project_id):
raise AppError(
code="PUBLIC_DEMO_UPLOAD_FORBIDDEN",
message="Operator uploads are not accepted in the public demo project.",
status_code=403,
)
if area_id is not None:
area = db.get(Area, area_id)
if not area:
+2
View File
@@ -55,12 +55,14 @@ def get_yolo_preflight(
tile_manifest_path: str | None = None,
check_model_load: bool = False,
model_asset_id: str | None = None,
db: Session = Depends(get_db),
) -> dict:
return envelope(
YoloPreflightService.run(
tile_manifest_path=tile_manifest_path,
check_model_load=check_model_load,
model_asset_id=model_asset_id,
db=db,
)
)
+6 -14
View File
@@ -47,21 +47,18 @@ def _database_checks() -> dict[str, str]:
with get_engine().connect() as connection:
connection.execute(text("SELECT 1"))
checks["database"] = "ok"
postgis_version = connection.execute(
connection.execute(
text("SELECT PostGIS_Version()")
).scalar_one()
checks["postgis"] = f"ok:{postgis_version}"
checks["postgis"] = "ok"
database_head = connection.execute(
text("SELECT version_num FROM alembic_version")
).scalar_one()
expected_heads = _expected_migration_heads()
if len(expected_heads) == 1 and database_head == expected_heads[0]:
checks["migration"] = f"ok:{database_head}"
checks["migration"] = "ok"
else:
checks["migration"] = (
f"degraded:database={database_head};"
f"expected={','.join(expected_heads) or 'none'}"
)
checks["migration"] = "degraded"
except Exception:
return checks
return checks
@@ -94,9 +91,7 @@ def _readiness_payload() -> HealthResponse:
return HealthResponse(
status="ok" if ready else "degraded",
service="geointel-backend",
version=settings.app_version,
build_sha=settings.build_sha,
build_time=settings.build_time,
version="public",
database=checks["database"],
postgis=checks["postgis"],
migration=checks["migration"],
@@ -107,13 +102,10 @@ def _readiness_payload() -> HealthResponse:
@router.get("/health/live", response_model=HealthResponse)
def liveness() -> HealthResponse:
settings = get_settings()
return HealthResponse(
status="ok",
service="geointel-backend",
version=settings.app_version,
build_sha=settings.build_sha,
build_time=settings.build_time,
version="public",
)