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
Expand Up @@ -6,7 +6,7 @@

import com.back.domain.node.dto.BaseLineBulkCreateRequest;
import com.back.domain.node.dto.BaseLineBulkCreateResponse;
import com.back.domain.node.dto.BaseLineDto;
import com.back.domain.node.dto.BaseNodeDto;
import com.back.domain.node.dto.PivotListDto;
import com.back.domain.node.service.NodeService;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -35,16 +35,15 @@ public ResponseEntity<PivotListDto> getPivots(@PathVariable Long baseLineId) {
return ResponseEntity.ok(nodeService.getPivotBaseNodes(baseLineId));
}

// GET /api/v1/base-lines/{baseLineId}/nodes
// 전체 노드 목록 반환
@GetMapping("/{baseLineId}/nodes")
public ResponseEntity<List<BaseLineDto>> getBaseLineNodes(@PathVariable Long baseLineId) {
public ResponseEntity<List<BaseNodeDto>> getBaseLineNodes(@PathVariable Long baseLineId) {
return ResponseEntity.ok(nodeService.getBaseLineNodes(baseLineId));
}

// GET /api/v1/base-lines/node/{baseNodeId}
@GetMapping("/node/{baseNodeId}")
public ResponseEntity<BaseLineDto> getBaseNode(@PathVariable Long baseNodeId) {
// 단일 노드 반환
@GetMapping("/nodes/{baseNodeId}")
public ResponseEntity<BaseNodeDto> getBaseNode(@PathVariable Long baseNodeId) {
return ResponseEntity.ok(nodeService.getBaseNode(baseNodeId));
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
/**
* [API] 피벗에서 시작→연속 저장→완료/취소 흐름
* - from-base: 첫 결정 생성
* - next: 다음 결정 생성
* - from-base: 첫 결정 생성(서버가 피벗 노드 해석)
* - next: 다음 결정 생성(라인은 부모에서 해석)
* - cancel: 라인 취소(파기)
* - complete: 라인 완료(잠금)
*/
package com.back.domain.node.controller;

import com.back.domain.node.dto.*;
import com.back.domain.node.dto.DecLineDto;
import com.back.domain.node.dto.DecisionLineLifecycleDto;
import com.back.domain.node.dto.DecisionNodeFromBaseRequest;
import com.back.domain.node.dto.DecisionNodeNextRequest;
import com.back.domain.node.service.NodeService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.*;
Expand All @@ -20,21 +23,25 @@ public class DecisionFlowController {

private final NodeService nodeService;

// from-base: 라인+피벗(순번/나이)+분기슬롯 인덱스만 받아 서버가 pivotBaseNodeId를 해석
@PostMapping("/from-base")
public ResponseEntity<DecLineDto> createFromBase(@RequestBody DecisionNodeFromBaseRequest request) {
return ResponseEntity.status(HttpStatus.CREATED).body(nodeService.createDecisionNodeFromBase(request));
}

// next: 부모 결정 id만 받아 서버가 라인/다음 나이/베이스 매칭을 해석
@PostMapping("/next")
public ResponseEntity<DecLineDto> createNext(@RequestBody DecisionNodeNextRequest request) {
return ResponseEntity.status(HttpStatus.CREATED).body(nodeService.createDecisionNodeNext(request));
}

// 라인 취소
@PostMapping("/{decisionLineId}/cancel")
public ResponseEntity<DecisionLineLifecycleDto> cancel(@PathVariable Long decisionLineId) {
return ResponseEntity.ok(nodeService.cancelDecisionLine(decisionLineId));
}

// 라인 완료
@PostMapping("/{decisionLineId}/complete")
public ResponseEntity<DecisionLineLifecycleDto> complete(@PathVariable Long decisionLineId) {
return ResponseEntity.ok(nodeService.completeDecisionLine(decisionLineId));
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

public record BaseLineBulkCreateRequest(
Long userId,
String title,
List<BaseNodePayload> nodes
) {
public record BaseNodePayload(
Expand Down
21 changes: 0 additions & 21 deletions back/src/main/java/com/back/domain/node/dto/BaseLineDto.java

This file was deleted.

25 changes: 25 additions & 0 deletions back/src/main/java/com/back/domain/node/dto/BaseNodeDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* [DTO-RES] BaseNode 응답
* - 고정 선택과 분기 2칸 및 각 타겟 링크를 포함한다
*/
package com.back.domain.node.dto;

import com.back.domain.node.entity.NodeCategory;

public record BaseNodeDto(
Long id,
Long userId,
String type,
NodeCategory category,
String situation,
String decision,
Integer ageYear,
Long baseLineId,
Long parentId,
String title,
String fixedChoice,
String altOpt1,
String altOpt2,
Long altOpt1TargetDecisionId,
Long altOpt2TargetDecisionId
) {}
14 changes: 8 additions & 6 deletions back/src/main/java/com/back/domain/node/dto/DecLineDto.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
/**
* [DTO-RES] DecisionNode 응답
* - background: AI 생성 설명(옵션)
* - options/selectedIndex/parentOptionIndex를 포함해 프론트 렌더 정보를 제공한다
*/
package com.back.domain.node.dto;

import com.back.domain.node.entity.NodeCategory;
import java.util.List;

public record DecLineDto(
Long id,
Long userId,
String type, // "DECISION"
String type,
NodeCategory category,
String situation,
String decision,
Integer ageYear,
Long decisionLineId,
Long parentId,
Long baseNodeId,
String background
) {

}
String background,
List<String> options,
Integer selectedIndex,
Integer parentOptionIndex
) {}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* [DTO-REQ] DecisionNode 생성 요청
* - decisionLineId 없으면 새 라인 생성
* - parentId 또는 baseNodeId 중 하나 사용
* - 서비스 내부 매퍼용으로 사용되며 외부 API에서는 직접 받지 않는다
*/
package com.back.domain.node.dto;

import com.back.domain.node.entity.NodeCategory;
import java.util.List;

public record DecisionNodeCreateRequestDto(
Long decisionLineId,
Expand All @@ -14,5 +14,8 @@ public record DecisionNodeCreateRequestDto(
NodeCategory category,
String situation,
String decision,
Integer ageYear
Integer ageYear,
List<String> options,
Integer selectedIndex,
Integer parentOptionIndex
) {}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
/**
* [DTO-REQ] BaseLine의 특정 분기점(BaseNode)에서 DecisionNode 생성 요청
* - category/situation/ageYear 미지정 시 pivot 값 상속
* [DTO-REQ] BaseLine 피벗에서 첫 결정 생성 요청(슬림 계약 + 옵션 지원)
* - 서버가 baseLineId + (pivotOrd | pivotAge)로 피벗 노드를 해석하고, selectedAltIndex(0/1) 분기 슬롯을 링크한다
*/
package com.back.domain.node.dto;

import com.back.domain.node.entity.NodeCategory;
import java.util.List;

public record DecisionNodeFromBaseRequest(
Long userId,
Long baseLineId,
Long pivotBaseNodeId,
NodeCategory category,
String situation,
String decision,
Integer ageYear
Integer pivotOrd, // 피벗 순번(중간 노드 기준, 0부터) — null이면 pivotAge 사용
Integer pivotAge, // 피벗 나이 — null이면 pivotOrd 사용
Integer selectedAltIndex, // 0 또는 1
NodeCategory category, // 미지정 시 pivot.category 상속
String situation, // 미지정 시 pivot.situation 상속
List<String> options, // 1~3개, null 가능(첫 결정 노드도 옵션 보유 가능)
Integer selectedIndex // 0..2, null 가능(주어지면 decision과 일치)
) {}
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
/**
* [DTO-REQ] 직전 DecisionNode(parent)에서 다음 DecisionNode 생성
* - ageYear 미지정 시 자동으로 다음 피벗 나이 선택
* [DTO-REQ] 직전 DecisionNode(parent)에서 다음 DecisionNode 생성(슬림 계약)
* - 라인은 부모로부터 해석하고, ageYear 미지정 시 다음 피벗 나이 자동 선택
*/
package com.back.domain.node.dto;

import com.back.domain.node.entity.NodeCategory;
import java.util.List;

public record DecisionNodeNextRequest(
Long userId,
Long parentDecisionNodeId,
Long decisionLineId,
NodeCategory category,
String situation,
String decision,
Integer ageYear
NodeCategory category, // 미지정 시 parent.category 상속
String situation, // 미지정 시 parent.situation 상속
Integer ageYear, // null이면 다음 피벗 자동 선택
List<String> options, // 1~3개, null 가능
Integer selectedIndex, // 0..2, null 가능
Integer parentOptionIndex // 부모 옵션 인덱스(0..2), null 가능
) {}
2 changes: 1 addition & 1 deletion back/src/main/java/com/back/domain/node/dto/TreeDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
import java.util.List;

public record TreeDto(
List<BaseLineDto> baseNodes,
List<BaseNodeDto> baseNodes,
List<DecLineDto> decisionNodes
) {}
3 changes: 3 additions & 0 deletions back/src/main/java/com/back/domain/node/entity/BaseLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public class BaseLine extends BaseEntity {
@JoinColumn(name = "user_id", nullable = false)
private User user;

@Column(length = 100, nullable = false)
private String title;

// BaseLine ←→ BaseNode 양방향 매핑 (BaseNode 쪽에 @ManyToOne BaseLine baseLine 있어야 함)
@OneToMany(mappedBy = "baseLine", cascade = CascadeType.ALL, orphanRemoval = false)
@Builder.Default
Expand Down
21 changes: 19 additions & 2 deletions back/src/main/java/com/back/domain/node/entity/BaseNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,31 @@ public class BaseNode extends BaseEntity {

private int ageYear;

// com.back.domain.node.entity.BaseNode 안에 추가
@Column(length = 255)
private String fixedChoice; // 고정 선택 1개

@Column(length = 255)
private String altOpt1; // 분기 선택지 1

@Column(length = 255)
private String altOpt2; // 분기 선택지 2

private Long altOpt1TargetDecisionId; // 분기1 연결 대상 결정노드 id

private Long altOpt2TargetDecisionId; // 분기2 연결 대상 결정노드 id

// 헤더 판단 헬퍼
public boolean isHeaderOf(BaseLine baseLine) {
if (baseLine == null) return false;
// header 판단 기준이 따로 있다면 맞게 수정 (여기선 parent == null 가정)
return this.getBaseLine() != null
&& Objects.equals(this.getBaseLine().getId(), baseLine.getId())
&& this.getParent() == null;
}

// 베이스 분기 규칙 검증
public void guardBaseOptionsValid() {
if (fixedChoice == null || fixedChoice.isBlank()) throw new IllegalArgumentException("fixedChoice required");
if (altOpt1 != null && altOpt1.isBlank()) throw new IllegalArgumentException("altOpt1 blank");
if (altOpt2 != null && altOpt2.isBlank()) throw new IllegalArgumentException("altOpt2 blank");
}
}
16 changes: 15 additions & 1 deletion back/src/main/java/com/back/domain/node/entity/DecisionNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,25 @@ public class DecisionNode extends BaseEntity {
@Column(columnDefinition = "TEXT")
private String decision;

private int ageYear; // ← 나이(정수)
private int ageYear;

@Column(columnDefinition = "TEXT")
private String background;

@Column(length = 255)
private String option1; // 선택지1

@Column(length = 255)
private String option2; // 선택지2

@Column(length = 255)
private String option3; // 선택지3

private Integer selectedIndex; // 0..2

private Integer parentOptionIndex; // 부모 결정의 어떤 옵션(0..2)에서 파생됐는지

// 다음 나이 검증
public void guardNextAgeValid(int nextAge) {
if (nextAge <= this.getAgeYear()) {
throw new IllegalArgumentException("ageYear must be greater than parent's ageYear");
Expand Down
Loading