Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.ntropy.common.client;

import java.time.YearMonth;

import com.ntropy.common.dto.work.summary.MonthlyIncomeAnalysisSummary;

/** work-service가 diagnosis-service에 제공하는 회원·연월별 소득분석 조회 계약. */
public interface IncomeAnalysisQueryClient {

MonthlyIncomeAnalysisSummary getMonthlyIncomeAnalysis(
Long userId,
YearMonth yearMonth
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ public interface JobCommandClient {

Long registerJob(JobRegisterCommand command);

void updateJob(Long jobId, JobUpdateCommand command);
/** userId는 요청자 본인 확인용 - jobId가 그 사람 소유가 아니면 예외. */
void updateJob(Long userId, Long jobId, JobUpdateCommand command);

void deactivateJob(Long jobId);
/** userId는 요청자 본인 확인용 - jobId가 그 사람 소유가 아니면 예외. */
void deactivateJob(Long userId, Long jobId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ public interface WorkLogCommandClient {

Long registerActual(WorkLogRegisterCommand command);

void editWorkLog(Long logId, WorkLogPatchCommand command);
/** userId는 요청자 본인 확인용 - logId가 그 사람 소유가 아니면 예외. */
void editWorkLog(Long userId, Long logId, WorkLogPatchCommand command);

void confirmWorkLog(Long logId, WorkLogPatchCommand command);
/** userId는 요청자 본인 확인용 - logId가 그 사람 소유가 아니면 예외. */
void confirmWorkLog(Long userId, Long logId, WorkLogPatchCommand command);

void deleteWorkLog(Long logId);
/** userId는 요청자 본인 확인용 - logId가 그 사람 소유가 아니면 예외. */
void deleteWorkLog(Long userId, Long logId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ntropy.common.dto.work.summary;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* 잡별 발생소득(확정 근무일지 기준)과 실입금소득(매칭된 입금 거래 기준) 비교.
* differenceAmount가 음수라고 해서 미지급을 의미하지는 않는다(다음 달 입금 가능성).
*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class EarnedDepositComparison {

private Long jobId;
private String jobName;
private Long earnedIncome;
private Long depositedIncome;
private Long differenceAmount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.ntropy.common.dto.work.summary;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/** 월별 소득분석에서 잡별 피로도 집계. averageFatigue는 근무시간 가중평균이다. */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class JobFatigueSummary {

private Long jobId;
private String jobName;
private Integer workDays;
private Long totalWorkMinutes;
private Double averageFatigue;
private Long latestFatigue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.ntropy.common.dto.work.summary;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/** 월별 소득분석에서 잡별 소득 비중을 나타내는 DTO. */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class JobIncomeSummary {

private Long jobId;
private String jobName;
private Long incomeAmount;
private Double incomeRatio;
private Integer transactionCount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.ntropy.common.dto.work.summary;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* work-service가 diagnosis-service/AI-service에 제공하는 회원·연월별 소득분석 결과.
* 필드가 많아 다른 summary DTO와 달리 Builder를 사용한다.
*/
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthlyIncomeAnalysisSummary {

private Long userId;
private YearMonth yearMonth;
private LocalDate asOfDate;
private Long totalIncome;
private Long unmatchedIncome;
private Long pendingSettlementIncome;
private Integer matchedTransactionCount;
private Integer unmatchedTransactionCount;
private Integer ambiguousTransactionCount;
private List<JobIncomeSummary> jobIncomes;
private Long primaryJobId;
private String primaryJobName;
private Long previousMonthIncome;
private Long incomeChangeAmount;
private Double incomeChangeRate;
private Double incomeVolatility;
private List<EarnedDepositComparison> earnedDepositComparisons;
private List<JobFatigueSummary> fatigueSummaries;
private LocalDateTime calculatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,31 @@ public ApiResponse<JobCandidatesResponse> getJobCandidates(@ApiParam(hidden = tr
}

@PostMapping
public ResponseEntity<ApiResponse<JobCreateResponse>> createJob(@RequestBody JobCreateRequest request) {
Long jobId = jobCommandClient.registerJob(request.toCommand());
public ResponseEntity<ApiResponse<JobCreateResponse>> createJob(
@ApiParam(hidden = true) Authentication authentication,
@RequestBody JobCreateRequest request) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
Long jobId = jobCommandClient.registerJob(request.toCommand(userId));
ApiResponse<JobCreateResponse> body =
ApiResponse.success(HttpStatus.CREATED.value(), "잡이 등록되었습니다.", new JobCreateResponse(jobId));
return ResponseEntity.status(HttpStatus.CREATED).body(body);
}

@PutMapping("/{jobId}")
public ApiResponse<Void> updateJob(@PathVariable Long jobId, @RequestBody JobUpdateRequest request) {
jobCommandClient.updateJob(jobId, request.toCommand());
public ApiResponse<Void> updateJob(
@ApiParam(hidden = true) Authentication authentication,
@PathVariable Long jobId, @RequestBody JobUpdateRequest request) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
jobCommandClient.updateJob(userId, jobId, request.toCommand());
return ApiResponse.success(HttpStatus.OK.value(), "잡이 수정되었습니다.", null);
}

@PatchMapping("/{jobId}/deactivate")
public ApiResponse<Void> deactivateJob(@PathVariable Long jobId) {
jobCommandClient.deactivateJob(jobId);
public ApiResponse<Void> deactivateJob(
@ApiParam(hidden = true) Authentication authentication,
@PathVariable Long jobId) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
jobCommandClient.deactivateJob(userId, jobId);
return ApiResponse.success(HttpStatus.OK.value(), "잡이 비활성화되었습니다.", null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PatchMapping;
Expand All @@ -14,8 +15,10 @@
import com.ntropy.bff.dto.work.request.WorkLogPatchRequest;
import com.ntropy.bff.dto.work.request.WorkLogRegisterRequest;
import com.ntropy.bff.dto.work.response.WorkLogCreateResponse;
import com.ntropy.bff.security.AuthenticatedUserIdResolver;
import com.ntropy.common.client.WorkLogCommandClient;

import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;

@RestController
Expand All @@ -24,38 +27,54 @@
public class WorkLogController {

private final WorkLogCommandClient workLogCommandClient;
private final AuthenticatedUserIdResolver authenticatedUserIdResolver;

@PostMapping("/plan")
public ResponseEntity<ApiResponse<WorkLogCreateResponse>> registerPlan(@RequestBody WorkLogRegisterRequest request) {
Long workId = workLogCommandClient.registerPlan(request.toCommand());
public ResponseEntity<ApiResponse<WorkLogCreateResponse>> registerPlan(
@ApiParam(hidden = true) Authentication authentication,
@RequestBody WorkLogRegisterRequest request) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
Long workId = workLogCommandClient.registerPlan(request.toCommand(userId));
ApiResponse<WorkLogCreateResponse> body =
ApiResponse.success(HttpStatus.CREATED.value(), "근무 계획이 등록되었습니다.", new WorkLogCreateResponse(workId));
return ResponseEntity.status(HttpStatus.CREATED).body(body);
}

@PostMapping("/actual")
public ResponseEntity<ApiResponse<WorkLogCreateResponse>> registerActual(@RequestBody WorkLogRegisterRequest request) {
Long workId = workLogCommandClient.registerActual(request.toCommand());
public ResponseEntity<ApiResponse<WorkLogCreateResponse>> registerActual(
@ApiParam(hidden = true) Authentication authentication,
@RequestBody WorkLogRegisterRequest request) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
Long workId = workLogCommandClient.registerActual(request.toCommand(userId));
ApiResponse<WorkLogCreateResponse> body =
ApiResponse.success(HttpStatus.CREATED.value(), "근무일지가 등록되었습니다.", new WorkLogCreateResponse(workId));
return ResponseEntity.status(HttpStatus.CREATED).body(body);
}

@PatchMapping("/{workId}/edit")
public ApiResponse<Void> editWorkLog(@PathVariable Long workId, @RequestBody WorkLogPatchRequest request) {
workLogCommandClient.editWorkLog(workId, request.toCommand());
public ApiResponse<Void> editWorkLog(
@ApiParam(hidden = true) Authentication authentication,
@PathVariable Long workId, @RequestBody WorkLogPatchRequest request) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
workLogCommandClient.editWorkLog(userId, workId, request.toCommand());
return ApiResponse.success(HttpStatus.OK.value(), "근무일지가 수정되었습니다.", null);
}

@PatchMapping("/{workId}/confirm")
public ApiResponse<Void> confirmWorkLog(@PathVariable Long workId, @RequestBody WorkLogPatchRequest request) {
workLogCommandClient.confirmWorkLog(workId, request.toCommand());
public ApiResponse<Void> confirmWorkLog(
@ApiParam(hidden = true) Authentication authentication,
@PathVariable Long workId, @RequestBody WorkLogPatchRequest request) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
workLogCommandClient.confirmWorkLog(userId, workId, request.toCommand());
return ApiResponse.success(HttpStatus.OK.value(), "근무일지가 확정되었습니다.", null);
}

@DeleteMapping("/{workId}")
public ApiResponse<Void> deleteWorkLog(@PathVariable Long workId) {
workLogCommandClient.deleteWorkLog(workId);
public ApiResponse<Void> deleteWorkLog(
@ApiParam(hidden = true) Authentication authentication,
@PathVariable Long workId) {
Long userId = authenticatedUserIdResolver.resolve(authentication);
workLogCommandClient.deleteWorkLog(userId, workId);
return ApiResponse.success(HttpStatus.OK.value(), "근무일지가 삭제되었습니다.", null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
@NoArgsConstructor
public class JobCreateRequest {

private Long userId;
private Long categoryId;
private String jobName;
private String settlementType;
Expand All @@ -26,7 +25,7 @@ public class JobCreateRequest {
private List<Long> platformIds;
private List<JobScheduleRequest> schedules;

public JobRegisterCommand toCommand() {
public JobRegisterCommand toCommand(Long userId) {
List<JobScheduleRequest> safeSchedules = schedules == null ? Collections.emptyList() : schedules;
return new JobRegisterCommand(
userId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@
@NoArgsConstructor
public class WorkLogRegisterRequest {

private Long userId;
private Long jobId;
private LocalDate workDate;
private LocalTime startTime;
private LocalTime endTime;
private Long taskCount;
private Long fatigue;

public WorkLogRegisterCommand toCommand() {
public WorkLogRegisterCommand toCommand(Long userId) {
return new WorkLogRegisterCommand(userId, jobId, workDate, startTime, endTime, taskCount, fatigue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ntropy.work.client;

import java.time.YearMonth;

import org.springframework.stereotype.Component;

import com.ntropy.common.client.IncomeAnalysisQueryClient;
import com.ntropy.common.dto.work.summary.MonthlyIncomeAnalysisSummary;
import com.ntropy.work.service.IncomeAnalysisService;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class LocalIncomeAnalysisQueryClient implements IncomeAnalysisQueryClient {

private final IncomeAnalysisService incomeAnalysisService;

@Override
public MonthlyIncomeAnalysisSummary getMonthlyIncomeAnalysis(Long userId, YearMonth yearMonth) {
return incomeAnalysisService.getMonthlyIncomeAnalysis(userId, yearMonth);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public Long registerJob(JobRegisterCommand command) {
}

@Override
public void updateJob(Long jobId, JobUpdateCommand command) {
public void updateJob(Long userId, Long jobId, JobUpdateCommand command) {
Job job = Job.builder()
.jobId(jobId)
.categoryId(command.getCategoryId())
Expand All @@ -66,12 +66,12 @@ public void updateJob(Long jobId, JobUpdateCommand command) {
.baseFatigue(command.getBaseFatigue())
.build();

jobService.updateJob(job, toSchedules(command.getSchedules()));
jobService.updateJob(userId, job, toSchedules(command.getSchedules()));
}

@Override
public void deactivateJob(Long jobId) {
jobService.deactivateJob(jobId);
public void deactivateJob(Long userId, Long jobId) {
jobService.deactivateJob(userId, jobId);
}

private List<JobSchedule> toSchedules(List<JobScheduleCommand> commands) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ public Long registerActual(WorkLogRegisterCommand command) {
}

@Override
public void editWorkLog(Long logId, WorkLogPatchCommand command) {
workLogService.editWorkLog(logId, toPatch(command));
public void editWorkLog(Long userId, Long logId, WorkLogPatchCommand command) {
workLogService.editWorkLog(userId, logId, toPatch(command));
}

@Override
public void confirmWorkLog(Long logId, WorkLogPatchCommand command) {
workLogService.confirmWorkLog(logId, toPatch(command));
public void confirmWorkLog(Long userId, Long logId, WorkLogPatchCommand command) {
workLogService.confirmWorkLog(userId, logId, toPatch(command));
}

@Override
public void deleteWorkLog(Long logId) {
workLogService.deleteWorkLog(logId);
public void deleteWorkLog(Long userId, Long logId) {
workLogService.deleteWorkLog(userId, logId);
}

private WorkLog toWorkLog(WorkLogRegisterCommand command) {
Expand Down
Loading
Loading