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

#ServicePortBase PathDatabaseCategoryStatus
1backend8000/api/v1appdbCoreActive
2survey-service8001/api/v1survey_dbDomainActive
3data-service8002/api/v1data_dbDomainActive
4sync-service8003/api/v1sync_dbDomainActive
5analytics-service8004/api/v1analytics_dbAnalyticsActive
6workspace-service8006/api/v1workspace_dbDomainActive
7webhook-service8007/api/v1webhook_dbIntegrationActive
8odk-bridge8009/api/v1odk_dbIntegrationActive
9form-service8010/api/v1mquad_forms_dbFormsActive
10media-service8011/api/v1media_dbInfrastructureActive
11notification-service8012/api/v1notification_dbIntegrationActive
12audit-service8013/api/v1audit_dbSecurityActive
13feature-flags-service8014/api/v1feature_flags_dbInfrastructureActive
14quota-service6380/—CoreActive
15scalar-service8030/—DocumentationActive

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
└── .env

Critical 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_admin

Database 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.