Skip to content

Commit dd3f0de

Browse files
committed
Merge branch 'main' of https://github.com/Dialogue-Bot/dialogue-bot into DIAL-12-Feat-Login-with-google
2 parents dd99a58 + ada26e7 commit dd3f0de

File tree

23 files changed

+708
-24
lines changed

23 files changed

+708
-24
lines changed

server/.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@
55
},
66
"editor.formatOnSave": true,
77
"editor.defaultFormatter": "esbenp.prettier-vscode",
8-
"editor.formatOnSaveMode": "file"
8+
"editor.formatOnSaveMode": "file",
9+
"[typescript]": {
10+
"editor.defaultFormatter": "vscode.typescript-language-features"
11+
}
912
}

server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"lodash": "^4.17.21",
5151
"mime": "^4.0.1",
5252
"mime-types": "^2.1.35",
53+
"moment": "^2.30.1",
5354
"morgan": "^1.10.0",
5455
"multer": "1.4.5-lts.1",
5556
"nodemailer": "^6.9.8",

server/src/constants/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ export const ENDPOINTS = {
2626
SINGLE: '/upload/single',
2727
MULTIPLE: '/upload/multiple',
2828
},
29+
CHANNEL: {
30+
INDEX: '/channel',
31+
DELETE: '/channel/delete',
32+
DELETES: '/channel/deletes',
33+
}
2934
};
3035

3136
export const LOCALE_KEY = 'lang';
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { LOCALE_KEY } from "@/constants";
2+
import { PagingDTO } from "@/dtos/paging.dto";
3+
import { LocaleService } from "@/i18n/ctx";
4+
import { ChannelService } from "@/services/channels.service";
5+
import { catchAsync } from "@/utils/catch-async";
6+
import { plainToClass } from "class-transformer";
7+
import { validateOrReject } from "class-validator";
8+
import { StatusCodes } from "http-status-codes";
9+
import Container from "typedi";
10+
11+
export class ChannelController {
12+
public channelService = Container.get(ChannelService);
13+
public localeService = Container.get<LocaleService>(LOCALE_KEY);
14+
15+
public createChannel = catchAsync(async (req, res) => {
16+
await this.channelService.create(req.body);
17+
res.status(StatusCodes.OK).json({
18+
message: this.localeService.i18n().CHANNEL.CREATE_SUCCESS(),
19+
});
20+
});
21+
22+
public updateChannel = catchAsync(async (req, res) => {
23+
await this.channelService.updateById(req.params.id, req.body);
24+
res.status(StatusCodes.OK).json({
25+
message: this.localeService.i18n().CHANNEL.UPDATE_SUCCESS(),
26+
});
27+
})
28+
29+
public deleteChannel = catchAsync(async (req, res) => {
30+
await this.channelService.deleteById(req.params.id);
31+
res.status(StatusCodes.OK).json({
32+
message: this.localeService.i18n().CHANNEL.DELETE_CHANNEL_SUCCESS(),
33+
});
34+
})
35+
36+
public deleteMultipleChannel = catchAsync(async (req, res) => {
37+
await this.channelService.deleteByIds(req.body.id);
38+
res.status(StatusCodes.OK).json({
39+
message: this.localeService.i18n().CHANNEL.DELETE_MULTIPLE_CHANNELS_SUCCESS(),
40+
});
41+
})
42+
43+
public getChannelsPaging = catchAsync(async (req, res) => {
44+
const paging = plainToClass(PagingDTO, req.query);
45+
await validateOrReject(paging);
46+
47+
const result = await this.channelService.getChannelsPaging(paging);
48+
res.status(StatusCodes.OK).json({ result });
49+
})
50+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ALTER TABLE "channel_types" ALTER COLUMN "id" SET DATA TYPE varchar(36);--> statement-breakpoint
2+
ALTER TABLE "channels" ALTER COLUMN "id" SET DATA TYPE varchar(36);--> statement-breakpoint
3+
ALTER TABLE "channels" ALTER COLUMN "credentials" SET DATA TYPE text;--> statement-breakpoint
4+
ALTER TABLE "channels" ALTER COLUMN "active" DROP DEFAULT;--> statement-breakpoint
5+
ALTER TABLE "channels" ALTER COLUMN "channel_type_id" SET DATA TYPE text;--> statement-breakpoint
6+
ALTER TABLE "channel_types" ADD COLUMN "deleted" boolean DEFAULT false;--> statement-breakpoint
7+
ALTER TABLE "channels" ADD COLUMN "deleted" boolean DEFAULT false;--> statement-breakpoint
8+
ALTER TABLE "channels" ADD COLUMN "updated_at" timestamp;--> statement-breakpoint
9+
ALTER TABLE "channels" DROP COLUMN IF EXISTS "update_at";
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
{
2+
"id": "60dd3aa6-20af-49e5-abd3-af199aaa5310",
3+
"prevId": "7c12eaec-b7a1-4ca4-9255-28a150e82397",
4+
"version": "5",
5+
"dialect": "pg",
6+
"tables": {
7+
"channel_types": {
8+
"name": "channel_types",
9+
"schema": "",
10+
"columns": {
11+
"id": {
12+
"name": "id",
13+
"type": "varchar(36)",
14+
"primaryKey": true,
15+
"notNull": true
16+
},
17+
"name": {
18+
"name": "name",
19+
"type": "text",
20+
"primaryKey": false,
21+
"notNull": true
22+
},
23+
"description": {
24+
"name": "description",
25+
"type": "text",
26+
"primaryKey": false,
27+
"notNull": true
28+
},
29+
"deleted": {
30+
"name": "deleted",
31+
"type": "boolean",
32+
"primaryKey": false,
33+
"notNull": false,
34+
"default": false
35+
}
36+
},
37+
"indexes": {},
38+
"foreignKeys": {},
39+
"compositePrimaryKeys": {},
40+
"uniqueConstraints": {
41+
"channel_types_name_unique": {
42+
"name": "channel_types_name_unique",
43+
"nullsNotDistinct": false,
44+
"columns": [
45+
"name"
46+
]
47+
},
48+
"channel_types_description_unique": {
49+
"name": "channel_types_description_unique",
50+
"nullsNotDistinct": false,
51+
"columns": [
52+
"description"
53+
]
54+
}
55+
}
56+
},
57+
"channels": {
58+
"name": "channels",
59+
"schema": "",
60+
"columns": {
61+
"id": {
62+
"name": "id",
63+
"type": "varchar(36)",
64+
"primaryKey": true,
65+
"notNull": true
66+
},
67+
"contact_id": {
68+
"name": "contact_id",
69+
"type": "text",
70+
"primaryKey": false,
71+
"notNull": true
72+
},
73+
"contact_name": {
74+
"name": "contact_name",
75+
"type": "text",
76+
"primaryKey": false,
77+
"notNull": true
78+
},
79+
"credentials": {
80+
"name": "credentials",
81+
"type": "text",
82+
"primaryKey": false,
83+
"notNull": false
84+
},
85+
"active": {
86+
"name": "active",
87+
"type": "boolean",
88+
"primaryKey": false,
89+
"notNull": false
90+
},
91+
"deleted": {
92+
"name": "deleted",
93+
"type": "boolean",
94+
"primaryKey": false,
95+
"notNull": false,
96+
"default": false
97+
},
98+
"channel_type_id": {
99+
"name": "channel_type_id",
100+
"type": "text",
101+
"primaryKey": false,
102+
"notNull": true
103+
},
104+
"created_at": {
105+
"name": "created_at",
106+
"type": "timestamp",
107+
"primaryKey": false,
108+
"notNull": false,
109+
"default": "now()"
110+
},
111+
"updated_at": {
112+
"name": "updated_at",
113+
"type": "timestamp",
114+
"primaryKey": false,
115+
"notNull": false
116+
}
117+
},
118+
"indexes": {},
119+
"foreignKeys": {},
120+
"compositePrimaryKeys": {},
121+
"uniqueConstraints": {
122+
"channels_contact_id_unique": {
123+
"name": "channels_contact_id_unique",
124+
"nullsNotDistinct": false,
125+
"columns": [
126+
"contact_id"
127+
]
128+
}
129+
}
130+
},
131+
"users": {
132+
"name": "users",
133+
"schema": "",
134+
"columns": {
135+
"id": {
136+
"name": "id",
137+
"type": "varchar(36)",
138+
"primaryKey": true,
139+
"notNull": true
140+
},
141+
"email": {
142+
"name": "email",
143+
"type": "text",
144+
"primaryKey": false,
145+
"notNull": true
146+
},
147+
"password": {
148+
"name": "password",
149+
"type": "text",
150+
"primaryKey": false,
151+
"notNull": false
152+
},
153+
"name": {
154+
"name": "name",
155+
"type": "text",
156+
"primaryKey": false,
157+
"notNull": true
158+
},
159+
"avatar": {
160+
"name": "avatar",
161+
"type": "text",
162+
"primaryKey": false,
163+
"notNull": false
164+
},
165+
"role": {
166+
"name": "role",
167+
"type": "roles[]",
168+
"primaryKey": false,
169+
"notNull": true
170+
},
171+
"provider": {
172+
"name": "provider",
173+
"type": "text",
174+
"primaryKey": false,
175+
"notNull": true,
176+
"default": "'local'"
177+
}
178+
},
179+
"indexes": {
180+
"email_idx": {
181+
"name": "email_idx",
182+
"columns": [
183+
"email"
184+
],
185+
"isUnique": true
186+
}
187+
},
188+
"foreignKeys": {},
189+
"compositePrimaryKeys": {},
190+
"uniqueConstraints": {
191+
"users_email_unique": {
192+
"name": "users_email_unique",
193+
"nullsNotDistinct": false,
194+
"columns": [
195+
"email"
196+
]
197+
}
198+
}
199+
}
200+
},
201+
"enums": {
202+
"roles": {
203+
"name": "roles",
204+
"values": {
205+
"ADMIN": "ADMIN",
206+
"USER": "USER"
207+
}
208+
}
209+
},
210+
"schemas": {},
211+
"_meta": {
212+
"columns": {},
213+
"schemas": {},
214+
"tables": {}
215+
}
216+
}

server/src/database/schema.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ import { createId } from '@paralleldrive/cuid2';
22
import { relations } from 'drizzle-orm';
33
import {
44
boolean,
5-
integer,
6-
json,
75
pgEnum,
86
pgTable,
9-
serial,
107
text,
118
timestamp,
129
uniqueIndex,
@@ -39,24 +36,31 @@ export const users = pgTable(
3936
})
4037
);
4138

42-
export const channelTypes = pgTable(
43-
'channel_types', // cho nay minh theo conversation channel_types nha
44-
{
45-
id: serial('id').primaryKey(),
46-
name: text('name').unique().notNull(),
47-
description: text('description').unique().notNull(),
48-
}
49-
);
39+
export const channelTypes = pgTable('channel_types', {
40+
id: varchar('id', {
41+
length: MAX_ID_LENGTH,
42+
})
43+
.primaryKey()
44+
.$defaultFn(() => createId()),
45+
name: text('name').unique().notNull(),
46+
description: text('description').unique().notNull(),
47+
deleted: boolean('deleted').default(false),
48+
});
5049

5150
export const channels = pgTable('channels', {
52-
id: serial('id').primaryKey(),
51+
id: varchar('id', {
52+
length: MAX_ID_LENGTH,
53+
})
54+
.primaryKey()
55+
.$defaultFn(() => createId()),
5356
contactId: text('contact_id').unique().notNull(),
5457
contactName: text('contact_name').notNull(),
55-
credentials: json('credentials'),
56-
active: boolean('active').default(true),
57-
channelTypeId: integer('channel_type_id').notNull(),
58+
credentials: text('credentials'),
59+
active: boolean('active'),
60+
deleted: boolean('deleted').default(false),
61+
channelTypeId: text('channel_type_id').notNull(),
5862
createdAt: timestamp('created_at').defaultNow(),
59-
updatedAt: timestamp('update_at').defaultNow(),
63+
updatedAt: timestamp('updated_at'),
6064
});
6165

6266
export const channelTypesRelations = relations(channelTypes, ({ many }) => ({

server/src/database/seed.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import * as bcrypt from 'bcrypt';
12
import { db } from "./db";
2-
import { channelTypes } from "./schema";
3+
import { channelTypes, users } from "./schema";
34

45
async function seedChannelTypes() {
56
try {
@@ -15,4 +16,14 @@ async function seedChannelTypes() {
1516
}
1617
}
1718

18-
seedChannelTypes();
19+
async function seedDefaultAccount() {
20+
try {
21+
const hashedPassword = await bcrypt.hash("Hello@123", 10);
22+
await db.insert(users).values({email: "[email protected]", password: hashedPassword, name: "admin",});
23+
} catch (error) {
24+
console.error(`Can't create default account`);
25+
}
26+
}
27+
28+
seedChannelTypes();
29+
seedDefaultAccount();

0 commit comments

Comments
 (0)