Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/chats business entity #110

Draft
wants to merge 71 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
b21e56b
feat: Cоздаёт базовую фаловую структуру для сущности бизнес-логики 'Ч…
aleksr777 Jul 3, 2024
3579716
feat: удалил лишний код, реализовал сущность бизнес-логики Chats, ско…
aleksr777 Jul 6, 2024
ee7c761
fix: удалил лишний импорт контроллера
aleksr777 Jul 6, 2024
41bd68d
fix: удалил лишний файл репозитория из entities, подключился к репози…
aleksr777 Jul 13, 2024
82edbca
feat: Cоздаёт базовую фаловую структуру для сущности бизнес-логики 'Ч…
aleksr777 Jul 14, 2024
185dbf6
feat: удалил лишний код, реализовал сущность бизнес-логики Chats, ско…
aleksr777 Jul 14, 2024
49657ca
fix: удалил лишний импорт контроллера
aleksr777 Jul 14, 2024
d0cdafa
fix: удалил лишний файл репозитория из entities, подключился к репози…
aleksr777 Jul 14, 2024
3b2ab25
Merge branch 'feature/chats-business-entity' of github.com:ya-pomogau…
aleksr777 Jul 14, 2024
0183b3b
refactor: вернулся к исходному коду
aleksr777 Jul 14, 2024
14087f0
refactor: вернулся к исходному коду
aleksr777 Jul 14, 2024
73fded0
fix: обновил код сущности, запросы к базе данных идёт теперь напрямую…
aleksr777 Jul 14, 2024
2e14c7a
fix: поправки по замечаниям
aleksr777 Jul 19, 2024
235905f
fix: поправка в типизации
aleksr777 Jul 19, 2024
5beb219
fix: упростил код поиска сообщений чата
aleksr777 Jul 19, 2024
38bc45d
fix: незначительные поправки
aleksr777 Jul 23, 2024
9f7ef5e
Merge branch 'development' into feature/chats-business-entity
aleksr777 Jul 23, 2024
1e9af4c
fix: поправки в сущности, создал тест
aleksr777 Jul 25, 2024
ef92513
Merge branch 'development' of github.com:ya-pomogau/backend into deve…
aleksr777 Jul 25, 2024
fb7a238
Merge branch 'development' into feature/chats-business-entity
aleksr777 Jul 25, 2024
95e6c49
fix: временно удалил подключение к app.module, чтобы не возникало ошибок
aleksr777 Jul 25, 2024
28ad4f4
fix: внёс необходимые поправки, создал новые чаты, исправил тест для …
aleksr777 Jul 28, 2024
34815a0
Merge branch 'development' into feature/chats-business-entity
aleksr777 Jul 29, 2024
4b59952
Merge branch 'development' into feature/chats-business-entity
aleksr777 Jul 30, 2024
55aabe5
Merge branch 'development' into feature/chats-business-entity
aleksr777 Aug 1, 2024
c9fe5fd
fix: добавлены тесты
aleksr777 Aug 1, 2024
632637a
Merge branch 'development' into feature/chats-business-entity
aleksr777 Aug 2, 2024
9b25b61
fix: поправки в тестах
aleksr777 Aug 2, 2024
9c7a943
feat: добавил недостающие методы в сущности
aleksr777 Aug 8, 2024
b69869b
Merge branch 'development' into feature/chats-business-entity
aleksr777 Aug 8, 2024
5d3bf1d
fix: поправки в типизации
aleksr777 Aug 8, 2024
6cd68db
fix: незначительные поправки в коде, добавлен геттер для получения со…
aleksr777 Aug 9, 2024
0432685
feat: написал каркас для общего chat.entity
aleksr777 Aug 9, 2024
bb7f530
feat: создан метод createChat, поправки типизации, создан метод loadM…
aleksr777 Aug 11, 2024
019c57d
feat: Добавлен метод findChatByParams для поиска чата по параметрам
aleksr777 Aug 11, 2024
cd4b278
feat: добавлен метод addMessage, небольшие поправки в остальном коде
aleksr777 Aug 12, 2024
7be02f2
feat: добавлен метод closeChat, дополнительные правки по всему коду.
aleksr777 Aug 12, 2024
5bfc846
feat: добавил интерфейс и тест, удалил лишние файлы
aleksr777 Aug 12, 2024
51caeb0
Merge branch 'development' into feature/chats-business-entity
aleksr777 Aug 12, 2024
1c247a5
feat: написан тест создания чатов для разных типов
aleksr777 Aug 17, 2024
24bf152
Merge branch 'development' into feature/chats-business-entity
aleksr777 Aug 17, 2024
33d9d51
feat: добавлены тесты закрытия чата, поправки в основном коде
aleksr777 Aug 17, 2024
c5d77c7
feat: добавлен тест загрузки сообщений, поправки в entity
aleksr777 Aug 17, 2024
6c6cca3
feat: добавлен тест добавления сообщения и тест поиска чата по параме…
aleksr777 Aug 17, 2024
21b1828
fix: Исправил возвращаемый тип данных при создании чата и поиска чата…
aleksr777 Aug 18, 2024
6082b4e
fix: переименовал интерфейс
aleksr777 Aug 18, 2024
a5a0d9f
fix: внёс поправки в описании геттеров в интерфейсе.
aleksr777 Aug 18, 2024
4c87ebd
fix: удалён декоратор Injectable
aleksr777 Aug 26, 2024
e6847c2
fix: поправка в тестах
aleksr777 Aug 26, 2024
a56d7f8
fix: добавлен общий тип для конфликтных чатов
aleksr777 Aug 26, 2024
a371b3e
fix: поправка в методе createChat
aleksr777 Aug 26, 2024
271fe3f
fix: поправка в типизации dto
aleksr777 Aug 26, 2024
90f1de2
fix: данные вносятся теперь только после получения ответа от БД, уточ…
aleksr777 Aug 26, 2024
aea6ff6
refactor: изменения в типизации
aleksr777 Aug 27, 2024
bfdb894
fix: добавлен поиск сообщений чатов по нескольким id, поправки в тестах.
aleksr777 Aug 27, 2024
fd90134
feat: вынес константы теста в отдельный файл
aleksr777 Aug 27, 2024
5f99c13
feat: добавил проверки для геттеров
aleksr777 Aug 28, 2024
ce9f525
fix: подправил loadMessages()
aleksr777 Aug 28, 2024
175ad4b
Merge branch 'development' into feature/chats-business-entity
kspshnik Nov 27, 2024
8d0e9f3
[Merge] Merged `development` into `feature/business-chat-entity` / Te…
kspshnik Nov 27, 2024
73ed128
[Merge] Merged `development` into `feature/business-chat-entity` / Te…
kspshnik Nov 27, 2024
eca4093
Merge branch 'feature/chats-business-entity' of github.com:ya-pomogau…
kspshnik Nov 27, 2024
7b551da
[Refactor] Allowed `null` for `chatId` in `MessageInterface` as sign …
kspshnik Nov 28, 2024
665757f
[Interim/ReviewRequest] Created Chat Entity
kspshnik Dec 12, 2024
e04a429
[Interim/ReviewRequest] Created Chat Entity
kspshnik Dec 12, 2024
5e531ad
Merge remote-tracking branch 'origin/feature/chats-business-entity' i…
kspshnik Dec 12, 2024
3f88f72
Merge branch 'development' into feature/chats-business-entity
kspshnik Dec 13, 2024
5febb88
[Fix] Fixed typing to avoid circular deps
kspshnik Dec 14, 2024
2354ac0
[New] Chat Entity interface
kspshnik Dec 14, 2024
c27de25
[Fix] Fix typings & direct model injection
kspshnik Dec 17, 2024
da60ff8
[Fix] No generics in entity + fixes
kspshnik Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { PolicyModule } from './core/policy/policy.module';
import { SystemApiModule } from './api/system-api/system-api.module';
import { LoggerMiddleware } from './common/middleware';
import { WebsocketApiModule } from './api/websocket-api/websocket-api.module';
import { ChatEntityModule } from './entities/chats/chat.entity.module';

@Module({
imports: [
Expand Down Expand Up @@ -55,6 +56,7 @@ import { WebsocketApiModule } from './api/websocket-api/websocket-api.module';
PolicyModule,
SystemApiModule,
WebsocketApiModule,
ChatEntityModule,
],
providers: [
{
Expand Down
80 changes: 62 additions & 18 deletions src/common/types/chats.types.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
/* eslint-disable import/no-cycle */
import { type ObjectId } from 'mongoose';
import {
AdminInterface,
AnyUserInterface,
RecipientInterface,
VolunteerInterface,
} from './user.types';
import { MongooseIdAndTimestampsInterface } from './system.types';

export interface MessageInterface {
_id: ObjectId | string;
import { ChatType, ChatTypes, MongooseIdAndTimestampsInterface } from './system.types';
// eslint-disable-next-line import/no-cycle
import { Chat } from '../../datalake/chats/schemas/chat.schema';
import { SystemChat } from '../../datalake/chats/schemas/system-chat.schema';
import { TaskChat } from '../../datalake/chats/schemas/task-chat.schema';
import { ConflictChatWithVolunteer } from '../../datalake/chats/schemas/conflict-volunteer-chat.schema';
import { ConflictChatWithRecipient } from '../../datalake/chats/schemas/conflict-recipient-chat.schema';

export interface MessageModelInterface {
body: string;
attaches: string[];
createdAt: Date | string;
author: AnyUserInterface;
chatId: ObjectId | string;
chatId: ObjectId | string | null;
timestamp: Date;
}

export const ChatTypes = {
TASK_CHAT: 'TaskChat',
SYSTEM_CHAT: 'SystemChat',
CONFLICT_CHAT_WITH_VOLUNTEER: 'ConflictChatWithVolunteer',
CONFLICT_CHAT_WITH_RECIPIENT: 'ConflictChatWithRecipient',
} as const;
export interface MessageInterface extends MessageModelInterface, MongooseIdAndTimestampsInterface {}

export type ChatType = keyof typeof ChatTypes;
export interface VirginMessageInterface {
body: string;
author: AnyUserInterface;
chatId: ObjectId | string | null;
attaches?: string[];
}

export type TaskChatType = typeof ChatType.TASK_CHAT;
export type SystemChatType = typeof ChatType.SYSTEM_CHAT;
export type VolunteerConflictChatType = typeof ChatType.CONFLICT_CHAT_WITH_VOLUNTEER;
export type RecipientConflictChatType = typeof ChatType.CONFLICT_CHAT_WITH_RECIPIENT;
export type AnyConflictChatType = VolunteerConflictChatType | RecipientConflictChatType;

export interface ChatModelInterface {
type: ChatType;
type: ChatTypes;
isActive: boolean;
}

Expand Down Expand Up @@ -82,6 +94,19 @@ export interface ConflictChatWithRecipientInterface
ConflictChatWithRecipientModelInterface,
MongooseIdAndTimestampsInterface {}

export type AnyChatInterface =
| TaskChatInterface
| SystemChatInterface
| ConflictChatWithVolunteerInterface
| ConflictChatWithRecipientInterface;

export type AnyChat =
| Chat
| SystemChat
| TaskChat
| ConflictChatWithVolunteer
| ConflictChatWithRecipient;

export interface WatermarkInterface {
watermark: string;
unreads: number;
Expand Down Expand Up @@ -159,7 +184,26 @@ export type AnyUserChatsResponseDtoInterface =
| GetUserChatsResponseDtoInterface
| GetAdminChatsResponseDtoInterface;

export type CreateTaskChatDtoType = Pick<
TaskChatInterface,
'taskId' | 'type' | 'volunteer' | 'recipient'
>;
export type CreateChatEntityDtoBaseType<T> = T extends TaskChatType
? Pick<TaskChatInterface, 'taskId' | 'type' | 'volunteer' | 'recipient'>
: T extends SystemChatType
? Pick<SystemChatInterface, 'type' | 'user'>
: T extends VolunteerConflictChatType
? Pick<ConflictChatWithVolunteerInterface, 'type' | 'taskId' | 'admin' | 'volunteer'>
: T extends RecipientConflictChatType
? Pick<ConflictChatWithRecipientInterface, 'type' | 'taskId' | 'admin' | 'recipient'>
: never;

export type CreateTaskChatEntityDtoType = CreateChatEntityDtoBaseType<TaskChatType>;
export type CreateSystemChatEntityDtoType = CreateChatEntityDtoBaseType<SystemChatType>;
export type CreateConflictVolunteerChatEntityDtoType =
CreateChatEntityDtoBaseType<VolunteerConflictChatType>;
export type CreateConflictRecipientChatEntityDtoType =
CreateChatEntityDtoBaseType<RecipientConflictChatType>;
export type CreateChatEntityDtoTypes =
| CreateTaskChatEntityDtoType
| CreateSystemChatEntityDtoType
| CreateConflictVolunteerChatEntityDtoType
| CreateConflictRecipientChatEntityDtoType;

export type CreateChatDtoType<T extends CreateChatEntityDtoTypes> = Omit<T, '_id' | 'type'>;
31 changes: 31 additions & 0 deletions src/common/types/entities.interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ObjectId } from 'mongoose';
import {
AnyChatInterface,
CreateChatEntityDtoTypes,
MessageInterface,
VirginMessageInterface,
} from './chats.types';

export interface ChatEntityInterface {
readonly chatId: ObjectId | string;
readonly meta: AnyChatInterface;
readonly messages: Array<MessageInterface>;

create(dto: CreateChatEntityDtoTypes): Promise<ChatEntityInterface>;

toObject(): { metadata: AnyChatInterface; messages: Array<MessageInterface> };

setOpponentChat(opponentChatId: ObjectId | string): Promise<ChatEntityInterface>;

find(chatId: string): Promise<ChatEntityInterface>;

find(dto: Record<string, unknown>): Promise<ChatEntityInterface>;

find(...data): Promise<ChatEntityInterface>;

postMessage(dto: VirginMessageInterface): Promise<MessageInterface>;

close(): Promise<ChatEntityInterface>;

reopen(): Promise<ChatEntityInterface>;
}
19 changes: 15 additions & 4 deletions src/common/types/system.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ObjectId } from 'mongoose';

export type ServerConfiguration = {
port: number;
ws_port: number;
Expand Down Expand Up @@ -35,8 +37,17 @@ export type AppConfiguration = {
};

export interface MongooseIdAndTimestampsInterface {
_id: string;
id?: string;
createdAt: string;
updatedAt: string;
_id: string | ObjectId;
id?: string | ObjectId;
createdAt: string | Date;
updatedAt: string | Date;
}

export const ChatType = {
TASK_CHAT: 'TASK_CHAT',
SYSTEM_CHAT: 'SYSTEM_CHAT',
CONFLICT_CHAT_WITH_VOLUNTEER: 'CONFLICT_CHAT_WITH_VOLUNTEER',
CONFLICT_CHAT_WITH_RECIPIENT: 'CONFLICT_CHAT_WITH_RECIPIENT',
} as const;
// export const ChatTypes = ChatType;
export type ChatTypes = keyof typeof ChatType;
7 changes: 7 additions & 0 deletions src/common/utils/is-conflict-recipient-chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ConflictChatWithVolunteer } from '../../datalake/chats/schemas/conflict-volunteer-chat.schema';
import { ChatType } from '../types/system.types';
import { Chat } from '../../datalake/chats/schemas/chat.schema';

export function isConflictChatWithRecipient(chat: unknown): chat is ConflictChatWithVolunteer {
return chat instanceof Chat && chat.type === ChatType.CONFLICT_CHAT_WITH_RECIPIENT;
}
7 changes: 7 additions & 0 deletions src/common/utils/is-conflict-volunteer-chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ConflictChatWithVolunteer } from '../../datalake/chats/schemas/conflict-volunteer-chat.schema';
import { ChatType } from '../types/system.types';
import { Chat } from '../../datalake/chats/schemas/chat.schema';

export function isConflictChatWithVolunteer(chat: unknown): chat is ConflictChatWithVolunteer {
return chat instanceof Chat && chat.type === ChatType.CONFLICT_CHAT_WITH_VOLUNTEER;
}
8 changes: 8 additions & 0 deletions src/common/utils/is-system-chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SystemChat } from '../../datalake/chats/schemas/system-chat.schema';
import { Chat } from '../../datalake/chats/schemas/chat.schema';
import { ChatType } from '../types/system.types';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function isSystemChat(chat: unknown): chat is SystemChat {
return chat instanceof Chat && chat.type === ChatType.SYSTEM_CHAT;
}
7 changes: 7 additions & 0 deletions src/common/utils/is-task-chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { TaskChat } from '../../datalake/chats/schemas/task-chat.schema';
import { ChatType } from '../types/system.types';
import { Chat } from '../../datalake/chats/schemas/chat.schema';

export function isTaskChat(chat: unknown): chat is TaskChat {
return chat instanceof Chat && chat.type === ChatType.TASK_CHAT;
}
8 changes: 5 additions & 3 deletions src/datalake/chats/schemas/chat.schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, ObjectId, SchemaTypes } from 'mongoose';
import { ChatModelInterface, ChatType, ChatTypes } from '../../../common/types/chats.types';
// eslint-disable-next-line import/no-cycle
import { ChatModelInterface } from '../../../common/types/chats.types';
import { ChatType, ChatTypes } from '../../../common/types/system.types';

@Schema({
timestamps: true,
Expand All @@ -21,9 +23,9 @@ export class Chat extends Document implements ChatModelInterface {
@Prop({
required: true,
type: SchemaTypes.String,
enum: Object.values(ChatTypes),
enum: Object.values(ChatType),
})
type: ChatType;
type: ChatTypes;

@Prop({
required: true,
Expand Down
3 changes: 2 additions & 1 deletion src/datalake/chats/schemas/system-chat.schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SchemaTypes } from 'mongoose';
import { Document, SchemaTypes } from 'mongoose';
import { Prop, Schema, SchemaFactory, raw } from '@nestjs/mongoose';
// eslint-disable-next-line import/no-cycle
import { SystemChatModelInterface } from '../../../common/types/chats.types';
import {
VolunteerInterface,
Expand Down
13 changes: 5 additions & 8 deletions src/datalake/messages/schemas/messages.schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Prop, raw, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, SchemaTypes } from 'mongoose';
import { type ObjectId } from 'mongoose';
import { MessageInterface } from '../../../common/types/chats.types';
import { MessageModelInterface } from '../../../common/types/chats.types';
import { AnyUserInterface } from '../../../common/types/user.types';
import { rawUserProfile } from '../../../common/constants/mongoose-fields-raw-definition';

Expand All @@ -12,10 +12,7 @@ import { rawUserProfile } from '../../../common/constants/mongoose-fields-raw-de
virtuals: true,
},
})
export class Message extends Document implements MessageInterface {
@Prop({ required: true, type: SchemaTypes.ObjectId })
_id: ObjectId;

export class Message extends Document implements MessageModelInterface {
@Prop({ required: true, type: SchemaTypes.String })
title: string;

Expand All @@ -25,14 +22,14 @@ export class Message extends Document implements MessageInterface {
@Prop({ required: false, default: [], type: [SchemaTypes.String] })
attaches: string[];

@Prop({ required: true, type: SchemaTypes.Date })
createdAt: Date;

@Prop({ required: true, type: raw(rawUserProfile) })
author: AnyUserInterface;

@Prop({ required: true, type: SchemaTypes.ObjectId })
chatId: ObjectId;

@Prop({ required: true, type: SchemaTypes.Date })
timestamp: Date;
}

export const MessagesSchema = SchemaFactory.createForClass(Message);
36 changes: 36 additions & 0 deletions src/entities/chats/chat.entity.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Module } from '@nestjs/common';
import { ModelDefinition, MongooseModule } from '@nestjs/mongoose';
import { ChatEntity } from './chat.entity';
import { Chat, ChatSchema } from '../../datalake/chats/schemas/chat.schema';
import { TaskChat, TaskChatSchema } from '../../datalake/chats/schemas/task-chat.schema';
import { SystemChat, SystemChatSchema } from '../../datalake/chats/schemas/system-chat.schema';
import {
ConflictChatWithVolunteer,
ConflictChatWithVolunteerSchema,
} from '../../datalake/chats/schemas/conflict-volunteer-chat.schema';
import {
ConflictChatWithRecipient,
ConflictChatWithRecipientSchema,
} from '../../datalake/chats/schemas/conflict-recipient-chat.schema';
import { Message, MessagesSchema } from '../../datalake/messages/schemas/messages.schema';

@Module({
imports: [
MongooseModule.forFeature([
{
name: Chat.name,
schema: ChatSchema,
discriminators: [
{ name: TaskChat.name, schema: TaskChatSchema },
{ name: SystemChat.name, schema: SystemChatSchema },
{ name: ConflictChatWithVolunteer.name, schema: ConflictChatWithVolunteerSchema },
{ name: ConflictChatWithRecipient.name, schema: ConflictChatWithRecipientSchema },
],
} as ModelDefinition,
{ name: Message.name, schema: MessagesSchema },
]),
],
providers: [ChatEntity],
exports: [ChatEntity],
})
export class ChatEntityModule {}
Loading