---
globs: "buero-backend-api/src/**/subscriptions/**/*,buero-backend-api/src/**/payments/**/*,buero-backend-api/src/**/webhooks/**/*,buero-backend-api/src/**/*.ts"
description: "Stripe, підписки та перевірка доступу до контенту"
---

# Stripe та доступ до контенту — buero.de

## Stripe

- **Картки не зберігаємо**; Stripe Checkout + **Customer Portal** для керування підпискою.
- **Webhook:** `POST /webhooks/stripe`. Обов’язково: **перевірка signature** (Stripe SDK); **ідемпотентність** — перед обробкою перевірити `stripe_event_id` у таблиці **stripe_webhook_events**, при UNIQUE conflict — пропустити обробку.
- Події: checkout.session.completed, invoice.paid, customer.subscription.updated, customer.subscription.deleted (docs/architecture.md, секція Webhook Processing).
- Один **активний** subscription на користувача (partial unique за user_id де status = active).

## Доступ до контенту (курси, матеріали)

- **Курси продаються окремо.** Доступ до матеріалів курсу для **студента** — лише якщо є запис у **user_course_access** для (user_id, course_id) з активним доступом: trial (trial_ends_at > now()), купівля (access_type = purchase) або активна підписка на цей курс (subscription_id → subscriptions.status = active/trialing).
- Каталог (GET /api/courses) — всі опубліковані курси. GET /api/courses/:id/materials та прогрес — з перевіркою user_course_access.
- Вчитель: CRUD курсів/матеріалів незалежно від доступу (за роллю teacher).
- Якщо студент без доступу до курсу запитує матеріали курсу — повертати **403** та зрозуміле повідомлення.

## Посилання

- docs/modules/06-subscriptions-billing.md; docs/architecture.md (Payments, Business Rules).
