Skip to content

[FEAT] 기관 리팩토링 및 상담 및 예약 기능 구현 #19

@Uechann

Description

@Uechann

[FEAT] 기관 리팩토링 및 상담 및 예약 기능 구현

📋 이슈 개요

기관 관리자가 자신의 기관을 효율적으로 운영할 수 있도록 통합 관리 기능을 구현합니다.

🎯 핵심 구현 목표

✅ 반드시 구현해야 할 기능

  1. 기관 Auth 인증 연결 - 기관 관리자 회원가입 후 기관 등록 연결
  2. 기관 CRUD + 권한 - OWNER/MANAGER/STAFF 권한별 접근 제어
  3. 요양보호사 관리 - 기관 소속 요양보호사 등록 및 관리
  4. 상담 서비스 관리 - 기관이 제공하는 상담 서비스 등록
  5. 예약 관리 - 회원의 예약 요청 확인 및 상태 변경
  6. 기관 대시보드 - 예약/요양보호사/통계 한눈에 보기

📋 전체 API 엔드포인트 목록

Part 1: 기관 Auth & 기본 CRUD

Method Endpoint 설명 권한 상태
POST /api/v1/institutions/register 기관 등록 OWNER ❌ 구현 필요
GET /api/v1/institutions/my 내 기관 조회 OWNER, MANAGER, STAFF ❌ 구현 필요
PUT /api/v1/institutions/{institutionId} 기관 정보 수정 OWNER, MANAGER ❌ 구현 필요
PATCH /api/v1/institutions/{institutionId}/admission 입소 가능 여부 변경 OWNER, MANAGER ❌ 구현 필요
DELETE /api/v1/institutions/{institutionId} 기관 삭제 (Soft) OWNER ❌ 구현 필요
GET /api/v1/institutions 기관 목록 조회 (공개) 공개 ✅ 완료
GET /api/v1/institutions/{institutionId} 기관 상세 조회 (공개) 공개 ✅ 완료

Part 2: 요양보호사 관리

Method Endpoint 설명 권한 상태
POST /api/v1/institutions/{institutionId}/caregivers 요양보호사 등록 OWNER, MANAGER ❌ 구현 필요
GET /api/v1/institutions/{institutionId}/caregivers 요양보호사 목록 공개 ❌ 구현 필요
GET /api/v1/institutions/{institutionId}/caregivers/{caregiverId} 요양보호사 상세 공개 ❌ 구현 필요
PUT /api/v1/institutions/{institutionId}/caregivers/{caregiverId} 요양보호사 수정 OWNER, MANAGER ❌ 구현 필요
PATCH /api/v1/institutions/{institutionId}/caregivers/{caregiverId}/status 활성화 상태 변경 OWNER, MANAGER ❌ 구현 필요
DELETE /api/v1/institutions/{institutionId}/caregivers/{caregiverId} 요양보호사 삭제 OWNER ❌ 구현 필요

Part 3: 상담 서비스 관리

Method Endpoint 설명 권한 상태
POST /api/v1/institutions/{institutionId}/counsels 상담 서비스 등록 OWNER, MANAGER ❌ 구현 필요
GET /api/v1/institutions/{institutionId}/counsels 상담 서비스 목록 공개 ❌ 구현 필요
GET /api/v1/institutions/{institutionId}/counsels/{counselId} 상담 서비스 상세 공개 ❌ 구현 필요
PUT /api/v1/institutions/{institutionId}/counsels/{counselId} 상담 서비스 수정 OWNER, MANAGER ❌ 구현 필요
PATCH /api/v1/institutions/{institutionId}/counsels/{counselId}/status 제공 여부 변경 OWNER, MANAGER ❌ 구현 필요
DELETE /api/v1/institutions/{institutionId}/counsels/{counselId} 상담 서비스 삭제 OWNER ❌ 구현 필요

Part 4: 예약 관리 (기관 관리자)

Method Endpoint 설명 권한 상태
GET /api/v1/institutions/{institutionId}/reservations 내 기관 예약 목록 OWNER, MANAGER, STAFF ❌ 구현 필요
GET /api/v1/reservations/{reservationId} 예약 상세 조회 OWNER, MANAGER, STAFF ❌ 구현 필요
PATCH /api/v1/reservations/{reservationId}/status 예약 상태 변경 OWNER, MANAGER ❌ 구현 필요

Part 5: 대시보드

Method Endpoint 설명 권한 상태
GET /api/v1/institutions/{institutionId}/dashboard 대시보드 통계 OWNER, MANAGER ❌ 구현 필요

📊 통계

총 API 개수: 24개
✅ 완료: 2개 (기관 목록/상세 조회)
❌ 구현 필요: 22개

Part별 개수:
- Part 1 (기관 기본): 7개 (2개 완료, 5개 필요)
- Part 2 (요양보호사): 6개 (전체 필요)
- Part 3 (상담 서비스): 6개 (전체 필요)
- Part 4 (예약 관리): 3개 (전체 필요)
- Part 5 (대시보드): 1개 (필요)

✅ API 우선순위

1순위 (핵심 기능)

  1. POST /api/v1/institutions/register - 기관 등록
  2. GET /api/v1/institutions/my - 내 기관 조회
  3. PUT /api/v1/institutions/{institutionId} - 기관 수정
  4. POST /api/v1/institutions/{institutionId}/counsels - 상담 서비스 등록
  5. GET /api/v1/institutions/{institutionId}/counsels - 상담 서비스 목록

2순위 (관리 기능)

  1. POST /api/v1/institutions/{institutionId}/caregivers - 요양보호사 등록
  2. GET /api/v1/institutions/{institutionId}/caregivers - 요양보호사 목록
  3. GET /api/v1/institutions/{institutionId}/reservations - 예약 목록
  4. PATCH /api/v1/reservations/{reservationId}/status - 예약 상태 변경

3순위 (부가 기능)

  1. PATCH /api/v1/institutions/{institutionId}/admission - 입소 가능 여부
  2. GET /api/v1/institutions/{institutionId}/dashboard - 대시보드
  3. 나머지 수정/삭제 API들

🔐 Part 1: 기관 Auth 인증 연결

현재 상황

  • ✅ AuthController에서 기관 관리자 회원가입 완료
  • ✅ InstitutionAdmin 계정 생성됨
  • ❌ Institution(기관) 정보는 별도로 등록해야 함

구현할 것

1. 기관 등록 API

POST /api/v1/institutions/register
권한: OWNER (기관이 없는 경우만)
입력:
  - 기관명, 기관 유형, 사업자등록번호
  - 전화번호, 주소
  - 운영시간, 병상 수, 가격 정보
동작:
  - Institution 생성 (approvalStatus = PENDING)
  - InstitutionAdmin.institution 연결
  - Geocoding API로 위경도 자동 변환
검증:
  - 사업자등록번호 중복 체크
  - 이미 기관을 등록했는지 확인

2. 내 기관 조회

GET /api/v1/institutions/my
권한: OWNER, MANAGER, STAFF
응답: 내가 속한 기관 정보

🏥 Part 2: 기관 CRUD + 권한

구현할 API

1. 기관 정보 수정

PUT /api/v1/institutions/{institutionId}
권한: OWNER, MANAGER
제한: 본인 기관만 수정 가능

2. 입소 가능 여부 변경

PATCH /api/v1/institutions/{institutionId}/admission?isAvailable=true
권한: OWNER, MANAGER

3. 기관 삭제 (Soft Delete)

DELETE /api/v1/institutions/{institutionId}
권한: OWNER만
동작: deleted = true

4. 기관 목록 조회 (공개)

GET /api/v1/institutions
권한: 공개
이미 구현됨 ✅

5. 기관 상세 조회 (공개)

GET /api/v1/institutions/{institutionId}
권한: 공개
이미 구현됨 ✅

권한 체계

Controller에서 @AuthenticationPrincipal 사용

@PutMapping("/{institutionId}")
public ResponseEntity<Void> updateInstitution(
    @AuthenticationPrincipal InstitutionAdminDetails adminDetails,
    @PathVariable Long institutionId,
    @Valid @RequestBody InstitutionUpdateRequestDto dto
) {
    Long adminId = adminDetails.getId();
    institutionService.updateInstitution(institutionId, adminId, dto);
    return ResponseEntity.ok().build();
}

SecurityService 생성

  • isInstitutionMember(institutionId, adminId) - 기관 소속 확인
  • isOwner(institutionId, adminId) - OWNER 권한 확인
  • canManage(institutionId, adminId) - OWNER 또는 MANAGER 확인

👨‍⚕️ Part 3: 요양보호사 관리

구현할 API

1. 요양보호사 등록

POST /api/v1/institutions/{institutionId}/caregivers
권한: OWNER, MANAGER
입력: 이름, 전화번호, 자격증번호, 경력, 전문분야

2. 요양보호사 목록

GET /api/v1/institutions/{institutionId}/caregivers
권한: 공개 (활성화된 것만)
필터: isActive

3. 요양보호사 수정

PUT /api/v1/institutions/{institutionId}/caregivers/{caregiverId}
권한: OWNER, MANAGER

4. 활성화 상태 변경

PATCH /api/v1/institutions/{institutionId}/caregivers/{caregiverId}/status?isActive=false
권한: OWNER, MANAGER

5. 요양보호사 삭제

DELETE /api/v1/institutions/{institutionId}/caregivers/{caregiverId}
권한: OWNER

검증 로직

  • 자격증 번호 중복 확인
  • 전화번호 형식 검증
  • 본인 기관 소속만 수정 가능

💬 Part 4: 상담 서비스 관리

구현할 API

1. 상담 서비스 등록

POST /api/v1/institutions/{institutionId}/counsels
권한: OWNER, MANAGER
입력: 서비스명, 설명, 시간(분), 가격

2. 상담 서비스 목록

GET /api/v1/institutions/{institutionId}/counsels
권한: 공개 (활성화된 것만)

3. 상담 서비스 수정

PUT /api/v1/institutions/{institutionId}/counsels/{counselId}
권한: OWNER, MANAGER

4. 제공 여부 변경

PATCH /api/v1/institutions/{institutionId}/counsels/{counselId}/status?isActive=true
권한: OWNER, MANAGER

5. 상담 서비스 삭제

DELETE /api/v1/institutions/{institutionId}/counsels/{counselId}
권한: OWNER

📅 Part 5: 예약 관리 (기관 관리자 관점)

구현할 API

1. 내 기관 예약 목록

GET /api/v1/institutions/{institutionId}/reservations
권한: OWNER, MANAGER, STAFF
필터: status (PENDING, CONFIRMED, CANCELLED, COMPLETED, NO_SHOW)
정렬: 예약일시
페이징: page, size

2. 예약 상태 변경

PATCH /api/v1/reservations/{reservationId}/status
권한: OWNER, MANAGER
Body: { "status": "CONFIRMED" }
가능한 전환:
  - PENDING → CONFIRMED (승인)
  - PENDING → CANCELLED (거절)
  - CONFIRMED → COMPLETED (완료)
  - CONFIRMED → NO_SHOW (노쇼)

3. 예약 상세 조회

GET /api/v1/reservations/{reservationId}
권한: OWNER, MANAGER, STAFF (본인 기관 예약만)

검증 로직

  • 예약 시간 중복 확인
  • 본인 기관 예약만 조회/수정
  • 최종 상태는 변경 불가

📊 Part 6: 기관 대시보드

구현할 API

대시보드 통계

GET /api/v1/institutions/{institutionId}/dashboard
권한: OWNER, MANAGER
응답:
  - 총 병상 수 / 입소 가능 여부
  - 활성 요양보호사 수
  - 예약 통계 (대기/확정/완료 개수)
  - 이번 달 예약 건수
  - 최근 예약 5건

🏗️ 엔티티 구조

Institution (기관)

✅ 이미 존재
- id, name, institutionType, phoneNumber
- address, location, approvalStatus
- bedCount, isAdmissionAvailable, priceInfo, openingHours

InstitutionAdmin (기관 관리자)

✅ 이미 존재
- id, institution, name, username, passwordHash
- phoneNumber, birthDate, role (OWNER/MANAGER/STAFF)

CareGiver (요양보호사)

✅ 이미 존재
- id, institution, name, phoneNumber
- certificationNumber, certificationDate
- experienceYears, specialization, isActive

InstitutionCounsel (상담 서비스)

✅ 이미 존재
- id, institution, serviceName, description
- durationMinutes, price, isActive

Reservation (예약)

❌ 구현 필요
- id, institutionCounsel, member, elderlyProfile
- title, description
- reservationDate, reservationTime
- status (PENDING, CONFIRMED, CANCELLED, COMPLETED, NO_SHOW)

📋 구현 순서

Step 1: 기관 등록 및 Auth 연결 (1일)

  • POST /api/v1/institutions/register 구현
  • 사업자등록번호 중복 체크
  • InstitutionAdmin.institution 연결
  • Geocoding API 연동
  • GET /api/v1/institutions/my 구현

Step 2: 권한 체계 (1일)

  • InstitutionSecurityService 생성
  • InstitutionAdminRepository 메서드 추가
  • Controller에 @AuthenticationPrincipal 적용
  • Service에서 권한 검증

Step 3: 기관 CRUD (1일)

  • 기관 수정 API
  • 입소 가능 여부 변경 API
  • Soft Delete API

Step 4: 요양보호사 관리 (2일)

  • CareGiverService 구현
  • CareGiverController 구현 (5개 API)
  • DTO 정의 및 Validation

Step 5: 상담 서비스 관리 (1일)

  • InstitutionCounselService 구현
  • InstitutionCounselController 구현 (5개 API)

Step 6: 예약 Entity 및 Repository (1일)

  • Reservation Entity 생성
  • ReservationRepository 구현
  • ReservationStatus Enum 정의

Step 7: 예약 관리 (2일)

  • ReservationService 구현
  • ReservationController 구현 (기관 관리자용 3개 API)
  • 예약 시간 중복 검증

Step 8: 대시보드 (1일)

  • 통계 쿼리 작성 (QueryDSL)
  • DashboardService 구현
  • DashboardController 구현

Step 9: 테스트 (1일)

  • Swagger 시나리오 테스트
  • 권한 체크 검증
  • 예외 처리 확인

예상 기간: 11일 (약 2.5주)


🚨 핵심 주의사항

  1. 기관 등록

    • 회원가입과 분리 (회원가입 → 별도 기관 등록)
    • OWNER는 1개 기관만 등록 가능
    • 사업자등록번호 중복 체크 필수
  2. 권한

    • 모든 API에 권한 체크 필수
    • @AuthenticationPrincipal로 사용자 정보 추출
    • 본인 기관만 관리 가능
  3. 검증

    • 자격증 번호 중복 확인
    • 예약 시간 중복 확인
    • 전화번호 형식 검증
  4. Soft Delete

    • 실제 삭제 X
    • deleted = true로 변경
  5. 성능

    • N+1 문제 방지 (Fetch Join)
    • 페이징 처리
  6. 로그

    • 중요 작업 시 로그 남기기
    • AOP 활용

📚 참고 파일

이미 존재하는 파일

✅ /api/institution/controller/InstitutionController.java
✅ /domain/institution/profile/entity/Institution.java
✅ /domain/institution/profile/entity/InstitutionAdmin.java
✅ /domain/institution/profile/entity/CareGiver.java
✅ /domain/institution/counsel/entity/InstitutionCounsel.java
✅ /domain/institution/profile/repository/InstitutionRepository.java
✅ /domain/institution/profile/repository/CareGiverRepository.java
✅ /api/institution/dto/request/InstitutionCreateRequestDto.java
✅ /api/institution/dto/request/CareGiverCreateRequestDto.java

생성 필요한 파일

❌ /domain/reservation/entity/Reservation.java
❌ /domain/reservation/entity/ReservationStatus.java
❌ /domain/reservation/repository/ReservationRepository.java
❌ /domain/reservation/service/ReservationService.java
❌ /api/reservation/controller/ReservationController.java
❌ /domain/institution/profile/service/InstitutionSecurityService.java
❌ /api/institution/controller/CareGiverController.java
❌ /api/institution/controller/InstitutionCounselController.java
❌ /api/institution/controller/DashboardController.java

💡 구현 팁

1. 권한 체크 예시

// Service에서
public void updateInstitution(Long institutionId, Long adminId, InstitutionUpdateRequestDto dto) {
    if (!securityService.canManage(institutionId, adminId)) {
        throw new BusinessException(ErrorCode.FORBIDDEN);
    }
    // 비즈니스 로직
}

2. 예약 시간 중복 체크

boolean exists = reservationRepository.existsByInstitutionCounselIdAndReservationDateAndReservationTimeAndStatusIn(
    counselId, date, time, List.of(PENDING, CONFIRMED)
);

3. 통계 쿼리 (QueryDSL)

JPAQueryFactory queryFactory;

public DashboardDto getDashboardStats(Long institutionId) {
    // 예약 통계
    Long pendingCount = queryFactory
        .select(reservation.count())
        .from(reservation)
        .where(reservation.institutionCounsel.institution.id.eq(institutionId)
            .and(reservation.status.eq(PENDING)))
        .fetchOne();
    
    // ...
}

🎯 완료 기준

  • 모든 API가 Swagger에서 정상 동작
  • 권한 체크가 모든 API에 적용됨
  • 예약 시간 중복이 방지됨
  • 대시보드에서 통계가 정확하게 표시됨
  • Soft Delete가 정상 동작함
  • N+1 문제가 없음
  • 로그가 정상적으로 남음

📝 담장자

@Uechann

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions