This commit is contained in:
2025-12-09 17:02:27 +09:00
parent 26f8e1dab2
commit 83127da569
275 changed files with 139682 additions and 1 deletions

View 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';
}

View 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();
});
});

View 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 - 특정 사용자 조회 (관리자용)
}

View 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 {}

View 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();
});
});

View 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' },
// });
// }
}