Appearance
Карта бэкенда
Последняя сверка с кодом: 2026-06-06
Стек: Express, Prisma, Postgres, Better Auth, TUS, sharp/ffmpeg
OpenAPI: http://localhost:3002/api/docs
Связанные доки: 02-frontend-map · 01-glossary
1. Разделы API
| Prefix | Router | Auth | Назначение |
|---|---|---|---|
/api/auth/* | Better Auth handler | varies | Login, register, session, reset password |
/api/health | app.ts | — | Healthcheck |
/api/plans | routes/plans.ts | публично | Описание тарифов FREE/BASE/PRO |
/api/events | routes/events.ts | mixed | CRUD событий, settings, members, media list, ZIP, SSE |
/api/media | routes/media.ts | mixed | Файлы, like, delete, moderation |
/api/users | routes/users.ts | session | GET /me — профиль и роль |
/api/admin | routes/admin.ts | SUPER_ADMIN | Пользователи, события, планы платформы |
/api/tus | routes/tus.ts | optional | Resumable upload |
Порядок в app.ts: TUS и Auth до express.json() — иначе ломается body stream.
2. Events API (/api/events)
| Method | Path | Middleware | Service / логика | Frontend |
|---|---|---|---|---|
| GET | /my | requireAuth | listMyEvents | /account, /my-events |
| POST | / | requireAuth + plan limit | createEvent | CreateEventForm |
| GET | /:id | optionalAuth + qrAccess | getEvent | /:id, share |
| GET | /:id/access | optionalAuth | getEventAccess | middleware, useEventAccess |
| GET | /:id/media | optionalAuth + visibility | listEventMedia | album, admin, moderate |
| GET | /:id/stream | optionalAuth | SSE addSubscriber | useEventStream |
| GET | /:id/zip | optionalAuth + zipAccess | streamEventZip | admin, album download |
| POST | /:id/zip | body: selected ids | partial ZIP | admin multi-select |
| GET | /:id/settings | requireAuth + OWNER | getEventSettings | settings page |
| PATCH | /:id/settings | requireAuth + OWNER | updateEventSettings | settings page |
| POST | /:id/branding/:kind | requireAuth + OWNER + plan | uploadEventBranding | settings |
| DELETE | /:id/branding/:kind | requireAuth + OWNER | deleteEventBranding | settings |
| GET | /:id/members | requireAuth + admin role | listEventMembers | members |
| POST | /:id/members | requireAuth + OWNER | addEventMember | members |
| DELETE | /:id/members/:userId | requireAuth + OWNER | removeEventMember | members |
| GET | /:id/members/invite-link | requireAuth + OWNER | getMemberInviteLink | members |
| POST | /:id/members/invite-link | requireAuth + OWNER | regenerate invite | members |
| POST | /:id/join | requireAuth + token | joinEventWithInvite | join page |
3. Media API (/api/media)
| Method | Path | Middleware | Назначение | Frontend |
|---|---|---|---|---|
| GET | /:id | — | Оригинал файла | lightbox, download |
| GET | /:id/thumb | — | Превью | MediaGrid |
| GET | /file?key= | — | По storage key (internal) | branding URLs |
| POST | /:id/like | requireMediaLike | toggle like | MediaCard |
| DELETE | /:id | requireMediaDelete | удаление | admin / member own |
| PATCH | /:id/moderation | requireMediaManage | approve/reject | moderate |
4. Admin & Users & Plans
| Method | Path | Кто | Назначение |
|---|---|---|---|
| GET | /api/users/me | logged in | globalRole, plan |
| GET | /api/admin/stats | SUPER_ADMIN | счётчики |
| GET | /api/admin/users | SUPER_ADMIN | все пользователи |
| GET | /api/admin/events | SUPER_ADMIN | все события |
| GET | /api/admin/plans | SUPER_ADMIN | тарифы + лимиты (admin view) |
| GET | /api/plans | все | публичные тарифы для pricing |
5. TUS Upload (/api/tus)
| Этап | Что происходит |
|---|---|
| 1 | Клиент (Uppy) создаёт upload с metadata: eventId, guest name, … |
| 2 | eventUploadPolicy проверяет qrAccess, limits, allowedMedia |
| 3 | Файл пишется в Storage (local / R2) |
| 4 | onUploadFinish → запись Media, очередь processing |
| 5 | sharp/ffmpeg → thumb, blurhash; SSE уведомляет альбом |
Детали: 05-upload.md, 06-media-processing.md.
6. Services (слой домена)
| Service | Ответственность |
|---|---|
eventService | Event CRUD, list media, access, my events |
eventSettingsService | EventSettings GET/PATCH |
eventBrandingService | logo/background upload |
eventMemberService | MODERATOR assign/remove |
eventMemberInviteService | MEMBER invite link + join |
eventGuestAccessService | qrAccess, album visibility, zip |
eventRoleService | роли на событие |
mediaService | stream files, delete |
likeService | MediaLike toggle |
moderationService | PENDING → APPROVED/REJECTED |
planLimitsService | лимиты по User.plan |
adminService | platform admin lists |
zipService | archiver stream |
emailService | Zoho SMTP (reset password, verify, owner notify) |
storage/* | LocalDisk / R2 |
processing/* | image/video pipeline + queue |
7. Middleware (цепочки)
| Middleware | Когда |
|---|---|
corsMiddleware | Все запросы, credentials для auth cookie |
optionalAuth | Гость или user — session если есть |
requireAuth | 401 без session |
requireSuperAdmin | globalRole === SUPER_ADMIN |
requireEventRole(OWNER/MODERATOR) | роль на событие |
requireMediaManage | OWNER/MODERATOR + moderation |
requireMediaDelete | admin или MEMBER своё |
requireMediaLike | logged in + canLike |
requirePlanEventCreate | лимит событий по тарифу |
assertQrAccess / guest access | в handlers events/media |
Типичный защищённый запрос:
CORS → optionalAuth/requireAuth → requireEventRole → handler → service → Prisma8. Auth (Better Auth)
| Компонент | Путь |
|---|---|
| Config | config/auth.ts |
| Mount | app.all('/api/auth/*', toNodeHandler(auth)) |
| Session | httpOnly cookie, Prisma Session |
| Password reset | sendResetPassword → emailService |
Frontend: /api/auth/get-session, sign-in/email, и т.д. — см. 21-auth-frontend.md.
9. Данные и storage
| Где | Что |
|---|---|
| Postgres | User, Event, Media metadata, Settings, Roles, Likes |
| Storage (disk/R2) | original, thumb, branding files |
| In-memory | SSE subscribers (single instance; Redis — backlog) |
Схема Prisma: backend/prisma/schema.prisma. Продуктовое описание — 09-data-model-summary.md (фаза D).
10. Обработка ошибок
| Code | Константа | UX на фронте |
|---|---|---|
| 401 | UNAUTHORIZED | Auth modal / loginPath |
| 403 | FORBIDDEN | UiPageError inline |
| 404 | EVENT_NOT_FOUND | UiPageError not-found |
| 409 | DUPLICATE_MEDIA | toast |
Источник кодов: constants/apiErrorCode.ts → OpenAPI → ApiClientError на фронте.
11. Live updates (SSE)
GET /api/events/:id/stream
→ text/event-stream
→ события: new media, moderation, deleteКлиент: useEventStream.ts. Сервер: utils/sse.ts. Подробнее: 11-live-updates.md.
12. Где править код
| Задача | Куда |
|---|---|
| Новый REST endpoint | routes/*.ts + JSDoc swagger + generate-api.sh |
| Бизнес-правило | services/*.ts |
| Право доступа | middleware + getEventAccess |
| Лимит тарифа | planLimitsService + middleware/planLimits.ts |
| Env | config/env.ts, backend/.env.example |
13. Локальная отладка
bash
npm run dev:backend # :3002
open http://localhost:3002/api/docsSeed user: dev@local.test / dev123456, event demo-event.