plus-tdd / animalNest

TDD, CICD / AutoScaling, 통합 모니터링, 장애대응
1 stars 2 forks source link

2023.06.29 live code feedback #9

Open hubtwork opened 1 year ago

hubtwork commented 1 year ago

// Counseling 안에 들어가있어야할듯..
export enum CounselingStatus {
  Reserved = "Reserved", // 예약됨 ( 진료 전 )
  Complete = "Complete", // 진료됨 ( 진료 후 )
}

@Column({ type: "enum", name: "status", enum: Status })
status: Status

@Entity({
  name: 'Counseling',
  schema: 'animalnest',
})
export class CounselingEntity {
  @PrimaryGeneratedColumn({ type: 'int', name: 'id' })
  id: number;

  @Column('int', { name: 'doctor_id' })
  doctorId: number;

  @Column('int', { name: 'user_id' })
  userId: number;

  @Column('int', { name: 'pet_id' })
  petId: number;

  @Column('datetime', { name: 'counseling_date_time' })
  counselingDateTime: Date;   // 예약일이자 진료일

  @Column({ type: 'enum', name: 'counseling_status', enum: CounselingStatus })
  counselingStatus: CounselingStatus;

  @Column('text', { name: 'content', nullable: true })
  content: string | null;

  @Column('int', { name: 'expense' })
  expense: number;
}

유저가 예약을 한다. => Counseling 을 만듬

Counseling = {
  id
  의사,
  대상자,
  대상자의 애완동물,
  예약날짜 ( 진료일 ), 
  비용,
  현재 진행상태 = Reserved, 
  진료기록 = null,
}

진료를 했다. ( service ) => id 로 Counseling 찾아서 content 채우고 + 진행상태 바꿔줌.
async recordCounselingInfo(id: number, content: string): Counseling {
  const counseling: CounselingEntity = await this.counselingDB.find({ where: { id: id }})
  // 해당 id 의 진료가 없다면, 기록할 수 없으므로 에러다
  if (counseling === undefined) throw new Error()
  // 있다면, 진료기록을 엎어준다.
  counseling.content = content
  counseling.counselingStatus = CounselingStatus.Complete

  await this.counselingDB.update(counseling)

  return counseling.toDomain()
}

모든 Date 는 직접 Date 로 변환하기 전에 사용자로부터는 "yyyy-mm-dd" 스트링으로만 받아서
우리가 new Date(dateString) 해서 사용한다.
예약가능한 시간이 있는지 확인한다. ( 날짜로만 할거다 ) => 모든 Date 객체는 날짜 하위 단위 ( 시간 , ... ) = 0

// 해당 의사의 start 날짜 ~ end 날짜까지 중에 가능한 날짜를 반환해준다.
async checkPossibleReservationDates(doctor_id: number, startDate: Date, endDate: Date): Promise<Date[]> {
  // 예약이 이미 있는 날짜 ( 시작 ~ 종료 )
  const reserved: CounselingEntity[] = await this.counselingDB.find({
    where: {
      doctor_id: doctor_id,
      date: Between(startDate, endDate),
    }
  })

  const reservedDate: Date[] = reserved.map(it => it.counselingDateTime)
  const reservedSet: Set<Date> = new Set(reservedDate)

  // startDate ~ endDate 까지 날짜 하나씩 돌면서 
  // reserved 에 있는지를 확인하면 됨.
  const possibles: Date[] = []
  let current = startDate
  while(current <= endDate) {
    if (!reserved.has(start)) possibles.push(current) // 예약일에 없다면 추가
    current.setDate(current.getDate() + 1)  // 날짜 하나씩 증가시켜줌
  }
  return possibles
}

// 내 예약 목록을 보고싶다.
async getMyReservations(userId: number): Promise<Counseling[]> {
  // 예약이 이미 있는 날짜 ( 시작 ~ 종료 )
  const reserved: CounselingEntity[] = await this.counselingDB.find({
    where: {
      userId: userId,
      counselingStatus: CounselingStatus.Reserved,
    }
  })

  return reserved.map(it => toDomain(it) )
}

entity -> domain

export function toDomain(entity: CounselingEntity): Counseling {
  return {
    name: name ~
    id : ~
  }: Counseling
}
hubtwork commented 1 year ago

CounselingEntity 하나로 예약정보 / 진료정보를 구분해서 사용할 수 있도록 모델을 병합하면 어떻게 사용할 수 있을까 ? 에 대한 proposal 입니다.