Backend: FastAPI with PostgreSQL, SQLAlchemy, Alembic. Frontend: React + Vite + React Query.
- Build and publish the backend/frontend container images.
- Provision PostgreSQL (managed service or StatefulSet) and expose it to the backend.
- Create Kubernetes Deployments for backend and frontend, plus Services and an Ingress (or Gateway) for routing.
- Configure the backend with the required environment variables (see below).
- Run database migrations as a one-off Job or
kubectl execusing:python -m app.cli migrate-all(full backend) orpython -m app.migrator.main(public-only migrator). - Roll out the backend and frontend Deployments.
DATABASE_URLJWT_SECRETROOT_DOMAIN(e.g.securesoft.dev)PLATFORM_HOSTS(e.g.crm.securesoft.dev)RESERVED_SUBDOMAINS(e.g.crm,platform,www,api)DEFAULT_TENANT_SLUGFIRST_OWNER_EMAILFIRST_OWNER_PASSWORDBOOTSTRAP_TOKEN(optional fallback for platform auth)
DATABASE_URL
python -m app.migrator.main
- Public migrations are applied via
alembic upgrade head(no branch labels). - Alembic branches are not used for public migrations;
versions/publicis treated as the public migration source.
apiVersion: batch/v1
kind: Job
metadata:
name: crm-migrator
namespace: crm
spec:
backoffLimit: 0
ttlSecondsAfterFinished: 3600
template:
spec:
restartPolicy: Never
containers:
- name: migrator
image: ghcr.io/your-org/crm-migrator:latest
imagePullPolicy: Always
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: crm-database
key: DATABASE_URL
command: ["python", "-m", "app.migrator.main"]The frontend defaults to using /api/v1 for API requests. In local dev, the frontend sets VITE_API_BASE_URL=http://localhost:8000/api/v1 (see frontend/.env.development) so requests hit the backend directly. You can override this at build time by setting VITE_API_BASE_URL.
VITE_API_BASE_URL=/api/v1The frontend attempts to load /config.json at startup (no cache) for runtime overrides. This is useful for configuring platform/tenant hosts without rebuilding the image. Example:
{
"platformHosts": ["crm.securesoft.dev"],
"rootDomain": "securesoft.dev",
"apiBase": "/api/v1"
}In Kubernetes, provide this file via a ConfigMap and mount it at /usr/share/nginx/html/config.json inside the frontend container.
You can also set VITE_PLATFORM_HOSTS at build time to the same host list (comma-separated). Platform UI is enabled only for hosts listed in platformHosts/VITE_PLATFORM_HOSTS.
POST /api/v1/platform/auth/login— login with the configured platform owner email/password.POST /api/v1/platform/tenants— returnstenant_urlandinvite_urlfor first-user registration.POST /api/v1/invitations— create a tenant invite.GET /api/v1/invitations/{token}— validate invite token for tenant registration.POST /api/v1/invitations/{token}/accept— complete tenant owner registration and return a tenant JWT.
- Health:
http://localhost/api/v1/health - Login: open
http://localhost, sign in, and confirm the UI shows the authenticated state or user data.
- Финансы: сохранение фильтров и корректное восстановление выбранных значений после обновления страницы.
- Cashier: создание кассира и успешный вход в систему.
- POS-UX: работа кнопок оплаты, обработка Enter/Esc и управление корзиной.
- UI: наличие toast-уведомлений и reset-кнопок там, где они ожидаются.