Microservices Overview
Summary of all 14 microservices with ports, purposes, base paths, and database names
MQUAD runs 15 microservices plus supporting infrastructure. Each service is independently deployable, owns its own database, and communicates through the Traefik API Gateway.
Service Table
| # | Service | Port | Base Path | Database | Category | Status |
|---|---|---|---|---|---|---|
| 1 | backend | 8000 | /api/v1 | appdb | Core | Active |
| 2 | survey-service | 8001 | /api/v1 | survey_db | Domain | Active |
| 3 | data-service | 8002 | /api/v1 | data_db | Domain | Active |
| 4 | sync-service | 8003 | /api/v1 | sync_db | Domain | Active |
| 5 | analytics-service | 8004 | /api/v1 | analytics_db | Analytics | Active |
| 6 | workspace-service | 8006 | /api/v1 | workspace_db | Domain | Active |
| 7 | webhook-service | 8007 | /api/v1 | webhook_db | Integration | Active |
| 8 | odk-bridge | 8009 | /api/v1 | odk_db | Integration | Active |
| 9 | form-service | 8010 | /api/v1 | mquad_forms_db | Forms | Active |
| 10 | media-service | 8011 | /api/v1 | media_db | Infrastructure | Active |
| 11 | notification-service | 8012 | /api/v1 | notification_db | Integration | Active |
| 12 | audit-service | 8013 | /api/v1 | audit_db | Security | Active |
| 13 | feature-flags-service | 8014 | /api/v1 | feature_flags_db | Infrastructure | Active |
| 14 | quota-service | 6380 | / | — | Core | Active |
| 15 | scalar-service | 8030 | / | — | Documentation | Active |
Common Architecture
Every microservice follows the same internal structure:
service-name/
├── api/
│ ├── __init__.py # App factory + sys.path hack
│ ├── core/config.py # Pydantic Settings
│ ├── common/dtos/ # Shared DTOs
│ ├── domain/entities/ # SQLAlchemy models
│ ├── domain/enums/ # Enumerations
│ ├── infrastructure/database.py # SQLAlchemy async setup
│ ├── interfaces/api_controllers/ # FastAPI endpoints
│ ├── interfaces/middlewares/ # FastAPI middlewares
│ ├── interfaces/security/ # Role checkers
│ └── usecases/ # Business logic
├── alembic/ # Migrations (unless using create_all)
├── Dockerfile
├── requirements.txt
└── .envCritical Gotcha
Each service's api/__init__.py must include sys.path.insert(0, "/opt/common") before importing from common.*. This is because the common/ module is mounted as a Docker volume at /opt/common:
import sys
sys.path.insert(0, "/opt/common")
from common.rbac_helpers import is_super_adminDatabase Note
The analytics-service uses Base.metadata.create_all() instead of Alembic for schema management. Adding columns to an existing table in that service requires manual SQL migration.
