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

73 lines
2.9 KiB
YAML

# =====================================================================
# Tenant Events — multi-tenancy / reseller-specific
# =====================================================================
events:
tenant.usage.recorded.v1:
routing_key: tenant.usage.recorded.v1
description: Daily usage aggregate published (by usage aggregator cron).
payload:
type: object
required: [tenant_id, usage_date, renders_completed, render_seconds]
properties:
tenant_id: { type: string, format: uuid }
usage_date: { type: string, format: date }
renders_started: { type: integer }
renders_completed: { type: integer }
renders_failed: { type: integer }
render_seconds: { type: integer, format: int64 }
render_compute_sec: { type: integer, format: int64 }
storage_bytes: { type: integer, format: int64 }
api_calls: { type: integer, format: int64 }
active_users: { type: integer }
new_users: { type: integer }
amount_billed_minor: { type: integer, format: int64 }
currency: { type: string }
tenant.webhook.fired.v1:
routing_key: tenant.webhook.fired.v1
description: A webhook was successfully delivered to a reseller.
payload:
type: object
required: [webhook_id, tenant_id, event_type, response_status]
properties:
webhook_id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
delivery_id: { type: string, format: uuid }
event_type: { type: string }
request_url: { type: string }
response_status: { type: integer }
duration_ms: { type: integer }
attempt: { type: integer }
tenant.webhook.failed.v1:
routing_key: tenant.webhook.failed.v1
description: A webhook delivery exhausted retries.
payload:
type: object
required: [webhook_id, tenant_id, event_type, last_status, last_error]
properties:
webhook_id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
delivery_id: { type: string, format: uuid }
event_type: { type: string }
request_url: { type: string }
last_status: { type: integer, nullable: true }
last_error: { type: string }
attempts: { type: integer }
webhook_disabled: { type: boolean, description: "True if auto-disabled" }
tenant.api.rate_limited.v1:
routing_key: tenant.api.rate_limited.v1
description: A tenant exceeded its API rate limit (informational).
payload:
type: object
required: [tenant_id, api_key_id, limit_rpm, window_start]
properties:
tenant_id: { type: string, format: uuid }
api_key_id: { type: string, format: uuid }
limit_rpm: { type: integer }
actual_rpm: { type: integer }
window_start: { type: string, format: date-time }
ip_address: { type: string }