Skip to content

Conversation

@clainyun
Copy link
Member

@clainyun clainyun commented May 21, 2025

๐Ÿ“Œ PR ์ œ๋ชฉ

[feat] ๊ณต๊ฐ„ ๋‹ด๋‹น์ž ์ •๋ณด ์กฐํšŒ API ๊ตฌํ˜„


โœจ ๋ณ€๊ฒฝ ์‚ฌํ•ญ

๐Ÿ” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

  • ๊ณต๊ฐ„๋ณ„ ๋‹ด๋‹น์ž ์ •๋ณด ์กฐํšŒ API ๊ตฌํ˜„ (GET /api/workers/zone/{zoneId}/manager)
    • ๋‹ด๋‹น์ž์˜ ๊ธฐ๋ณธ ์ •๋ณด (์ด๋ฆ„, ID)
    • ์—ฐ๋ฝ์ฒ˜ ์ •๋ณด (์ด๋ฉ”์ผ, ์ „ํ™”๋ฒˆํ˜ธ)
    • ํ˜„์žฌ ์œ„์น˜ ์ •๋ณด (ํ˜„์žฌ ์žˆ๋Š” ๊ณต๊ฐ„์˜ ID์™€ ์ด๋ฆ„)

๐Ÿ“ ํด๋ž˜์Šค๋ณ„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ

  1. DTO
// ZoneManagerResponseDto.java
@Getter @Builder @NoArgsConstructor @AllArgsConstructor
public class ZoneManagerResponseDto {
    private String workerId;          // ์ž‘์—…์ž ID
    private String name;              // ์ž‘์—…์ž ์ด๋ฆ„
    private String phoneNumber;       // ์—ฐ๋ฝ์ฒ˜
    private String email;             // ์ด๋ฉ”์ผ
    private String currentZoneId;     // ํ˜„์žฌ ์œ„์น˜ํ•œ ๊ณต๊ฐ„ ID
    private String currentZoneName;   // ํ˜„์žฌ ์œ„์น˜ํ•œ ๊ณต๊ฐ„ ์ด๋ฆ„
    
    // Entity โ†’ DTO ๋ณ€ํ™˜ ๋ฉ”์„œ๋“œ
    public static ZoneManagerResponseDto fromEntity(Worker worker, Zone currentZone) { ... }
}
  1. Repository
// WorkerZoneRepository.java
public interface WorkerZoneRepository extends JpaRepository<WorkerZone, WorkerZoneId> {
    // ํŠน์ • zone_id์— ์†ํ•œ ์ž‘์—…์ž ๋ชฉ๋ก ์กฐํšŒ
    List<WorkerZone> findByZoneZoneId(String zoneId);
    
    // ํŠน์ • zone_id์˜ ๋‹ด๋‹น์ž ์กฐํšŒ (manageYn = true)
    Optional<WorkerZone> findByZoneZoneIdAndManageYnIsTrue(String zoneId);
}
  1. Service
// WorkerService.java
@Service @RequiredArgsConstructor
public class WorkerService {
    private final WorkerRepository workerRepository;
    private final WorkerLocationService workerLocationService;
    private final WorkerZoneRepository workerZoneRepository;

    @Transactional(readOnly = true)
    public ZoneManagerResponseDto getZoneManagerWithLocation(String zoneId) {
        // 1. ํ•ด๋‹น ๊ณต๊ฐ„์˜ ๋‹ด๋‹น์ž ์กฐํšŒ
        WorkerZone zoneManager = workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId)
                .orElseThrow(() -> new IllegalArgumentException("ํ•ด๋‹น ๊ณต๊ฐ„์˜ ๋‹ด๋‹น์ž๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค: " + zoneId));
        
        // 2. ๋‹ด๋‹น์ž์˜ ํ˜„์žฌ ์œ„์น˜ ์กฐํšŒ
        ZoneHist currentLocation = workerLocationService.getCurrentWorkerLocation(manager.getWorkerId());
        
        // 3. DTO ๋ณ€ํ™˜ ๋ฐ ๋ฐ˜ํ™˜
        return ZoneManagerResponseDto.fromEntity(manager, currentZone);
    }
}
  1. Controller
// WorkerController.java
@RestController @RequestMapping("/api/workers")
public class WorkerController {
    @Operation(summary = "๊ณต๊ฐ„ ๋‹ด๋‹น์ž ์ •๋ณด ์กฐํšŒ")
    @GetMapping("/zone/{zoneId}/manager")
    public ResponseEntity<ZoneManagerResponseDto> getZoneManager(@PathVariable String zoneId) {
        ZoneManagerResponseDto manager = workerService.getZoneManagerWithLocation(zoneId);
        return ResponseEntity.ok(manager);
    }
}

๐Ÿ“ธ ์Šคํฌ๋ฆฐ์ƒท

๋ณ€๊ฒฝ ์ „ ๋ณ€๊ฒฝ ํ›„
![๋ณ€๊ฒฝ ์ „](์ด๋ฏธ์ง€ URL) ![๋ณ€๊ฒฝ ํ›„](์ด๋ฏธ์ง€ URL)
  • Swagger UI์—์„œ API ๋ฌธ์„œํ™” ๋ฐ ํ…Œ์ŠคํŠธ ํ™”๋ฉด
  • API ์‘๋‹ต ๊ฒฐ๊ณผ ํ™”๋ฉด

โœ… ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ์ฝ”๋“œ์— ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ์—†๋Š”๊ฐ€?
    • ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜์—์„œ ๋‹จ์ผ ๊ฐ์ฒด ๋ฐ˜ํ™˜์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋กœ์ง ์ œ๊ฑฐ
    • ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”์„œ๋“œ ์—†์Œ
    • ๋ชจ๋“  ํด๋ž˜์Šค์— ์ ์ ˆํ•œ ์ ‘๊ทผ ์ œ์–ด์ž ์‚ฌ์šฉ
  • ๊ธฐ๋Šฅ์ด ์ •์ƒ ๋™์ž‘ํ•˜๋Š”๊ฐ€?
    • Swagger UI๋ฅผ ํ†ตํ•œ API ํ…Œ์ŠคํŠธ ์™„๋ฃŒ
    • ์ •์ƒ ์ผ€์ด์Šค ํ…Œ์ŠคํŠธ ์™„๋ฃŒ
    • ์˜ˆ์™ธ ์ผ€์ด์Šค (๋‹ด๋‹น์ž๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ) ํ…Œ์ŠคํŠธ ์™„๋ฃŒ
    • ๋‹ด๋‹น์ž์˜ ํ˜„์žฌ ์œ„์น˜๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์ฒ˜๋ฆฌ ํ™•์ธ
  • ์˜์กด์„ฑ์€ ๋ฌธ์ œ๊ฐ€ ์—†๋Š”๊ฐ€?
    • ๊ธฐ์กด ์—”ํ‹ฐํ‹ฐ์™€ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ํ™œ์šฉ
    • ์ˆœํ™˜ ์ฐธ์กฐ ์—†์Œ
    • Lombok ์–ด๋…ธํ…Œ์ด์…˜ ์ •์ƒ ๋™์ž‘ ํ™•์ธ
  • ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋Š” ๋ช…ํ™•ํ•œ๊ฐ€?
    • ์ปจ๋ฒค์…˜์— ๋งž๋Š” ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ์ž‘์„ฑ
    • ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…

๐Ÿ“Ž ๊ด€๋ จ ์ด์Šˆ

์—†์Œ


๐Ÿ’ฌ ์ถ”๊ฐ€ ์„ค๋ช…

  1. ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™

    • ๊ณต๊ฐ„๋ณ„ ๋‹ด๋‹น์ž๋Š” ๋ฐ˜๋“œ์‹œ ํ•œ ๋ช…๋งŒ ์กด์žฌ
    • ๋‹ด๋‹น์ž๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ 400 Bad Request ์‘๋‹ต ๋ฐ˜ํ™˜
    • ๋‹ด๋‹น์ž์˜ ํ˜„์žฌ ์œ„์น˜ ์ •๋ณด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ null๋กœ ๋ฐ˜ํ™˜
  2. API ๋ช…์„ธ

  • Request
GET /api/workers/zone/{zoneId}/manager
  • Response (200 OK)
{
    "workerId": "20240101-1234",
    "name": "ํ™๊ธธ๋™",
    "phoneNumber": "01012345678",
    "email": "[email protected]",
    "currentZoneId": "ZONE002",
    "currentZoneName": "2์ธต ์ž‘์—…์žฅ"
}
  • Error Response (400 Bad Request)
{
    "message": "ํ•ด๋‹น ๊ณต๊ฐ„์˜ ๋‹ด๋‹น์ž๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค: ZONE001",
    "status": 400
}
  1. ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค
    • ์ •์ƒ ์ผ€์ด์Šค: ๋‹ด๋‹น์ž๊ฐ€ ์žˆ๋Š” ๊ณต๊ฐ„ ์กฐํšŒ
    • ์˜ˆ์™ธ ์ผ€์ด์Šค 1: ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ณต๊ฐ„ ID๋กœ ์กฐํšŒ
    • ์˜ˆ์™ธ ์ผ€์ด์Šค 2: ๋‹ด๋‹น์ž๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ๊ณต๊ฐ„ ์กฐํšŒ
    • ์˜ˆ์™ธ ์ผ€์ด์Šค 3: ๋‹ด๋‹น์ž๊ฐ€ ํ˜„์žฌ ์–ด๋–ค ๊ณต๊ฐ„์—๋„ ์—†๋Š” ๊ฒฝ์šฐ

clainyun added 8 commits May 20, 2025 20:06
โ€ฆ ์ž‘์—…์ž ๋ฐ ์ „์ฒด ์ž‘์—…์ž ์กฐํšŒ, Swagger API) ๊ตฌํ˜„ ๋ฐ JUnit5 Mockito ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ | ์œค๋‹ค์ธ
โ€ฆ ์ž‘์—…์ž ๋ฐ ์ „์ฒด ์ž‘์—…์ž ์กฐํšŒ, Swagger API) ๊ตฌํ˜„ ๋ฐ JUnit5 Mockito ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ | ์œค๋‹ค์ธ
โ€ฆe ์ถ”๊ฐ€ (ํ•œ๊ธ€ ๋งคํ•‘ ํ™˜๊ฒฝ, ์ž‘์—…์ž, ์„ค๋น„) | ์œค๋‹ค์ธ
โ€ฆ๋น„(์ž‘์—…์ž ์กฐํšŒ ๊ธฐ๋Šฅ ์ˆ˜์ • ์˜ˆ์ •) | ์œค๋‹ค์ธ
@clainyun clainyun requested a review from JuneSHYoo May 21, 2025 08:16
@clainyun clainyun self-assigned this May 21, 2025
@clainyun clainyun merged commit abbc7c9 into develop May 21, 2025
1 check passed
gwangbu-desu pushed a commit that referenced this pull request May 24, 2025
@wdd1016 wdd1016 deleted the feature/FRB-156 branch June 3, 2025 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants