Модели данных
В проекте есть базовая модель данных (BaseModel
), с базовым сервисом, от которого наследуются все остальные.
CategoriesModel
Модель категорий.
/**
* Модель для категорий
*/
@ObjectType()
@Entity({ name: "categories" })
export class CategoriesModel extends BaseModel {
@Field({ description: "Название категории" })
@Column({ type: "varchar", length: 255, unique: true })
title: string;
}
CommentsModel
Модель для комментариев.
@ObjectType()
@Entity({ name: "comments" })
export class CommentsModel extends BaseModel {
@Field({ description: "Комментарий" })
@Column({ type: "text" })
comment: string;
@Field(() => UsersModel, { description: "Автор" })
@ManyToOne(() => UsersModel)
owner: UsersModel;
@Column({ nullable: true })
ownerId: string;
@Field(() => PostsModel, { description: "Пост", nullable: true })
@ManyToOne(() => PostsModel, { onDelete: "CASCADE" })
post: PostsModel;
@Column({ nullable: true })
postId: string;
@Field(() => TasksModel, { description: "Таск", nullable: true })
@ManyToOne(() => TasksModel, { onDelete: "CASCADE" })
task: TasksModel;
@Column({ nullable: true })
taskId: string;
@Field(() => [UsersModel], { description: "Пользователи, поставившие лайк" })
@ManyToMany(() => UsersModel, (user) => user.comments_liked)
users_liked: UsersModel[];
@Field(() => CommentsModel, {
description: "Родительский комментарий",
nullable: true,
})
@ManyToOne(() => CommentsModel, { nullable: true, onDelete: "CASCADE" })
parent?: CommentsModel;
}
CompletedTasksModel
Модель для завершенных задач.
@ObjectType()
@Entity({ name: "completed-tasks" })
export class CompletedTasksModel extends BaseModel {
@Field(() => UsersModel, { description: "Пользователь" })
@ManyToOne(() => UsersModel)
user: UsersModel;
@Field(() => TasksModel, { description: "Таск" })
@ManyToOne(() => TasksModel)
task: TasksModel;
@Column()
userId: string;
@Column()
taskId: string;
}
ErrorsModel
Модель ошибок. Предназначена для приема и логгирования ошибок от МП в БД.
@ObjectType()
@Entity({ name: "errors" })
export class ErrorsModel extends BaseModel {
@Field(() => GraphQLInt, { description: "Код ошибки", nullable: true })
@Column({ type: "int", nullable: true })
code?: number;
@Field({ description: "Имя файла", nullable: true })
@Column({ type: "text", nullable: true })
file?: string;
@Field(() => GraphQLInt, { description: "Строка", nullable: true })
@Column({ type: "int", nullable: true })
line?: number;
@Field({ description: "Сообщение", nullable: true })
@Column({ type: "text", nullable: true })
message?: string;
@Field({ description: "Версия", nullable: true })
@Column({ type: "varchar", length: 255, nullable: true })
version?: string;
@Field({ description: "ID устройства", nullable: true })
@Column({ type: "varchar", length: 36, nullable: true })
device_id?: string;
@Field({ description: "Функция", nullable: true })
@Column({ type: "varchar", length: 255, nullable: true })
function?: string;
@Field({ description: "Агент", nullable: true })
@Column({ type: "varchar", length: 255, nullable: true })
user_agent?: string;
}
ImagesModel
Модель для изображений. Аватаров/миниатюр/постеров и т.д.
@ObjectType()
@Entity({ name: "images" })
export class ImagesModel extends BaseModel {
@Field({ description: "Название", nullable: true })
@Column({ type: "varchar", length: 255, nullable: true })
title?: string;
@Field({ description: "Путь к файлу" })
@Column({ type: "varchar", length: 255 })
url: string;
@Field(() => UsersModel, { description: "Автор" })
@ManyToOne(() => UsersModel)
owner: UsersModel;
@Column({ nullable: true })
ownerId: string;
}
InvitesModel
Модель для инвайтов. Для доступа к программам по приглашениям.
@ObjectType()
@Entity({ name: "invites" })
export class InvitesModel extends BaseModel {
@Field(() => ProgramsModel, { description: "Программа" })
@ManyToOne(() => ProgramsModel, { nullable: true, onDelete: "CASCADE" })
program?: ProgramsModel;
@Field({ description: "Использован" })
@Column({ type: "boolean", default: false })
is_used: boolean;
}
MentorCommentsModel
Комментарии от менторов и для менторов. Требует переработки и возможно объединения с CommentsModel
.
@ObjectType()
@Entity({ name: "mentor-comments" })
export class MentorCommentsModel extends BaseModel {
@Field({ description: "Комментарий" })
@Column({ type: "text" })
comment: string;
@Field(() => UsersModel, { description: "Автор" })
@ManyToOne(() => UsersModel)
owner: UsersModel;
@Column({ nullable: true })
ownerId: string;
@Field(() => UsersModel, { description: "Для участника" })
@ManyToOne(() => UsersModel)
forUser: UsersModel;
@Column({ nullable: true })
forUserId: string;
@Field(() => TasksModel, { description: "Таск", nullable: true })
@ManyToOne(() => TasksModel, { onDelete: "CASCADE" })
task: TasksModel;
@Column({ nullable: true })
taskId: string;
@Field(() => ProgramsModel, { description: "Таск", nullable: true })
@ManyToOne(() => ProgramsModel, { onDelete: "CASCADE" })
program: TasksModel;
@Column({ nullable: true })
programId: string;
@Field(() => MentorCommentsModel, {
description: "Родительский комментарий",
nullable: true,
})
@ManyToOne(() => MentorCommentsModel, { nullable: true, onDelete: "CASCADE" })
parent?: MentorCommentsModel;
}
PostsModel
модель для постов (блогов).
export enum PostsOrder {
created_at = "created_at",
}
registerEnumType(PostsOrder, { name: "PostsOrder" });
@ObjectType()
@Entity({ name: "posts" })
export class PostsModel extends BaseModel {
@Field({ description: "Название", nullable: true })
@Column({ type: "varchar", length: 255, nullable: true })
title: string;
@Field({ description: "Описание", nullable: true })
@Column({ type: "text", nullable: true })
description: string;
@Field(() => [TagsModel], { description: "Теги" })
@ManyToMany(() => TagsModel, { cascade: true })
@JoinTable({ name: "posts_tags" })
tags: TagsModel[];
@Field(() => UsersModel, { description: "Автор" })
@ManyToOne(() => UsersModel, (user) => user.owned_posts)
owner: UsersModel;
@Column({ nullable: true })
ownerId: string;
@Field(() => ProgramsModel, { description: "Программа", nullable: true })
@ManyToOne(() => ProgramsModel, { nullable: true, onDelete: "CASCADE" })
program?: ProgramsModel;
@Column({ nullable: true })
programId: string;
@Field(() => TasksModel, { description: "Таск", nullable: true })
@ManyToOne(() => TasksModel, { nullable: true, onDelete: "CASCADE" })
task?: TasksModel;
@Column({ nullable: true })
taskId: string;
@Field(() => [UsersModel], { description: "Пользователи, поставившие лайк" })
@ManyToMany(() => UsersModel, (user) => user.posts_liked)
users_liked: UsersModel[];
@Field(() => [CommentsModel], { description: "Комментарии" })
@OneToMany(() => CommentsModel, (comment) => comment.post, { onDelete: "CASCADE" })
comments: CommentsModel[];
@Field(() => [ImagesModel], {
description: "Изображения, которые загрузили к посту",
})
@ManyToMany(() => ImagesModel, { cascade: true })
@JoinTable({ name: "posts_uploaded_images" })
uploaded_images?: ImagesModel[];
@Field(() => [VideosModel], {
description: "Видео, которые загрузили к посту",
})
@ManyToMany(() => VideosModel, { cascade: true })
@JoinTable({ name: "posts_uploaded_videos" })
uploaded_videos?: VideosModel[];
@Field({ description: "Ссылка", nullable: true })
@Column({ type: "varchar", length: 1024, nullable: true })
link?: string;
}
ProgramsModel
модель программ.
export enum ProgramsOrder {
created_at = "created_at",
begin_at = "begin_at",
end_at = "end_at",
title = "title",
}
registerEnumType(ProgramsOrder, { name: "ProgramsOrder" });
/**
* Enum видимости/доступности программ
*/
export enum ProgramVisibility {
owner,
favorite,
public,
mentor,
}
registerEnumType(ProgramVisibility, { name: "ProgramVisibility" });
@ObjectType()
@Entity({ name: "programs" })
export class ProgramsModel extends BaseModel {
@Field({ description: "Награда" })
@Column({ length: 500 })
reward: string;
@Field({ description: "Название программы" })
@Column({ length: 500 })
title: string;
@Field({ description: "Для чего нужна программа", nullable: true })
@Column({ type: "text", nullable: true })
goal?: string;
@Field({ description: "Описание программы", nullable: true })
@Column({ type: "text", nullable: true })
description?: string;
@Field(() => GraphQLInt, {
description: "Баллы за выполнение",
nullable: true,
})
@Column({ type: "int", nullable: true })
score?: number;
@Field(() => UsersModel, { description: "Автор" })
@ManyToOne(() => UsersModel, { onDelete: "SET NULL" })
owner: UsersModel;
@Column({ nullable: true })
ownerId: string;
@Field(() => ProgramVisibility, { description: "Тип программы(видимость)" })
@Column({ type: "int", default: ProgramVisibility.owner })
visibility: ProgramVisibility;
@Field(() => Boolean, { description: "Программа в архиве" })
@Column({ type: "boolean", default: false })
isArchived: boolean;
@Field({ description: "Категория" })
@ManyToOne(() => CategoriesModel, { onDelete: "SET NULL" })
@JoinColumn()
category: CategoriesModel;
@Field({ description: "Дата начала" })
@Column({ type: "timestamptz" })
begin_at: Date;
@Field({ description: "Дата окончания" })
@Column({ type: "timestamptz" })
end_at: Date;
@Field(() => [TagsModel], { nullable: true, description: "Тэги программы" })
@ManyToMany(() => TagsModel)
@JoinTable({ name: "programs_tags" })
tags: TagsModel[];
@Field(() => [TasksModel], {
nullable: true,
description: "Задачи программы",
})
@OneToMany(() => TasksModel, (task) => task.program, { onDelete: "CASCADE" })
tasks: TasksModel[];
@Field(() => [UsersModel], {
description: "Присоединившиеся к программе пользователи",
})
@ManyToMany(() => UsersModel, (user) => user.joined_programs)
joined_users: UsersModel[];
@Field(() => [UsersModel], {
description: "Пользователи, добавившие в избранное",
})
@ManyToMany(() => UsersModel, (user) => user.favorite_programs)
users_favorite: UsersModel[];
@Field(() => [UsersModel], {
description: "Пользователи, завершившие программу",
})
@ManyToMany(() => UsersModel, (user) => user.completed_programs)
users_completed: UsersModel[];
@Field(() => [PostsModel], { description: "Посты о программе (блоги)" })
@OneToMany(() => PostsModel, (post) => post.program, { onDelete: "CASCADE" })
posts: PostsModel[];
@Field(() => [ImagesModel], {
description: "Изображения, которые загрузили к программе",
})
@ManyToMany(() => ImagesModel, { cascade: true })
@JoinTable({ name: "programs_uploaded_images" })
uploaded_images?: ImagesModel[];
@Field(() => [VideosModel], {
description: "Видео, которые загрузили к программе",
})
@ManyToMany(() => VideosModel, { cascade: true })
@JoinTable({ name: "programs_uploaded_videos" })
uploaded_videos?: VideosModel[];
@Field(() => VideosModel, {
description: "Мотивационное видео",
nullable: true,
})
@ManyToOne(() => VideosModel)
@JoinColumn()
motivation_video?: VideosModel;
@Column({ nullable: true })
motivationVideoId: string;
@Field(() => GraphQLInt, {
description: "Продолжительность (в днях)",
defaultValue: 0,
nullable: true,
})
duration: number;
@Field(() => GraphQLBoolean, {
description: "Разрешать джойниться после старта",
defaultValue: false,
nullable: true,
})
@Column({ default: false })
allow_after_start_join: boolean;
}
TagsModel
модель для тегов.
@ObjectType()
@Entity({ name: "tags" })
export class TagsModel extends BaseModel {
@Field({ description: "Имя тега" })
@Column({ type: "varchar", length: 255, unique: true })
title: string;
}
TasksModel
модель для задач.
@ObjectType()
@Entity({ name: "tasks" })
export class TasksModel extends BaseModel {
@Field({ description: "Название", nullable: true })
@Column({ type: "varchar", length: 255 })
title: string;
@Field({ description: "Описание", nullable: true })
@Column({ type: "text", nullable: true })
description?: string;
@Field({ description: "Дата окончания", nullable: true })
@Column({ type: "timestamptz", nullable: true })
complete_at?: Date;
@Field({ description: "Таймер", nullable: true })
timer?: TimersModel;
@Field({ description: "Время таймера", nullable: true })
@Column({ type: "integer", nullable: true })
timer_time?: number;
@Field(() => ProgramsModel, {
description: "Родительская программа",
nullable: true,
})
@ManyToOne(() => ProgramsModel, (program) => program.tasks, { onDelete: "CASCADE" })
program: ProgramsModel;
@Field(() => [PostsModel], { description: "Посты о таске (блоги)" })
@OneToMany(() => PostsModel, (post) => post.task, { onDelete: "CASCADE" })
posts: PostsModel[];
@Field(() => [UsersModel], {
description: "Пользователи, завершившие задачу",
})
@ManyToMany(() => UsersModel, (user) => user.completed_tasks)
users_completed: UsersModel[];
@Field(() => [CommentsModel], { description: "Комментарии к задаче" })
@OneToMany(() => CommentsModel, (comment) => comment.task, { onDelete: "CASCADE" })
comments: CommentsModel[];
@Field(() => [ImagesModel], {
description: "Изображения, которые загрузили к задаче",
})
@ManyToMany(() => ImagesModel, { cascade: true })
@JoinTable({ name: "tasks_uploaded_images" })
uploaded_images?: ImagesModel[];
@Field(() => [VideosModel], {
description: "Видео, которые загрузили к задаче",
})
@ManyToMany(() => VideosModel, { cascade: true })
@JoinTable({ name: "tasks_uploaded_videos" })
uploaded_videos?: VideosModel[];
@Field({ description: "Дата завершения пользователем", nullable: true })
user_complete_at?: Date;
}
TimersModel
модель для таймеров к задачам.
@ObjectType()
@Entity({ name: "task_timers" })
export class TimersModel extends BaseModel {
@Field({ description: "Продолжительность таймера" })
@Column({ type: "integer" })
duration: number;
@Field({ description: "Учтеное время" })
@Column({ type: "integer", default: 0 })
elapsed: number;
@Field({ description: "Учтеное время" })
@Column()
state_at: Date;
@Field(() => TimerState, { description: "Состояние таймера" })
@Column({ type: "int", default: TimerState.initialized })
state: TimerState;
@Field(() => UsersModel, { description: "Автор" })
@ManyToOne(() => UsersModel, { onDelete: "SET NULL" })
owner: UsersModel;
@Column({ nullable: true })
ownerId: string;
@Field(() => TasksModel, { description: "Таск" })
@ManyToOne(() => TasksModel, { onDelete: "SET NULL" })
task: TasksModel;
@Column({ nullable: true })
taskId: string;
}
UsersModel
модель пользователей.
@ObjectType()
@Entity({ name: "users" })
export class UsersModel extends BaseModel {
@Field({ description: "Имя пользователя" })
@Column({ length: 500, nullable: true })
name: string;
@Field({ description: "Описание", nullable: true })
@Column({ type: "text", nullable: true })
description?: string;
@Column({ length: 12, unique: true, nullable: true })
@HideField()
phone: string;
@Column({ length: 500, unique: true, nullable: true })
@HideField()
email: string;
@HideField()
@Column({ length: 40, nullable: true })
pinhash: string;
@HideField()
@Column({ length: 16, nullable: true })
salt: string;
@Field({ description: "Баллы" })
@Column({ type: "int", default: 0 })
scores: number;
@Field(() => ImagesModel, {
description: "Изображение аватара",
nullable: true,
})
@ManyToOne(() => ImagesModel)
@JoinColumn()
avatar?: ImagesModel;
@Field(() => [ProgramsModel], {
description: "Программы, к которым присоединился пользователь",
})
@ManyToMany(() => ProgramsModel, (program) => program.joined_users)
@JoinTable({ name: "users_joined_programs" })
joined_programs: ProgramsModel[];
@Field(() => [ProgramsModel], {
description: "Программы, которые пользователь добавил в избранное",
})
@ManyToMany(() => ProgramsModel, (program) => program.users_favorite)
@JoinTable({ name: "users_favorite_programs" })
favorite_programs: ProgramsModel[];
@Field(() => [ProgramsModel], {
description: "Программы, которые создал пользователь",
})
@OneToMany(() => ProgramsModel, (program) => program.owner)
owned_programs: ProgramsModel[];
@Field(() => [PostsModel], {
description: "Посты, которые создал пользователь",
})
@OneToMany(() => PostsModel, (post) => post.owner)
owned_posts: PostsModel[];
@Field(() => [TasksModel], {
description: "Задачи, которые завершил пользователь",
})
@ManyToMany(() => TasksModel, (task) => task.users_completed)
@JoinTable({ name: "users_completed_tasks" })
completed_tasks: TasksModel[];
@Field(() => [ProgramsModel], {
description: "Программы, которые завершил пользователь",
})
@ManyToMany(() => ProgramsModel, (program) => program.users_completed)
@JoinTable({ name: "users_completed_programs" })
completed_programs: ProgramsModel[];
@Field(() => [PostsModel], {
description: "Посты, которые лайкнул пользователь",
})
@ManyToMany(() => PostsModel, (post) => post.users_liked)
@JoinTable({ name: "users_liked_posts" })
posts_liked: PostsModel[];
@Field(() => [CommentsModel], {
description: "Комментарии, которые лайкнул пользователь",
})
@ManyToMany(() => CommentsModel, (comment) => comment.users_liked)
@JoinTable({ name: "users_liked_comments" })
comments_liked?: CommentsModel[];
@Field(() => [ImagesModel], {
description: "Изображения, которые загрузил пользователь",
})
@ManyToMany(() => ImagesModel, { cascade: true })
@JoinTable({ name: "users_uploaded_images" })
uploaded_images?: ImagesModel[];
@Field(() => [VideosModel], {
description: "Видео, которые загрузил пользователь",
})
@ManyToMany(() => VideosModel, { cascade: true })
@JoinTable({ name: "users_uploaded_videos" })
uploaded_videos?: VideosModel[];
}
VideosModel
модель видео (прикрепленных видео).
@ObjectType()
@Entity({ name: "videos" })
export class VideosModel extends BaseModel {
@Field({ description: "Название", nullable: true })
@Column({ type: "varchar", length: 255, nullable: true })
title?: string;
@Field({ description: "Путь к файлу", nullable: true })
@Column({ type: "varchar", length: 255, nullable: true, default: null })
url?: string;
@Field({
description: "Ссылка на youtube",
nullable: true,
defaultValue: null,
})
@Column({ type: "varchar", length: 255, nullable: true, default: null })
youtube_link?: string;
@Field(() => UsersModel, { description: "Автор" })
@ManyToOne(() => UsersModel)
owner: UsersModel;
@Column({ nullable: true })
ownerId: string;
@Field(() => ImagesModel, { description: "Миниатюра", nullable: true })
@ManyToOne(() => ImagesModel, { onDelete: "SET NULL", nullable: true })
thumbnail?: ImagesModel;
}