Skip to main content

Backend Design & Structure

The FastAPI application follows a clean Domain-Driven Design (DDD) layered architecture. This separates database implementations and API routing frameworks from the core business domain logic.


📂 Backend Structure Tree​

Located under backend/stacgis/app:

app/
├── agent/ # Conversational AI Agent logic and run loops
├── api/ # API Router framework layer (endpoints, JWT authentication)
├── core/ # Config settings, logging, telemetry initialization
├── domain/ # Domain models, schema validations, service implementations
├── infrastructure/ # Database (SQLAlchemy), Cache (Redis), File storage (MinIO)
├── main.py # FastAPI Application startup and middleware definition
├── mcp/ # Model Context Protocol (MCP) tooling and integration
├── models/ # SQLAlchemy database declarations
├── templates/ # HTML and template layouts (e.g. verification emails)
└── workers/ # Celery workers and task processors

1. Domain Layer (/domain)​

The Domain Layer defines the core business rules of the platform. It remains decoupled from routers or database query scripts.

  • Schemas (/domain/schemas/): Pydantic validation models that define input/output structures.
  • Services (/domain/services/): High-level orchestrators containing pure business logic (e.g. UserService, STACService).

2. Infrastructure Layer (/infrastructure)​

The Infrastructure Layer manages external connections, operations, and file storage:

  • Repositories: Database persistence operations. Services query databases via repository interfaces to maintain high testability.
  • MinIO S3 Integration: Manages reading and writing large spatial raster files or geojson assets.
  • Redis Cache Layer: Quick session access, tracking rate limits, and short-term conversation logs storage.

3. Asynchronous Tasks (/workers)​

Time-consuming geospatial calculations (such as parsing huge STAC directories or rendering raster tiles) are handled by Celery:

  • Task queues are defined under /app/workers/tasks.py.
  • Results are saved to Redis and can be polled through API routers.