Преминете към основното съдържание

Licensing Server -- Архитектурен преглед

Dictaro Licensing Server е Go/Gin HTTP сървър, който обслужва автентикация, billing, лицензиране, usage tracking и quota management за Dictaro desktop клиента. Деплойнат е на Azure VM (dictaro-vm) чрез Docker.

Слоеста архитектура

Сървърът следва класическа трислойна архитектура: Handlers (HTTP слой) -> Services (бизнес логика) -> Database (PostgreSQL).

Middleware верига

Всяка заявка минава през следната верига middleware-и (в ред на изпълнение):

MiddlewareОписание
gin.Logger()Логване на заявки
gin.Recovery()Panic recovery
PrometheusMiddlewareHTTP метрики (request count, duration, response size)
SecurityHeadersMiddlewareX-Content-Type-Options, X-Frame-Options, Referrer-Policy, HSTS
CORSMiddlewareCORS headers за конфигурирани origins
LoginRateLimit5 req/min per IP за login endpoints
SensitiveEndpointRateLimit3 req/min per IP за password reset, verification
RefreshRateLimit30 req/min per IP за token refresh
RequireAuthЗадължителен JWT -- зарежда user от DB
OptionalAuthОпционален JWT -- user или nil

Маршрути (Routes)

Health

МетодПътAuthОписание
GET/health--Health check

OAuth автентикация

МетодПътAuthОписание
GET/auth/login-page--HTML login страница
GET/auth/login/:provider--Redirect към OAuth provider
GET/auth/callback/:provider--OAuth callback
POST/auth/refresh--Refresh JWT token

Email автентикация

МетодПътAuthОписание
POST/auth/register--Регистрация с email/password
POST/auth/login/email--Login с email/password
GET/auth/verify-email--Страница за потвърждение на email
POST/auth/confirm-email--Потвърждение на email token
POST/auth/resend-verification--Повторно изпращане на verification email
POST/auth/forgot-password--Заявка за password reset
GET/auth/reset-password-page--HTML страница за нова парола
POST/auth/reset-password--Задаване на нова парола

Лицензиране и акаунт

МетодПътAuthОписание
POST/license/activateRequireAuthАктивиране на license key
GET/account/statusRequireAuthСтатус на акаунта

Usage и Quota

МетодПътAuthОписание
POST/usage/recordOptionalAuthЗаписване на usage
GET/usage/quota-statusOptionalAuthТекущ quota статус
GET/stats/public--Публична статистика

Pricing

МетодПътAuthОписание
GET/pricing/plans--Списък с планове от Stripe

Billing

МетодПътAuthОписание
GET/billing/choose-plan-- (JWT в query)HTML страница за избор на план
POST/billing/create-checkoutRequireAuthСъздаване на Stripe Checkout Session
POST/billing/webhook-- (Stripe signature)Stripe webhook receiver
GET/billing/checkout-success--Успешно плащане
GET/billing/checkout-cancel--Отказано плащане
POST/account/portal-urlRequireAuthStripe Customer Portal URL

Ключови дизайнерски решения

  1. Stripe е source of truth за план: При всеки login се прави SyncStripeSubscription, за да се синхронизира локалният план с реалния Stripe subscription статус.

  2. Device account limiting: Free потребители имат ограничение за брой акаунти на устройство (по подразбиране 2), за да се предотврати злоупотреба. Pro потребители нямат ограничение.

  3. Два HTTP сървъра: Основният сървър слуша на port 8000 (конфигурируем), а вътрешен metrics сървър -- на port 9090 (само за Prometheus scraping).

  4. Graceful shutdown: Сървърът обработва SIGINT/SIGTERM и изчаква до 10 секунди за приключване на текущи заявки.

  5. Автоматични миграции: При стартиране се изпълняват SQL миграции автоматично чрез golang-migrate.

  6. Build time injection: buildTime се инжектира при компилация чрез -ldflags и се показва в login page footer.

Файлова структура

licensing-go/
├── cmd/server/main.go # Entry point, routes, middleware
├── internal/
│ ├── config/config.go # Environment variables
│ ├── database/
│ │ ├── connect.go # PostgreSQL connection pool
│ │ └── migrations/ # SQL миграции (golang-migrate)
│ ├── handlers/
│ │ ├── auth.go # OAuth handlers
│ │ ├── email_auth.go # Email/password handlers
│ │ ├── billing.go # Stripe handlers
│ │ ├── license.go # License activation, account status
│ │ ├── usage.go # Usage recording, quota
│ │ └── pricing.go # Pricing plans
│ ├── middleware/
│ │ ├── auth.go # RequireAuth, OptionalAuth
│ │ ├── cors.go # CORS
│ │ ├── metrics.go # Prometheus metrics
│ │ ├── ratelimit.go # Per-IP rate limiting
│ │ └── security_headers.go # Security headers
│ ├── models/ # Data models (User, LicenseKey, UsageRecord)
│ ├── services/
│ │ ├── auth.go # JWT, OAuth user management
│ │ ├── email_auth.go # Email registration, verification, password reset
│ │ ├── email.go # Resend API email sending
│ │ ├── billing.go # Stripe checkout, webhooks, portal
│ │ ├── usage.go # Usage recording, quota calculation
│ │ ├── device.go # Device account limiting
│ │ └── pricing.go # Stripe price fetching/caching
│ ├── i18n/ # Internationalization (EN, BG)
│ ├── metrics/ # Prometheus metric definitions
│ └── session/ # Session cookie management
└── templates/ # HTML templates (login, checkout, email verify, etc.)