Files
soroush.asadi 90ac0b81d1 feat: V2 microservices stack — backend services, gateway, JWT auth
Add full V2 architecture: identity, content, studio (.NET 10) and file,
render, notification, gateway (Go) services with vendored deps, plus DB
migrations, event/API contracts, and an init-db script.

Wire the Next.js frontend to the gateway: server-side JWT auth routes
(login/register/refresh/logout/me), gateway fetch helper, and session/
cookie/jwt helpers under src/lib.

Containerize the stack via docker-compose.v2.yml and per-service
Dockerfiles. Base images resolve through a Nexus mirror (Docker Hub) and
MCR directly; npm/NuGet pull from Nexus groups. Self-host fonts via
next/font/local to avoid Google Fonts (geo-blocked).

Add CI workflow and ignore .env.v2, *.stackdump, and .NET bin/obj.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 23:29:31 +03:30
..

RabbitMQ Event Catalog

All async communication between services uses RabbitMQ. Events follow strict naming: {domain}.{entity}.{verb}.v{n} (past tense).

Exchanges

Exchange Type Purpose
flatrender.events topic Domain events (fan-out by routing)
flatrender.render direct Render job dispatch (per queue)
flatrender.notify direct Notification dispatch (per channel)
flatrender.dlq fanout Dead-letter queue

Common envelope

Every message body has this shape:

{
  "event_id": "uuid",
  "event_type": "render.job.completed.v1",
  "event_time": "2026-05-27T10:15:00Z",
  "tenant_id": "uuid",
  "user_id": "uuid",
  "trace_id": "uuid",
  "correlation_id": "uuid",
  "producer": "render-orchestrator",
  "data": { ... }
}

Headers (AMQP)

Header Required Notes
content-type yes application/json
content-encoding yes utf-8
x-event-type yes Same as event_type (for routing convenience)
x-tenant-id yes For tenant-aware consumers
x-trace-id yes Distributed tracing
x-retry-count optional Incremented on requeue
x-max-retries optional Default 3

Routing keys (topic exchange flatrender.events)

identity.user.registered.v1
identity.user.email_verified.v1
identity.user.banned.v1
identity.tenant.created.v1
identity.tenant.suspended.v1
identity.plan.activated.v1
identity.plan.expired.v1
identity.payment.succeeded.v1
identity.payment.failed.v1
identity.payment.refunded.v1
identity.api_key.created.v1
identity.api_key.revoked.v1

content.template.published.v1
content.template.unpublished.v1
content.font.installed.v1
content.svg_preview.generated.v1

studio.project.saved.v1
studio.project.deleted.v1

render.job.queued.v1
render.job.started.v1
render.job.progress.v1
render.job.completed.v1
render.job.failed.v1
render.job.cancelled.v1
render.snapshot.requested.v1
render.snapshot.ready.v1

node.online.v1
node.offline.v1
node.crashed.v1
node.heartbeat.v1
node.cache.updated.v1

file.uploaded.v1
file.processed.v1
file.deleted.v1
file.quota_warning.v1
file.quota_exceeded.v1
file.cleanup.scheduled.v1
file.cleanup.executed.v1

notification.created.v1
notification.delivered.v1
notification.failed.v1

tenant.usage.recorded.v1
tenant.webhook.fired.v1
tenant.webhook.failed.v1

Render dispatch (direct exchange flatrender.render)

render.queue.snapshot
render.queue.vip
render.queue.paid
render.queue.preview
render.queue.mockup
render.queue.voiceover

Each queue has priority x-max-priority: 10. Job priority encoded in message priority property.

Notification dispatch (direct exchange flatrender.notify)

notify.channel.push
notify.channel.email
notify.channel.sms
notify.channel.telegram
notify.channel.webhook

Dead-letter routing

Failed messages (after x-max-retries exhausted) are republished to flatrender.dlq with original routing key preserved in x-original-routing-key header.