Files
stream.graff.tech-new/server/COMPANIES_BRANCHES.md
T

9.2 KiB

Компании и филиалы - Документация

Обзор

Добавлена функциональность для управления компаниями и филиалами с поддержкой привязки пользователей к нескольким филиалам.

Структура базы данных

Таблицы

companies - Компании

  • id - UUID, первичный ключ
  • name - Название компании (обязательное)
  • description - Описание компании
  • createdAt - Дата создания
  • updatedAt - Дата обновления

branches - Филиалы

  • id - UUID, первичный ключ
  • companyId - UUID, внешний ключ на компанию (каскадное удаление)
  • name - Название филиала (обязательное)
  • address - Адрес филиала
  • city - Город
  • country - Страна
  • createdAt - Дата создания
  • updatedAt - Дата обновления

user_branches - Связь пользователей и филиалов (Many-to-Many)

  • userId - UUID, внешний ключ на пользователя (каскадное удаление)
  • branchId - UUID, внешний ключ на филиал (каскадное удаление)
  • createdAt - Дата создания
  • Составной первичный ключ: (userId, branchId)

Изменения в таблице users

Добавлено поле:

  • currentBranchId - UUID, внешний ключ на выбранный филиал (nullable)

API Эндпоинты

Все эндпоинты требуют авторизации через Bearer токен.

Компании (/companies)

GET /companies

Получить список всех компаний с их филиалами.

Ответ:

{
  "companies": [
    {
      "id": "uuid",
      "name": "Компания 1",
      "description": "Описание",
      "branches": [...],
      "createdAt": "2024-01-01T00:00:00Z",
      "updatedAt": "2024-01-01T00:00:00Z"
    }
  ]
}

GET /companies/:id

Получить компанию по ID.

Параметры:

  • id - UUID компании

Ответ:

{
  "company": {
    "id": "uuid",
    "name": "Компания 1",
    "description": "Описание",
    "branches": [...],
    "createdAt": "2024-01-01T00:00:00Z",
    "updatedAt": "2024-01-01T00:00:00Z"
  }
}

POST /companies

Создать новую компанию.

Body:

{
  "name": "Новая компания",
  "description": "Описание (опционально)"
}

Ответ:

{
  "company": {
    "id": "uuid",
    "name": "Новая компания",
    "description": "Описание",
    "createdAt": "2024-01-01T00:00:00Z",
    "updatedAt": "2024-01-01T00:00:00Z"
  }
}

PATCH /companies/:id

Обновить компанию.

Body:

{
  "name": "Обновленное название (опционально)",
  "description": "Обновленное описание (опционально)"
}

DELETE /companies/:id

Удалить компанию (каскадно удалит все филиалы).

Ответ:

{
  "message": "Company deleted successfully"
}

Филиалы (/branches)

GET /branches/my

Получить филиалы текущего пользователя.

Ответ:

{
  "branches": [
    {
      "id": "uuid",
      "companyId": "uuid",
      "name": "Филиал 1",
      "address": "Адрес",
      "city": "Город",
      "country": "Страна",
      "company": {...},
      "createdAt": "2024-01-01T00:00:00Z",
      "updatedAt": "2024-01-01T00:00:00Z"
    }
  ]
}

GET /branches/:id

Получить филиал по ID.

Ответ:

{
  "branch": {
    "id": "uuid",
    "companyId": "uuid",
    "name": "Филиал 1",
    "address": "Адрес",
    "city": "Город",
    "country": "Страна",
    "company": {...},
    "createdAt": "2024-01-01T00:00:00Z",
    "updatedAt": "2024-01-01T00:00:00Z"
  }
}

GET /branches/:id/users

Получить пользователей филиала.

Ответ:

{
  "users": [
    {
      "id": "uuid",
      "email": "user@example.com",
      "fullName": "Иван Иванов",
      "role": "manager",
      "currentBranchId": "uuid"
    }
  ]
}

POST /branches

Создать новый филиал.

Body:

{
  "companyId": "uuid",
  "name": "Новый филиал",
  "address": "Адрес (опционально)",
  "city": "Город (опционально)",
  "country": "Страна (опционально)"
}

PATCH /branches/:id

Обновить филиал.

Body:

{
  "name": "Обновленное название (опционально)",
  "address": "Обновленный адрес (опционально)",
  "city": "Обновленный город (опционально)",
  "country": "Обновленная страна (опционально)"
}

DELETE /branches/:id

Удалить филиал.

POST /branches/:id/users

Привязать пользователя к филиалу.

Body:

{
  "userId": "uuid"
}

Ответ:

{
  "message": "User assigned to branch successfully"
}

DELETE /branches/:id/users/:userId

Отвязать пользователя от филиала.

Ответ:

{
  "message": "User removed from branch successfully"
}

POST /branches/:id/select

Установить филиал как текущий для авторизованного пользователя.

Ответ:

{
  "message": "Current branch updated successfully",
  "currentBranchId": "uuid"
}

Ошибки:

  • 400 - Пользователь не привязан к этому филиалу

Использование

Создание компании и филиалов

// 1. Создать компанию
POST /companies
{
  "name": "ООО Рога и Копыта",
  "description": "Крупная IT компания"
}

// 2. Создать филиалы
POST /branches
{
  "companyId": "company-uuid",
  "name": "Московский офис",
  "city": "Москва",
  "country": "Россия"
}

POST /branches
{
  "companyId": "company-uuid",
  "name": "Питерский офис",
  "city": "Санкт-Петербург",
  "country": "Россия"
}

Привязка пользователя к филиалам

// Привязать пользователя к московскому офису
POST /branches/{moscow-branch-id}/users
{
  "userId": "user-uuid"
}

// Привязать пользователя к питерскому офису
POST /branches/{spb-branch-id}/users
{
  "userId": "user-uuid"
}

Выбор текущего филиала

// Установить московский офис как текущий
POST /branches/{moscow-branch-id}/select

// Теперь в объекте пользователя currentBranchId будет указывать на московский офис

Получение филиалов пользователя

// Получить все филиалы, к которым привязан пользователь
GET /branches/my

Миграция базы данных

После добавления схем необходимо выполнить миграцию:

cd server
bun run drizzle-kit generate
bun run drizzle-kit migrate

Типы TypeScript

Company

type Company = {
  id: string;
  name: string;
  description: string | null;
  createdAt: Date;
  updatedAt: Date;
};

Branch

type Branch = {
  id: string;
  companyId: string;
  name: string;
  address: string | null;
  city: string | null;
  country: string | null;
  createdAt: Date;
  updatedAt: Date;
};

UserBranch

type UserBranch = {
  userId: string;
  branchId: string;
  createdAt: Date;
};

Примечания

  1. Каскадное удаление: При удалении компании автоматически удаляются все её филиалы
  2. Каскадное удаление связей: При удалении пользователя или филиала автоматически удаляются все связи в таблице user_branches
  3. Валидация: Пользователь может установить текущим только тот филиал, к которому он привязан
  4. Many-to-Many: Пользователь может быть привязан к нескольким филиалам одновременно
  5. Текущий филиал: Поле currentBranchId в таблице пользователей позволяет отслеживать, в каком филиале пользователь работает в данный момент