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>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# =====================================================================
|
||||
# Notification Events
|
||||
# =====================================================================
|
||||
events:
|
||||
|
||||
notification.created.v1:
|
||||
routing_key: notification.created.v1
|
||||
description: A new in-app notification was created (also fans out to channels).
|
||||
payload:
|
||||
type: object
|
||||
required: [notification_id, user_id, notification_type, title, message]
|
||||
properties:
|
||||
notification_id: { type: string, format: uuid }
|
||||
tenant_id: { type: string, format: uuid }
|
||||
user_id: { type: string, format: uuid }
|
||||
notification_type:
|
||||
type: string
|
||||
enum: [RenderCompleted, RenderFailed, RenderProgress,
|
||||
PlanExpiring, PlanExpired, PaymentSuccess, PaymentFailed,
|
||||
StorageWarning, StorageFull, ExportExpiring, ExportDeleted,
|
||||
GiftEarned, QuestCompleted, LevelUp,
|
||||
AccountSecurity, SystemAnnouncement, TenantInvite,
|
||||
Marketing, Other]
|
||||
priority: { type: string, enum: [Low, Normal, High, Urgent] }
|
||||
title: { type: string }
|
||||
message: { type: string }
|
||||
action_url: { type: string, nullable: true }
|
||||
# Fan-out routing — which channels to deliver to
|
||||
channels:
|
||||
type: array
|
||||
items: { type: string, enum: [InApp, Push, Email, SMS, Telegram, Webhook] }
|
||||
|
||||
notification.delivered.v1:
|
||||
routing_key: notification.delivered.v1
|
||||
payload:
|
||||
type: object
|
||||
required: [delivery_id, notification_id, channel, status]
|
||||
properties:
|
||||
delivery_id: { type: string, format: uuid }
|
||||
notification_id: { type: string, format: uuid }
|
||||
tenant_id: { type: string, format: uuid }
|
||||
user_id: { type: string, format: uuid }
|
||||
channel: { type: string, enum: [InApp, Push, Email, SMS, Telegram, Webhook] }
|
||||
status: { type: string, enum: [Sent, Delivered] }
|
||||
provider: { type: string }
|
||||
provider_message_id: { type: string, nullable: true }
|
||||
sent_at: { type: string, format: date-time }
|
||||
delivered_at: { type: string, format: date-time, nullable: true }
|
||||
|
||||
notification.failed.v1:
|
||||
routing_key: notification.failed.v1
|
||||
payload:
|
||||
type: object
|
||||
required: [delivery_id, channel, error_message]
|
||||
properties:
|
||||
delivery_id: { type: string, format: uuid }
|
||||
notification_id: { type: string, format: uuid, nullable: true }
|
||||
tenant_id: { type: string, format: uuid }
|
||||
user_id: { type: string, format: uuid }
|
||||
channel: { type: string }
|
||||
attempt: { type: integer }
|
||||
max_attempts: { type: integer }
|
||||
error_code: { type: string, nullable: true }
|
||||
error_message: { type: string }
|
||||
will_retry: { type: boolean }
|
||||
next_retry_at: { type: string, format: date-time, nullable: true }
|
||||
Reference in New Issue
Block a user