Files
AFFAANhandClaude Opus 5 f6a54d6f93 Initial commit: Maskan CRM backend
Independent FastAPI backend for Maskan CRM.

Owns contacts, organizations, leads, pipelines, activities, products,
quotes, users, permissions, audit records and first-party integration
credentials, with Alembic migrations against PostgreSQL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 10:28:41 +05:30

4.0 KiB

Maskan CRM Backend

Independent FastAPI API for Maskan CRM. This repository owns CRM contacts, organizations, leads, pipelines, activities, products, quotes, users, permissions, audit records, and first-party integration credentials.

Runtime

  • Python 3.11 to 3.13
  • FastAPI and SQLAlchemy
  • Alembic migrations
  • PostgreSQL 16 for every non-test environment
  • Node.js 20+ only as a consistent command runner for DevOps

The API never shares a database or database credentials with MaskanX.

Local Setup

Copy-Item .env.local.example .env.local
npm install
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
npm run docker:up
npm run local:seed

docker:up starts the API and PostgreSQL. To run the API directly with reload, start only PostgreSQL and use:

npm run local:migrate
npm run local:seed
npm run local

Which PostgreSQL are you pointing at?

.env.local.example ships with DB_PORT=5433, the port Docker Compose publishes for this repository's own maskan-crm-postgres container. That is correct when you run npm run docker:up.

If you instead use a PostgreSQL you already run locally (usually port 5432), set DB_PORT=5432 and DB_PASSWORD to that server's password, and create the database first:

CREATE DATABASE maskan_crm;

Pointing at a port where nothing is listening fails with psycopg.errors.ConnectionTimeout: connection timeout expired during local:migrate or local:seed, and the API returns 500s on /auth/login (which the browser then reports as a CORS error, because the error response carries no CORS headers).

Open:

  • API: http://127.0.0.1:8091
  • API docs: http://127.0.0.1:8091/api/docs
  • Readiness: http://127.0.0.1:8091/health/ready

Lifecycle Commands

The requested environment command names are available using this backend's native Python tooling. Alembic replaces Sequelize because this is a FastAPI service.

Command Purpose
npm start Start using .env or injected environment variables
npm run build Build the Python wheel into dist/
npm run local Start with .env.local and reload
npm run local:migrate Apply local Alembic migrations
npm run local:migrate:undo Undo the newest local migration
npm run local:migrate:undo:all Roll back all local migrations
npm run local:seed Seed the bootstrap workspace and optional demo data
npm run local:seed:undo Remove the local bootstrap workspace
npm run local:reset Recreate and seed the local schema
npm run dev* Equivalent commands using .env.development
npm test Run unit/API tests using .env.testing
npm run test:migrate Apply migrations using .env.testing
npm run test:seed Seed using .env.testing
npm run test:reset Recreate the test schema
npm run prod Start with production validation enabled
npm run prod:migrate Apply production migrations
npm run prod:seed Seed production without demo records

Production

Supply secrets through the deployment platform, not committed files:

MASKAN_CRM_ENV=production
MASKAN_CRM_MODE=standalone
MASKAN_CRM_CORS_ORIGINS=https://crm.example.com
MASKAN_CRM_JWT_SECRET=<at-least-32-random-characters>
DB_HOST=<managed-postgres-host>
DB_PORT=5432
DB_NAME=maskan_crm
DB_USER=<dedicated-user>
DB_PASSWORD=<secret>
DB_SSLMODE=require

Run npm run prod:migrate as a release step, then run npm run prod.

MaskanX Integration

MaskanX connects to /api/v1/integrations with a revocable mcrm_ service key and idempotency keys. This reliable REST path is the normal product integration. MCP tools are an optional agent interface and do not replace the service-to-service API.

Database Policy

PostgreSQL is the configured database for local, development, testing migrations, staging, and production. A small in-memory SQLite fixture is used inside isolated unit tests only and is rejected as an application runtime database outside the explicit testing environment.