mirror of
https://github.com/MrSedan/neuro-reply-website.git
synced 2026-01-14 20:49:42 +03:00
Merge branch 'dev' of https://github.com/MrSedan/neuro-reply-website into typeorm
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -4,4 +4,8 @@
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
node_modules
|
||||
|
||||
# Env files
|
||||
**/.env
|
||||
**/.env.*
|
||||
!**/.env.example
|
||||
@@ -4,6 +4,5 @@
|
||||
"semi": true,
|
||||
"tabWidth": 4,
|
||||
"printWidth": 150,
|
||||
"bracketSpacing": true,
|
||||
"endOfLine": "auto"
|
||||
"bracketSpacing": true
|
||||
}
|
||||
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -10,5 +10,5 @@
|
||||
"**/node_modules": true
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
}
|
||||
7
backend/.env.example
Normal file
7
backend/.env.example
Normal file
@@ -0,0 +1,7 @@
|
||||
DATABASE_PASSWORD=postgres
|
||||
DATABASE_NAME=bot_db
|
||||
DATABASE_USER=postgres
|
||||
DATABASE_HOST=localhost
|
||||
DATABASE_PORT=5432
|
||||
|
||||
SERVER_PORT=3000
|
||||
20
backend/config/index.ts
Normal file
20
backend/config/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { config as configInit } from 'dotenv';
|
||||
|
||||
configInit();
|
||||
|
||||
export const config = {
|
||||
database: {
|
||||
type: 'postgres',
|
||||
host: process.env.DATABASE_HOST || 'localhost',
|
||||
port: +process.env.DATABASE_PORT || 5432,
|
||||
username: process.env.DATABASE_USERNAME || 'postgres',
|
||||
password: process.env.DATABASE_PASSWORD || '',
|
||||
database: process.env.DATABASE_DB || 'bot_db',
|
||||
synchronize: true,
|
||||
logging: false,
|
||||
autoLoadEntities: true,
|
||||
},
|
||||
server: {
|
||||
port: +process.env.SERVER_PORT || 8080,
|
||||
},
|
||||
};
|
||||
14
backend/libs/database/user.entity.ts
Normal file
14
backend/libs/database/user.entity.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
constructor(props?: Partial<User>) {
|
||||
Object.assign(this, props);
|
||||
}
|
||||
|
||||
@PrimaryColumn()
|
||||
public id!: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
public user_name: string;
|
||||
}
|
||||
8
backend/libs/libs.module.ts
Normal file
8
backend/libs/libs.module.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { User } from './database/user.entity';
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([User])],
|
||||
exports: [TypeOrmModule],
|
||||
})
|
||||
export class LibsModule {}
|
||||
@@ -23,7 +23,9 @@
|
||||
"@nestjs/common": "^10.0.0",
|
||||
"@nestjs/core": "^10.0.0",
|
||||
"@nestjs/platform-express": "^10.0.0",
|
||||
"nestjs": "^0.0.1",
|
||||
"@nestjs/swagger": "^7.1.16",
|
||||
"@nestjs/typeorm": "^10.0.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"pg": "^8.11.3",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.8.1",
|
||||
|
||||
80
backend/pnpm-lock.yaml
generated
80
backend/pnpm-lock.yaml
generated
@@ -14,9 +14,15 @@ dependencies:
|
||||
'@nestjs/platform-express':
|
||||
specifier: ^10.0.0
|
||||
version: 10.2.8(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)
|
||||
nestjs:
|
||||
specifier: ^0.0.1
|
||||
version: 0.0.1
|
||||
'@nestjs/swagger':
|
||||
specifier: ^7.1.16
|
||||
version: 7.1.16(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)(reflect-metadata@0.1.13)
|
||||
'@nestjs/typeorm':
|
||||
specifier: ^10.0.1
|
||||
version: 10.0.1(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)(reflect-metadata@0.1.13)(rxjs@7.8.1)(typeorm@0.3.17)
|
||||
dotenv:
|
||||
specifier: ^16.3.1
|
||||
version: 16.3.1
|
||||
pg:
|
||||
specifier: ^8.11.3
|
||||
version: 8.11.3
|
||||
@@ -941,6 +947,23 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
/@nestjs/mapped-types@2.0.3(@nestjs/common@10.2.8)(reflect-metadata@0.1.13):
|
||||
resolution: {integrity: sha512-40Zdqg98lqoF0+7ThWIZFStxgzisK6GG22+1ABO4kZiGF/Tu2FE+DYLw+Q9D94vcFWizJ+MSjNN4ns9r6hIGxw==}
|
||||
peerDependencies:
|
||||
'@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0
|
||||
class-transformer: ^0.4.0 || ^0.5.0
|
||||
class-validator: ^0.13.0 || ^0.14.0
|
||||
reflect-metadata: ^0.1.12
|
||||
peerDependenciesMeta:
|
||||
class-transformer:
|
||||
optional: true
|
||||
class-validator:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@nestjs/common': 10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
||||
reflect-metadata: 0.1.13
|
||||
dev: false
|
||||
|
||||
/@nestjs/platform-express@10.2.8(@nestjs/common@10.2.8)(@nestjs/core@10.2.8):
|
||||
resolution: {integrity: sha512-WoSSVtwIRc5AdGMHWVzWZK4JZLT0f4o2xW8P9gQvcX+omL8W1kXCfY8GQYXNBG84XmBNYH8r0FtC8oMe/lH5NQ==}
|
||||
peerDependencies:
|
||||
@@ -972,6 +995,33 @@ packages:
|
||||
- chokidar
|
||||
dev: true
|
||||
|
||||
/@nestjs/swagger@7.1.16(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)(reflect-metadata@0.1.13):
|
||||
resolution: {integrity: sha512-f9KBk/BX9MUKPTj7tQNYJ124wV/jP5W2lwWHLGwe/4qQXixuDOo39zP55HIJ44LE7S04B7BOeUOo9GBJD/vRcw==}
|
||||
peerDependencies:
|
||||
'@fastify/static': ^6.0.0
|
||||
'@nestjs/common': ^9.0.0 || ^10.0.0
|
||||
'@nestjs/core': ^9.0.0 || ^10.0.0
|
||||
class-transformer: '*'
|
||||
class-validator: '*'
|
||||
reflect-metadata: ^0.1.12
|
||||
peerDependenciesMeta:
|
||||
'@fastify/static':
|
||||
optional: true
|
||||
class-transformer:
|
||||
optional: true
|
||||
class-validator:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@nestjs/common': 10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
||||
'@nestjs/core': 10.2.8(@nestjs/common@10.2.8)(@nestjs/platform-express@10.2.8)(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
||||
'@nestjs/mapped-types': 2.0.3(@nestjs/common@10.2.8)(reflect-metadata@0.1.13)
|
||||
js-yaml: 4.1.0
|
||||
lodash: 4.17.21
|
||||
path-to-regexp: 3.2.0
|
||||
reflect-metadata: 0.1.13
|
||||
swagger-ui-dist: 5.9.1
|
||||
dev: false
|
||||
|
||||
/@nestjs/testing@10.2.8(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)(@nestjs/platform-express@10.2.8):
|
||||
resolution: {integrity: sha512-9Kj5IQhM67/nj/MT6Wi2OmWr5YQnCMptwKVFrX1TDaikpY12196v7frk0jVjdT7wms7rV07GZle9I2z0aSjqtQ==}
|
||||
peerDependencies:
|
||||
@@ -991,6 +1041,23 @@ packages:
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/@nestjs/typeorm@10.0.1(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)(reflect-metadata@0.1.13)(rxjs@7.8.1)(typeorm@0.3.17):
|
||||
resolution: {integrity: sha512-YVFYL7D25VAVp5/G+KLXIgsRfYomA+VaFZBpm2rtwrrBOmkXNrxr7kuI2bBBO/Xy4kKBDe6wbvIVVFeEA7/ngA==}
|
||||
peerDependencies:
|
||||
'@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0
|
||||
'@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0
|
||||
reflect-metadata: ^0.1.13
|
||||
rxjs: ^7.2.0
|
||||
typeorm: ^0.3.0
|
||||
dependencies:
|
||||
'@nestjs/common': 10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
||||
'@nestjs/core': 10.2.8(@nestjs/common@10.2.8)(@nestjs/platform-express@10.2.8)(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
||||
reflect-metadata: 0.1.13
|
||||
rxjs: 7.8.1
|
||||
typeorm: 0.3.17(pg@8.11.3)(ts-node@10.9.1)
|
||||
uuid: 9.0.1
|
||||
dev: false
|
||||
|
||||
/@nodelib/fs.scandir@2.1.5:
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -1653,7 +1720,6 @@ packages:
|
||||
|
||||
/argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
|
||||
/array-flatten@1.1.1:
|
||||
resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
|
||||
@@ -3764,7 +3830,6 @@ packages:
|
||||
hasBin: true
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
dev: true
|
||||
|
||||
/jsesc@2.5.2:
|
||||
resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
|
||||
@@ -3867,7 +3932,6 @@ packages:
|
||||
|
||||
/lodash@4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
dev: true
|
||||
|
||||
/log-symbols@4.1.0:
|
||||
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
|
||||
@@ -5006,6 +5070,10 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/swagger-ui-dist@5.9.1:
|
||||
resolution: {integrity: sha512-5zAx+hUwJb9T3EAntc7TqYkV716CMqG6sZpNlAAMOMWkNXRYxGkN8ADIvD55dQZ10LxN90ZM/TQmN7y1gpICnw==}
|
||||
dev: false
|
||||
|
||||
/symbol-observable@4.0.0:
|
||||
resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
|
||||
describe('AppController', () => {
|
||||
let appController: AppController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const app: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
}).compile();
|
||||
|
||||
appController = app.get<AppController>(AppController);
|
||||
});
|
||||
|
||||
describe('root', () => {
|
||||
it('should return "Hello World!"', () => {
|
||||
expect(appController.getHello()).toBe('Hello World!');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { AppService } from './app.service';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService) {}
|
||||
|
||||
@Get()
|
||||
getHello(): string {
|
||||
return this.appService.getHello();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
|
||||
import { config } from 'config';
|
||||
import { LibsModule } from 'libs/libs.module';
|
||||
import { AppInitService } from './modules/initialization/app.init.service';
|
||||
import { UserModule } from './modules/user/user.module';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
imports: [LibsModule, UserModule, TypeOrmModule.forRoot(<TypeOrmModuleOptions>config.database)],
|
||||
controllers: [],
|
||||
providers: [AppInitService],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
getHello(): string {
|
||||
return 'Hello World!';
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,14 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { config } from 'config';
|
||||
import { AppModule } from './app.module';
|
||||
import { swagger } from './swagger';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
await app.listen(3000);
|
||||
const app = await NestFactory.create(AppModule, {
|
||||
logger: ['log', 'debug', 'error', 'warn', 'verbose'],
|
||||
});
|
||||
swagger(app);
|
||||
await app.listen(config.server.port, () => Logger.log(`Server started on port ${config.server.port}`));
|
||||
}
|
||||
bootstrap();
|
||||
|
||||
11
backend/src/modules/initialization/app.init.service.ts
Normal file
11
backend/src/modules/initialization/app.init.service.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { User } from 'libs/database/user.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class AppInitService implements OnModuleInit {
|
||||
constructor(@InjectRepository(User) private userRepository: Repository<User>) {}
|
||||
|
||||
async onModuleInit() {}
|
||||
}
|
||||
18
backend/src/modules/user/user.controller.ts
Normal file
18
backend/src/modules/user/user.controller.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Body, Controller, Post } from '@nestjs/common';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { IGetUser } from './user.dto';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
@ApiTags('User')
|
||||
@Controller('user')
|
||||
export class UserController {
|
||||
constructor(private adminService: UserService) {}
|
||||
|
||||
@ApiOperation({
|
||||
description: 'Create or get user from db',
|
||||
})
|
||||
@Post('get')
|
||||
async getUser(@Body() data: IGetUser) {
|
||||
return await this.adminService.getUser(data);
|
||||
}
|
||||
}
|
||||
6
backend/src/modules/user/user.dto.ts
Normal file
6
backend/src/modules/user/user.dto.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class IGetUser {
|
||||
@ApiProperty({ description: 'telegram id', example: '123456' }) readonly id: string;
|
||||
@ApiProperty({ description: 'telegram username', example: 'durov' }) readonly username?: string;
|
||||
}
|
||||
11
backend/src/modules/user/user.module.ts
Normal file
11
backend/src/modules/user/user.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { LibsModule } from 'libs/libs.module';
|
||||
import { UserController } from './user.controller';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
@Module({
|
||||
imports: [LibsModule],
|
||||
controllers: [UserController],
|
||||
providers: [UserService],
|
||||
})
|
||||
export class UserModule {}
|
||||
27
backend/src/modules/user/user.service.ts
Normal file
27
backend/src/modules/user/user.service.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { User } from 'libs/database/user.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
import { IGetUser } from './user.dto';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
private readonly logger: Logger = new Logger(UserService.name);
|
||||
constructor(@InjectRepository(User) private userRepository: Repository<User>) {}
|
||||
|
||||
async getUser(data: IGetUser) {
|
||||
try {
|
||||
this.logger.debug(`[admin.getUser] data: ${JSON.stringify(data)}`);
|
||||
let user = await this.userRepository.findOne({
|
||||
where: { id: data.id },
|
||||
});
|
||||
if (!user) {
|
||||
user = await this.userRepository.save({ id: data.id, user_name: data.username });
|
||||
this.logger.log(`User ${data.id} created`);
|
||||
}
|
||||
return user;
|
||||
} catch (error) {
|
||||
this.logger.log(`[getUser] ${JSON.stringify({ error })}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
9
backend/src/swagger.ts
Normal file
9
backend/src/swagger.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||
|
||||
export function swagger(app: INestApplication): INestApplication {
|
||||
const config = new DocumentBuilder().setTitle('Neuro website').setDescription('Some description').setVersion('0.1').build();
|
||||
const document = SwaggerModule.createDocument(app, config);
|
||||
SwaggerModule.setup('api', app, document);
|
||||
return app;
|
||||
}
|
||||
@@ -18,4 +18,4 @@
|
||||
"forceConsistentCasingInFileNames": false,
|
||||
"noFallthroughCasesInSwitch": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user