# Template Packages — AI-Optimized Reference

> This document describes all template packages implemented in /templates/backend/base and /templates/frontend/base.
> Designed for quick understanding by AI agents. All packages are commented out by default.

---

## Architecture Overview

### Backend (Go/Gin/GORM/MySQL)

**Location:** `/templates/backend/base/internal/packages/{name}/`

Each package contains:
- `model.go` — GORM models with table definitions
- `repository.go` — Interface + implementation for DB operations
- `service.go` — Business logic layer
- `handler.go` — HTTP handlers (Gin)
- `events.go` — Event type definitions for EventBus
- `register.go` — `Register(deps PackageDeps)` function that wires everything (products.Register returns *ProductService)

**Dependency injection:** `PackageDeps` struct (`internal/packages/deps.go`) passes DB, EventBus, router groups, config.

**Inter-package communication:** Async EventBus (`internal/events/bus.go`). Events are published as values, handlers run in goroutines. Cross-package event consumption uses JSON marshal/unmarshal to avoid import cycles.

**Activation:** Uncomment registration calls in `internal/router/router.go` (section marked with `============`).

### Frontend (Next.js 16/React 19/TypeScript/Gravity UI)

**Location:** `/templates/frontend/base/packages/{name}/`

Each package contains:
- `api/{name}.types.ts` — TypeScript interfaces
- `api/{name}Service.ts` — API service using `createApiClient` from `@/api/base`
- `components/` — Gravity UI-based React components (Table, Form, Detail)
- `{Name}Page.tsx` — Main page component with list/form/detail modes
- `index.ts` — Public export

**Page wrappers:** `app/admin/{entity}/page.tsx` — 1-line re-export from package.

**Activation:** Uncomment re-export in `app/admin/{entity}/page.tsx` and sidebar items in `admin/components/layout/Sidebar.tsx`.

---

## Backend Packages

### products — `internal/packages/products/`

**Model:** `Product` (id, name, description, price, image_url, active, timestamps)

**API Endpoints:**
- Admin: `GET/POST /admin/products`, `GET/PUT/DELETE /admin/products/:id`
- User: `GET /user/products` (active only), `GET /user/products/:id`

**Events Published:** `product.created`, `product.updated`, `product.deleted`

**Dependencies:** None (standalone)

---

### tariffs — `internal/packages/tariffs/`

**Models:**
- `Tariff` (id, name, description, price, duration_days, features[JSON], active, timestamps)
- `Subscription` (id, user_id, tariff_id, status[active/expired/cancelled], starts_at, expires_at, transaction_id, timestamps)

**API Endpoints:**
- Admin: CRUD `/admin/tariffs`, `GET /admin/subscriptions`
- User: `GET /user/tariffs` (active), `POST /user/tariffs/:id/subscribe`, `GET /user/subscriptions`

**Events Published:** `tariff.created`, `tariff.subscribe_requested`
**Events Consumed:** `payment.completed` → creates Subscription

**Dependencies:** None (standalone)

---

### cart — `internal/packages/cart/`

**Models:**
- `Cart` (id, user_id[unique], items[], timestamps)
- `CartItem` (id, cart_id, product_id, quantity, timestamps)

**API Endpoints (User only):**
- `GET /user/cart`, `POST /user/cart/items`, `PUT/DELETE /user/cart/items/:id`, `POST /user/cart/checkout`

**Events Published:** `cart.checkout` (user_id, items with price snapshots, total)

**Dependencies:** Requires `products.ProductService` (passed in Register)

---

### orders — `internal/packages/orders/`

**Models:**
- `Order` (id, user_id, status[pending/awaiting_payment/paid/cancelled/refunded], total_amount, items[], timestamps)
- `OrderItem` (id, order_id, product_id, name[snapshot], price[snapshot], quantity)

**API Endpoints:**
- Admin: `GET /admin/orders`, `GET/PUT /admin/orders/:id` (status change)
- User: `GET /user/orders`, `GET /user/orders/:id`

**Events Published:** `order.created`, `order.status_changed`
**Events Consumed:** `cart.checkout` → creates Order, `payment.completed` → updates status to paid

**Dependencies:** None (uses JSON marshal for cross-package events)

---

### transactions — `internal/packages/transactions/`

**Model:** `Transaction` (id, order_id[nullable], user_id, tariff_id[nullable], amount, currency, status[pending/success/failed/refunded], provider, provider_tx_id, provider_data[JSON], timestamps)

**API Endpoints:**
- Admin: `GET /admin/transactions`, `GET /admin/transactions/:id` (view only)
- User: `GET /user/transactions` (own transactions)

**Events Consumed:** `payment.completed` → creates Transaction record

**Dependencies:** None

---

### telegram — `internal/packages/telegram/`

**Files:** `bot.go` (API client), `sender.go` (message sending), `router.go` (command/callback routing), `types.go` (Update/Message types), `handler.go` (webhook HTTP handler), `register.go`

**API Endpoints:**
- Public: `POST /public/telegram/webhook`

**Behavior:** Auto-sets webhook to `{APP_URL}/api/v1/public/telegram/webhook` on startup. Basic `/start` command. Extensible router for adding commands/callbacks.

**Global instances:** `BotInstance`, `RouterInstance`, `SenderInstance` (used by telegram_stars)

**Config:** `TELEGRAM_BOT_TOKEN`, `TELEGRAM_ENABLED`, `APP_URL`

---

### payments — `internal/packages/payments/`

**Interface:** `PaymentProvider` with methods: `Name()`, `CreatePayment()`, `HandleCallback()`, `GetPaymentStatus()`

**Registry:** `ProviderRegistry` — thread-safe map of providers

**API Endpoints:**
- User: `POST /user/payments/create` (initiate payment)
- Public: `POST/GET /public/payments/callback/:provider` (provider callback)
- Public: `GET /public/payments/providers` (list available)

**Events Published:** `payment.initiated`, `payment.completed`, `payment.failed`

**Sub-packages (providers):**

#### robokassa — `payments/robokassa/`
- MD5 signature: `MD5(MerchantLogin:OutSum:InvId:Password1)` for URL, `MD5(OutSum:InvId:Password2)` for ResultURL verification
- Payment URL: `https://auth.robokassa.ru/Merchant/Index.aspx?...`
- Config: `ROBOKASSA_MERCHANT_LOGIN`, `ROBOKASSA_PASSWORD1`, `ROBOKASSA_PASSWORD2`, `ROBOKASSA_TEST_MODE`

#### tinkoff — `payments/tinkoff/`
- Tinkoff Acquiring API v2: `https://securepay.tinkoff.ru/v2`
- Init → PaymentURL, GetState for status checks
- Token: sort params alphabetically, concatenate values (including Password), SHA-256
- Config: `TINKOFF_TERMINAL_KEY`, `TINKOFF_SECRET_KEY`

#### telegram_stars — `payments/telegram_stars/`
- Uses Telegram Bot Payments API via bot token
- `createInvoiceLink` with currency=XTR (Telegram Stars)
- Handles `pre_checkout_query` (auto-confirm) and `successful_payment` via webhook
- Config: uses `TELEGRAM_BOT_TOKEN` from TelegramConfig

---

### telegram_auth — `internal/packages/telegram_auth/`

**Telegram Login Widget авторизация.** Полностью инкапсулированный пакет — не модифицирует `models/user.go`, `auth_service.go` или другие существующие файлы.

**Models:**
- `TelegramUser` (id, user_id[FK→users], telegram_id, username, first_name, last_name, photo_url, timestamps)

**Files:**
- `model.go` — TelegramUser model + LoginResponse
- `widget.go` — WidgetData struct + VerifyWidgetData (HMAC-SHA-256 verification, auth_date freshness check)
- `repository.go` — TelegramAuthRepository (GetByTelegramID, GetByUserID, Create)
- `service.go` — HandleWidgetCallback: verify → find-or-create user → generate JWT
- `handler.go` — HTTP handler with Swagger annotations
- `events.go` — Event types + structs
- `register.go` — Register(deps PackageDeps)

**API Endpoints:**
- Public: `POST /public/auth/telegram/callback` — принимает WidgetData, возвращает JWT + user

**Auth Flow:**
1. Frontend загружает Telegram Widget SDK, открывает popup
2. Telegram возвращает подписанные данные (WidgetData с HMAC-SHA-256)
3. Backend верифицирует: `secret = SHA256(bot_token)`, `HMAC_SHA256(data_check_string, secret) == hash`
4. Ищет TelegramUser по telegram_id, если не найден — создаёт `models.User` (email=`tg_{id}@telegram.local`) + `TelegramUser`
5. Генерирует JWT-токен, публикует события

**Events Published:** `telegram_auth.user_created`, `telegram_auth.user_logged_in`

**Config:** `TELEGRAM_BOT_TOKEN` (existing), `TELEGRAM_BOT_ID` (numeric bot ID for frontend)

**Dependencies:** None (uses shared `models.User`, `pkg/jwt`, `events.EventBus` — infrastructure only)

---

## Frontend Packages

### packages/products/
- **Types:** Product, CreateProductRequest, UpdateProductRequest
- **Service:** CRUD via `/api/v1/admin/products`
- **Components:** ProductsTable (Table+Pagination), ProductForm (name, description, price, image_url, active)
- **Page:** ProductsPage — list/create/edit modes via query params

### packages/tariffs/
- **Types:** Tariff, CreateTariffRequest, UpdateTariffRequest
- **Service:** CRUD via `/api/v1/admin/tariffs`
- **Components:** TariffsTable, TariffForm (name, description, price, duration_days, features, active)
- **Page:** TariffsPage — list/create/edit modes

### packages/orders/
- **Types:** Order, OrderItem, UpdateOrderStatusRequest
- **Service:** List, GetById, UpdateStatus via `/api/v1/admin/orders`
- **Components:** OrdersTable (with status labels), OrderDetail (with status change dropdown)
- **Page:** OrdersPage — list/detail modes (no create/delete)

### packages/transactions/
- **Types:** Transaction
- **Service:** List, GetById via `/api/v1/admin/transactions` (view only)
- **Components:** TransactionsTable (with colored status/provider labels), TransactionDetail
- **Page:** TransactionsPage — list/detail modes (read-only)

### packages/telegram-auth/
- **Types:** TelegramWidgetData, TelegramLoginResponse
- **Service:** `telegramAuthService.callback()` via `POST /api/v1/public/auth/telegram/callback`
- **Utils:** `loadTelegramScript()`, `openTelegramLogin()` — Telegram Widget SDK management
- **Components:** `TelegramLoginButton` — fully encapsulated button, accepts `onSuccess(token, user)` callback
- **Usage:** Import and place `<TelegramLoginButton onSuccess={(token) => ...} />` on any login page
- **Config:** `NEXT_PUBLIC_TELEGRAM_BOT_ID` env variable

---

## Event Flow Diagram

```
[User adds items to Cart] → cart.checkout →
    [Orders] creates Order → order.created →
        [Payments] initiates payment → payment.completed →
            [Orders] updates status to "paid"
            [Transactions] creates Transaction record
            [Tariffs] creates Subscription (if tariff payment)

[User subscribes to Tariff] → tariff.subscribe_requested →
    [Payments] initiates payment → payment.completed →
        [Tariffs] creates Subscription
        [Transactions] creates Transaction record
```

## Activation Checklist

### Backend
1. Uncomment imports and `Register()` calls in `internal/router/router.go`
2. Add required env vars to `.env` (see `.env.example`)
3. Migrations run automatically in each `Register()` function

### Frontend
1. Uncomment re-exports in `app/admin/{entity}/page.tsx`
2. Uncomment sidebar items in `admin/components/layout/Sidebar.tsx`
3. Ensure backend API is running with corresponding packages enabled

### Telegram Auth (additional)
1. Backend: uncomment `telegram_auth.Register(deps)` in `router.go`
2. Set `TELEGRAM_BOT_TOKEN` and `TELEGRAM_BOT_ID` in `.env`
3. Frontend: set `NEXT_PUBLIC_TELEGRAM_BOT_ID` env variable
4. Add `<TelegramLoginButton>` to your login page, connecting `onSuccess` to your auth store
