Skip to content

Введение

Planner — полнофункциональная платформа управления проектами, построенная на современном TypeScript-стеке. Поддерживает мультиарендные организации, команды, проекты, задачи с богатым жизненным циклом, чат в реальном времени, WebSocket-уведомления и детальный контроль доступа на основе ролей.

Архитектура

Структура монорепозитория

Проект использует pnpm workspaces с Turborepo для оркестрации сборки:

planner/
├── apps/
│   ├── backend/         # NestJS API (порт 4000)
│   ├── frontend/        # Vue 3 SPA (порт 3000)
│   ├── website/         # Nuxt 4 маркетинговый сайт (порт 8080)
│   └── docs/            # VitePress документация (порт 8081)
├── mobile/               # Мобильные приложения (отдельный репозиторий)
│   ├── ios/              # iOS (Swift)
│   └── android/          # Android (Kotlin)
├── packages/
│   ├── shared-types/    # @planner/shared-types
│   ├── shared-utils/    # @planner/shared-utils
│   ├── shared-i18n/     # @planner/shared-i18n
│   └── ui-kit/          # @planner/ui-kit
├── docker/              # Dockerfile для каждого приложения
├── docker-compose.yml   # Docker Compose для разработки
├── docker-compose.prod.yml  # Docker Compose для продакшна
├── turbo.json           # Конфигурация пайплайна Turborepo
├── pnpm-workspace.yaml
└── package.json

Архитектура фронтенда (Vue 3)

  • Маршрутизация: Vue Router с ленивой загрузкой представлений, вложенные макеты (AdminLayout, OrgLayout, TeamLayout)
  • Состояние: Pinia setup store с storeToRefs для реактивных привязок
  • UI: PrimeVue 4 с темой Aura (изумрудный primary, серый surface)
  • Реальное время: Socket.IO клиент подключается при аутентификации, присоединяется к комнатам пользователя
  • i18n: vue-i18n@9 с Composition API, EN/RU локали сохраняются в localStorage

Архитектура бэкенда (NestJS)

  • Модули: Модули на основе фич (Auth, Users, Organizations, Teams, Projects, Tasks, Comments, Chat, Notifications, TaskHistory, Invitations, Events, VideoChat, RBAC, Quotas, Plans, Storage, Email, Health, Admin)
  • Аутентификация: JWT access token (15 мин) + refresh token (7 дней) со стратегией passport-jwt. Подтверждение email перед первым входом. Refresh токены хранятся как SHA-256 хеш с ротацией и обнаружением повторного использования
  • Заголовки безопасности: CSP, HSTS (продакшн), белый список CORS через helmet
  • Ограничение запросов: Лимиты на эндпоинты (регистрация 5/мин, вход 10/мин и т.д.) + глобально 60/мин через Redis. Блокировка после 5 неудачных попыток
  • Требования к паролю: 8-128 символов, заглавная + строчная + цифра + спецсимвол, хешируется bcrypt (cost 10)
  • Разрешения: Пользовательский декоратор @Permissions() + PermissionsGuard — проверяет requiredPermissions против эффективных разрешений пользователя
  • Реальное время: NotificationsGateway (пространство имён /notifications) — отправляет в комнаты user:<id>
  • База данных: PostgreSQL с Prisma ORM, миграции через prisma migrate (для продакшна), prisma db push для локальной разработки
  • Swagger UI: Автоматическая документация API доступна по /api/docs (только разработка)

Ключевые проектные решения

Модуль уведомлений

  • @Global() — все сервисы внедряют NotificationsService напрямую
  • NotificationsService.create() — fire-and-forget (не ожидается) для избежания замедления основных операций
  • WebSocket-шлюз (/notifications) аутентифицируется через handshake.auth.token с использованием JwtService

Задачи — в рамках проекта

  • projectId в модели Task обязателен с каскадным удалением от Project
  • CRUD через ProjectTasksController на /projects/:id/tasks (разрешения уровня PROJECT)
  • Комментарии к задачам через ProjectTaskCommentsController на /projects/:id/tasks/:taskId/comments
  • История задач логируется автоматически при создании/обновлении/изменении статуса/назначении/удалении

Система разрешений

  • 30+ детальных разрешений в 6 областях: GLOBAL, ORGANIZATION, TEAM, PROJECT, TASK, CHAT
  • Пользовательские роли могут комбинировать любой набор разрешений
  • Группы пользователей для массового назначения ролей
  • Вычисляемые разрешения агрегируются из ролей пользователя на глобальном уровне, уровне организации, команды и проекта