What's Changed
Added
- Service layer (
app/services/): business logic extracted from FastAPI routes into HTTP-agnostic services (ServiceContext, domain services for basic/CRM/OM/EPA/routing/system/admin). HTTP handlers and the CLI share the same code path. giswater-apiCLI (app/cli/, Click): console script entry point afterpip install -e .. Commands:admin tenants list|get— platform tenant registryadmin users list|create— gwapi user management (basic-auth tenants)tenant --tenant … --schema … ready— tenant readiness probe (exit code 1 when not ready)tenant … crm insert-hydrometer— example tenant-scoped CRM operation- Global
--tenants-diroverridesTENANTS_DIRoutside the FastAPI lifespan
app/api/exception_handlers.py: centralized mapping of service-layer exceptions to HTTP responses (replaces per-route error handling).docs/ARCHITECTURE.md(package map, dependency rules, where to add code) anddocs/VERSIONING.md(API/DB versioning policy).- CLI smoke test (
tests/test_cli_smoke.py).
Changed
- FastAPI-aligned internal layout (no HTTP path, env var, or behavior changes).
app/is now split into standard subpackages:app/api/—deps.py(wasdependencies.py),v1/(router.pywiring +endpoints/tenant routers), andadmin/(tenants.py,users.py,router.py).app/core/—config.py,constants.py,exceptions.py(dependency-free leaf).AUTH_MODES/DEPRECATED_KEYCLOAK_ENABLED_ISSUEnow live incore/config.py, fixing a latentconfig<=>authimport cycle.app/auth/—session.py(wasauth.py),keycloak.py,users.py(wasgwapi_users.py),schemas.py(ApiUser+ gwapi user DTOs),constants.py.app/db/—manager.py(wasdatabase.py),context.py,execution.py,version.py,log_store.py, andbootstrap/{log,gwapi}.py(the oldapp/schemas.pyDDL).app/tenancy/—registry.py(wastenant.py),state.py,host_middleware.py.app/middleware/request_logging.py(wasapp/logging.py, no longer shadows stdliblogging).app/schemas/now holds all Pydantic request/response models (wasapp/models/).app/utils/slimmed into focused modules:body.py,version.py(mergesgiswater_version.py),rate_limit.py,plugins.py,log_setup.py,routing.py.
- All v1 and admin route handlers are now thin wrappers:
CommonsDep→get_service_context()→ service method → JSON response. - OpenAPI
descriptionmetadata added or improved across admin, system, and tenant endpoints. - README updated with CLI usage examples and the new package layout.
Fixed
- Service-layer exceptions are re-raised after handling so FastAPI's registered exception handlers produce the correct HTTP status and body (instead of being swallowed or mapped inline in routes).
Removed
app/api/http_errors.py(superseded byexception_handlers.py).
Pull Requests
Full Changelog: v1.4.0...v1.5.0