Skip to content

Модели данных ​

Диаграмма базы данных ​


BaseEntity ​

Все сущности наследуются от BaseEntity, которая предоставляет общие поля:

typescript
export abstract class BaseEntity<Optional extends string = never> {
  @PrimaryKey({ type: 'integer' })
  id!: number;                    // Автоинкрементный PK

  @Property({ type: 'datetime', onCreate: () => new Date() })
  createdAt: Date = new Date();   // Дата создания

  @Property({ type: 'datetime', onCreate: () => new Date(), onUpdate: () => new Date() })
  updatedAt: Date = new Date();   // Дата последнего обновления
}

Каждая сущность также имеет поле guid (UUID v4) — публичный идентификатор, используемый в API вместо числового id.


Institute ​

Институт университета СКФУ. Содержит пользователей.

Таблица: institute

ПолеТипОписание
idint, PKАвтоинкрементный идентификатор
guidstring(36), uniqueПубличный UUID
namestring(255), uniqueНазвание института
createdAtdatetimeДата создания
updatedAtdatetimeДата обновления

Связи:

  • OneToMany → User — институт содержит множество пользователей. При удалении института каскадно удаляются все его пользователи (Cascade.REMOVE, orphanRemoval: true)
typescript
@Entity()
export class Institute extends BaseEntity<'guid'> {
  @Property({ type: 'string', length: 36, unique: true, onCreate: () => randomUUID() })
  guid: string = randomUUID();

  @Property({ type: 'string', length: 255, unique: true })
  name!: string;

  @OneToMany(() => User, (u) => u.institute, {
    cascade: [Cascade.REMOVE],
    orphanRemoval: true
  })
  users = new Collection<User>(this);
}

User ​

Пользователь системы — студент, организатор или администратор.

Таблица: user

ПолеТипОписание
idint, PKАвтоинкрементный идентификатор
guidstring(36), uniqueПубличный UUID
xamIdint, uniqueID пользователя в мессенджере MAX
firstNamestring(100)Имя
lastNamestring(100)Фамилия
instituteFK → InstituteИнститут
groupstring(22)Учебная группа
rolestring(16), default 'user'Роль: user, organizer, admin
avatarUrlstring(500), nullableURL аватара из MAX
themestring(8), default 'dark'Тема интерфейса: dark / light
notificationsboolean, default trueВключены ли уведомления
createdAtdatetimeДата создания
updatedAtdatetimeДата обновления

Связи:

  • ManyToOne → Institute — пользователь принадлежит одному институту

Процесс регистрации:

  1. Администратор создаёт пользователя через API (xamId = 0)
  2. Пользователь сканирует QR-код с guid в приложении MAX
  3. Система привязывает xamId из InitData к записи пользователя
  4. После привязки пользователь авторизуется автоматически

Event ​

Мероприятие с датой, местом проведения и ограничением по вместимости.

Таблица: event

ПолеТипОписание
idint, PKАвтоинкрементный идентификатор
guidstring(36), uniqueПубличный UUID
titlestring(255)Название мероприятия
descriptionstring(2000)Описание
datedatetimeДата и время проведения
locationstring(255)Место проведения
capacityintМаксимальное количество участников
colorstring(7)HEX-цвет для отображения в UI
createdAtdatetimeДата создания
updatedAtdatetimeДата обновления

Связи:

  • ManyToMany → EventType — мероприятие может иметь несколько типов/категорий
  • OneToMany → EventRegistration — регистрации участников. Каскадное удаление при удалении мероприятия

EventType ​

Тип/категория мероприятия (например: «Лекция», «Конференция», «Спорт»).

Таблица: event_type

ПолеТипОписание
idint, PKАвтоинкрементный идентификатор
guidstring(36), uniqueПубличный UUID
namestring(100), uniqueНазвание типа
createdAtdatetimeДата создания
updatedAtdatetimeДата обновления

Используется для фильтрации мероприятий на фронтенде и в API.


EventRegistration ​

Регистрация пользователя на мероприятие и отметка посещаемости.

Таблица: event_registration

ПолеТипОписание
idint, PKАвтоинкрементный идентификатор
guidstring(36), uniqueПубличный UUID
eventFK → EventМероприятие
userFK → UserПользователь
attendedboolean, default falseОтметка о посещении
createdAtdatetimeДата регистрации
updatedAtdatetimeДата обновления

Ограничения:

  • Unique(event, user) — пользователь может зарегистрироваться на мероприятие только один раз

Бизнес-логика:

  • При регистрации проверяется, не превышена ли вместимость мероприятия (capacity)
  • Отметка посещаемости (attended = true) ставится организатором через QR-сканер
  • Статистика посещаемости рассчитывается на основе соотношения attended = true к общему числу регистраций

NCFU Events Documentation