INIT
This commit is contained in:
72
backend/src/user/entities/user.entity.ts
Normal file
72
backend/src/user/entities/user.entity.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { BaseModel } from 'src/common/entities/base.entity';
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
/**
|
||||
* 사용자/관리자 정보 (tb_user)
|
||||
*/
|
||||
@Entity({ name: 'tb_user' })
|
||||
export class UserModel extends BaseModel {
|
||||
@PrimaryGeneratedColumn({
|
||||
name: 'pk_user_no',
|
||||
type: 'int',
|
||||
comment: '내부 PK (자동증가)',
|
||||
})
|
||||
pkUserNo: number;
|
||||
|
||||
@Column({
|
||||
name: 'user_id',
|
||||
type: 'varchar',
|
||||
length: 100,
|
||||
nullable: false,
|
||||
unique: true,
|
||||
comment: '로그인 ID',
|
||||
})
|
||||
userId: string;
|
||||
|
||||
@Column({
|
||||
name: 'user_pw',
|
||||
type: 'varchar',
|
||||
length: 200,
|
||||
nullable: false,
|
||||
comment: '비밀번호 (암호화)',
|
||||
})
|
||||
userPw: string;
|
||||
|
||||
@Column({
|
||||
name: 'user_name',
|
||||
type: 'varchar',
|
||||
length: 100,
|
||||
nullable: false,
|
||||
comment: '이름',
|
||||
})
|
||||
userName: string;
|
||||
|
||||
@Column({
|
||||
name: 'user_phone',
|
||||
type: 'varchar',
|
||||
length: 20,
|
||||
nullable: true,
|
||||
comment: '핸드폰번호',
|
||||
})
|
||||
userPhone: string;
|
||||
|
||||
@Column({
|
||||
name: 'user_email',
|
||||
type: 'varchar',
|
||||
length: 100,
|
||||
nullable: true,
|
||||
unique: true,
|
||||
comment: '이메일 (인증용)',
|
||||
})
|
||||
userEmail: string;
|
||||
|
||||
@Column({
|
||||
name: 'user_role',
|
||||
type: 'varchar',
|
||||
length: 20,
|
||||
nullable: false,
|
||||
default: 'USER',
|
||||
comment: '권한 (USER: 일반, ADMIN: 관리자)',
|
||||
})
|
||||
userRole: 'USER' | 'ADMIN';
|
||||
}
|
||||
20
backend/src/user/user.controller.spec.ts
Normal file
20
backend/src/user/user.controller.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UserController } from './user.controller';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
describe('UserController', () => {
|
||||
let controller: UserController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [UserController],
|
||||
providers: [UserService],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<UserController>(UserController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
23
backend/src/user/user.controller.ts
Normal file
23
backend/src/user/user.controller.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Controller } from '@nestjs/common';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
/**
|
||||
* 사용자 정보 관리 컨트롤러
|
||||
*
|
||||
* @description
|
||||
* 사용자 API
|
||||
* 인증 관련 API는 AuthController로 이동
|
||||
*
|
||||
* @export
|
||||
* @class UserController
|
||||
* @typedef {UserController}
|
||||
*/
|
||||
@Controller('users')
|
||||
export class UserController {
|
||||
constructor(private readonly usersService: UserService) {}
|
||||
|
||||
// TODO: 나중에 프로필 관련 엔드포인트 추가
|
||||
// - GET /users/profile - 내 프로필 조회
|
||||
// - PATCH /users/profile - 프로필 수정
|
||||
// - GET /users/:id - 특정 사용자 조회 (관리자용)
|
||||
}
|
||||
19
backend/src/user/user.module.ts
Normal file
19
backend/src/user/user.module.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { UserService } from './user.service';
|
||||
import { UserController } from './user.controller';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { UserModel } from './entities/user.entity';
|
||||
|
||||
/**
|
||||
* 사용자 모듈
|
||||
* 프로필 조회/수정 등 사용자 정보 관련 기능 제공
|
||||
*/
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([UserModel]),
|
||||
],
|
||||
controllers: [UserController],
|
||||
providers: [UserService],
|
||||
exports: [UserService],
|
||||
})
|
||||
export class UserModule {}
|
||||
18
backend/src/user/user.service.spec.ts
Normal file
18
backend/src/user/user.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
describe('UserService', () => {
|
||||
let service: UserService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UserService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<UserService>(UserService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
98
backend/src/user/user.service.ts
Normal file
98
backend/src/user/user.service.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { UserModel } from './entities/user.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
/**
|
||||
* 사용자 정보 서비스
|
||||
* 프로필 조회/수정 등 사용자 정보 관련 비즈니스 로직
|
||||
*
|
||||
* TODO: 나중에 프로필 기능 필요시 아래 주석 해제
|
||||
*/
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(
|
||||
@InjectRepository(UserModel)
|
||||
private readonly userRepository: Repository<UserModel>,
|
||||
) {}
|
||||
|
||||
// /**
|
||||
// * 사용자 ID로 조회
|
||||
// */
|
||||
// async findByUserId(userId: string): Promise<UserModel | null> {
|
||||
// return this.userRepository.findOne({
|
||||
// where: { userId, delDt: IsNull() },
|
||||
// });
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 사용자 번호로 조회
|
||||
// */
|
||||
// async findByUserNo(userNo: number): Promise<UserModel | null> {
|
||||
// return this.userRepository.findOne({
|
||||
// where: { pkUserNo: userNo, delDt: IsNull() },
|
||||
// });
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 내 프로필 조회
|
||||
// */
|
||||
// async getProfile(userNo: number): Promise<{
|
||||
// userNo: number;
|
||||
// userId: string;
|
||||
// userName: string;
|
||||
// userPhone: string;
|
||||
// userEmail: string;
|
||||
// userRole: string;
|
||||
// }> {
|
||||
// const user = await this.userRepository.findOne({
|
||||
// where: { pkUserNo: userNo, delDt: IsNull() },
|
||||
// });
|
||||
|
||||
// if (!user) {
|
||||
// throw new NotFoundException('사용자를 찾을 수 없습니다');
|
||||
// }
|
||||
|
||||
// return {
|
||||
// userNo: user.pkUserNo,
|
||||
// userId: user.userId,
|
||||
// userName: user.userName,
|
||||
// userPhone: user.userPhone,
|
||||
// userEmail: user.userEmail,
|
||||
// userRole: user.userRole,
|
||||
// };
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 프로필 수정
|
||||
// */
|
||||
// async updateProfile(
|
||||
// userNo: number,
|
||||
// data: { userName?: string; userPhone?: string },
|
||||
// ): Promise<{ message: string }> {
|
||||
// const user = await this.userRepository.findOne({
|
||||
// where: { pkUserNo: userNo, delDt: IsNull() },
|
||||
// });
|
||||
|
||||
// if (!user) {
|
||||
// throw new NotFoundException('사용자를 찾을 수 없습니다');
|
||||
// }
|
||||
|
||||
// if (data.userName) user.userName = data.userName;
|
||||
// if (data.userPhone) user.userPhone = data.userPhone;
|
||||
|
||||
// await this.userRepository.save(user);
|
||||
|
||||
// return { message: '프로필이 수정되었습니다' };
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 전체 사용자 목록 조회 (관리자용)
|
||||
// */
|
||||
// async findAll(): Promise<UserModel[]> {
|
||||
// return this.userRepository.find({
|
||||
// where: { delDt: IsNull() },
|
||||
// order: { regDt: 'DESC' },
|
||||
// });
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user