Skip to content

[Task][P2] Case 상세 담당자 지정·변경 API 구현 #142

Description

@hywznn

한 줄 목표

Case 상세 화면에서 같은 사업장의 활성 HR·관리자를 Task 담당자로 지정·변경하고, 새로고침 후에도 담당자가 유지되도록 합니다.

왜 필요한가요?

현재 Client의 Case 상세에는 담당자 변경 버튼이 있지만 Server에는 담당자를 저장할 assignee_id와 변경 API가 없습니다.

created_byupdated_by는 각각 생성자와 마지막 수정자를 뜻하므로 현재 업무 담당자로 사용할 수 없습니다.

API 계약

담당자 변경

PATCH /api/v1/tasks/{taskId}/assignee
Authorization: Bearer <access-token>
Content-Type: application/json
{
  "assignee_id": "7e2722bb-3c72-4aa0-b37c-28931c4f8e53",
  "expected_version": 3
}

성공 시 변경된 Task 상세를 반환합니다.

담당자 후보 조회

기존 API를 그대로 사용합니다.

GET /api/v1/company-members?active_only=true

구현 범위

  • Task와 DB에 nullable assignee_id 추가
  • Task 생성 시 기본 담당자를 생성자(HR·ADMIN)로 저장
  • PATCH /api/v1/tasks/{taskId}/assignee 구현
  • 담당자 변경 응답과 Task 상세 조회에 담당자 ID·표시명 반환
  • 같은 사업장의 ACTIVE HR·ADMIN만 담당자로 지정
  • ADMIN·HR만 변경 가능
  • expected_version 기반 동시 수정 충돌 처리
  • 담당자 변경 감사로그 기록
  • Swagger 요청·응답·오류 예시 보완
  • 단위·통합·사업장 격리 테스트
  • Task 단위 담당자 변경 방식 최종 확인
  • #143의 V42 병합 후 #135의 V43 병합

오류 규칙

  • 400: 요청 형식 또는 필수값 오류
  • 403: VIEWER 등 변경 권한 없음
  • 404: Task가 없거나 다른 사업장 Task·사용자를 요청
  • 409: 오래된 expected_version
  • 422: 비활성 사용자 또는 담당자로 지정할 수 없는 사용자

보안·데이터 규칙

  • company_id는 요청에서 받지 않고 JWT의 ActorContext로 결정
  • 다른 사업장의 사용자 존재 여부가 노출되지 않도록 404 처리
  • 이메일 등 인증정보는 Task 응답에 포함하지 않음
  • 감사로그에는 담당자 ID 변경만 기록하고 개인정보 원문은 남기지 않음

DB·충돌 주의

  • 이번 담당자 변경 PR #143이 공통 Migration V42를 사용합니다.
  • 새 테이블은 만들지 않고 기존 taskassignee_id와 tenant-aware FK를 추가합니다.
  • PR #135의 PostgreSQL 전용 RLS Migration은 V43으로 조정합니다.
  • feat: 업무카드 담당자 지정·변경 API 구현 #143 병합 후 #135에 최신 main을 반영하고 전체 Flyway 검증을 다시 실행합니다.

완료 기준

  • 담당자 변경 후 Task·Case 재조회에서 동일 담당자가 반환됨
  • 같은 사업장의 활성 HR·ADMIN만 선택 가능
  • 타 사업장·비활성 사용자·권한 없음·동시 수정 충돌 테스트 통과
  • 담당자 변경 감사로그 1건 생성
  • Client #315가 후보 조회 → 변경 → 새로고침 복구 흐름을 연결할 수 있음

Metadata

Metadata

Assignees

Labels

area:serverSpring Boot API·도메인·DB·tenant·Task Workflow 영역; Prompt·모델·Provider 구현 제외priority:P2일정에 따라 미룰 수 있는 보완 작업status:in-progress담당자가 현재 구현 중인 작업type:feature사용자 또는 Agent가 사용하는 기능 개발

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions