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
15 changes: 15 additions & 0 deletions agent/history/sseoyeon-ssonia/dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
### 작업지시 마감 테스트 수정 (Codex)
- **User Intent**: `./gradlew clean test --refresh-dependencies --no-configuration-cache` 실행 시 `WorkOrderServiceTest.closeWorkOrder_underTargetRequiresRequestFlag`에서 `expected: 8 but was: 0` assertion 실패가 발생하여, 테스트를 서비스 규칙에 맞추는 방식으로 수정 요청.
- **Agent Context**: `data.sql`의 `창원제1공장/A라인`은 5개 공정을 가지지만 테스트가 3번째 공정을 마지막 공정으로 가정해, 서비스의 실제 마지막 공정 기준 집계 결과가 0으로 반환되는 원인을 확인하고 마지막 라우팅까지 실적을 등록하도록 테스트를 수정.
- **Key Decisions**:
- 테스트가 seed 데이터의 고정 공정 인덱스에 의존하지 않고 `lineRoutings.size() - 1`을 마지막 공정으로 사용하도록 변경 — `agent/project/backend.md`의 실제 코드 우선 및 기존 서비스 규칙 준수.
- 앞 공정은 양품 9개, 마지막 공정은 양품 8개와 불량 1개로 등록하도록 반복 처리 — `ProductionExecutionServiceImpl`의 이전 공정 양품 수량 기반 공정 진행 검증 규칙과 일치.
- **Affected Files**: <details><summary>1개 파일</summary>

- **Created**:
- `agent/history/sseoyeon-ssonia/dev.md` — 작업 히스토리 신규 기록
- **Modified**:
- `backend/src/test/java/com/ssafy/demo_app/domain/production/service/WorkOrderServiceTest.java` (+8/-10) — 목표 미달 마감 테스트가 실제 마지막 공정까지 생산 실적을 등록하도록 수정
- **Deleted**:

</details>
11 changes: 9 additions & 2 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,18 @@ dependencies {
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'com.h2database:h2'

testImplementation platform('org.testcontainers:testcontainers-bom:1.21.3')
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:mysql'
testImplementation 'org.testcontainers:jdbc'
testRuntimeOnly 'com.mysql:mysql-connector-j'


implementation project(':lib:web-starter')
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.5'
Expand Down
2 changes: 1 addition & 1 deletion backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ spring:

sql:
init:
mode: always
mode: never

jwt:
secret: ${JWT_SECRET}
Expand Down
74 changes: 37 additions & 37 deletions backend/src/main/resources/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ SELECT
WHEN n <= 20 THEN CONCAT('RM-', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('SM-', LPAD(n - 20, 3, '0'))
ELSE CONCAT('FG-', LPAD(n - 35, 3, '0'))
END,
END,
CASE
WHEN n <= 20 THEN CONCAT('원자재 ', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('반제품 ', LPAD(n - 20, 3, '0'))
ELSE CONCAT('완제품 ', LPAD(n - 35, 3, '0'))
END,
END,
CONCAT(ELT(1 + MOD(n - 1, 5), 'STD', 'PRO', 'ECO', 'HEAVY', 'LIGHT'), '-', LPAD(n, 3, '0')),
ELT(1 + MOD(n - 1, 4), 'ea', 'kg', 'box', 'L'),
CASE WHEN n <= 20 THEN 'RAW' WHEN n <= 35 THEN 'HALF' ELSE 'FG' END,
Expand Down Expand Up @@ -138,16 +138,16 @@ SELECT
CASE WHEN MOD(n, 29) = 0 THEN 'INACTIVE' ELSE 'ACTIVE' END,
TIMESTAMP('2026-01-06 08:00:00') + INTERVAL n DAY
FROM seq
JOIN item_master parent_item
ON parent_item.item_code = CASE
WHEN n <= 30 THEN CONCAT('SM-', LPAD(1 + MOD(n - 1, 15), 3, '0'))
ELSE CONCAT('FG-', LPAD(1 + MOD(n - 31, 15), 3, '0'))
END
JOIN item_master parent_item
ON parent_item.item_code = CASE
WHEN n <= 30 THEN CONCAT('SM-', LPAD(1 + MOD(n - 1, 15), 3, '0'))
ELSE CONCAT('FG-', LPAD(1 + MOD(n - 31, 15), 3, '0'))
END
JOIN item_master child_item
ON child_item.item_code = CASE
WHEN n <= 30 THEN CONCAT('RM-', LPAD(1 + MOD((n * 7) - 1, 20), 3, '0'))
ELSE CONCAT('SM-', LPAD(1 + MOD((n - 31) + (5 * FLOOR((n - 31) / 15)), 15), 3, '0'))
END;
END;

-- ===================================================================
-- 4. 입고 및 재고 도메인 (WMS / INVENTORY)
Expand All @@ -166,12 +166,12 @@ SELECT
DATE('2026-01-01') + INTERVAL n DAY,
TIMESTAMP('2026-02-01 10:00:00') + INTERVAL n DAY
FROM seq
JOIN item_master item
ON item.item_code = CASE
WHEN n <= 20 THEN CONCAT('RM-', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('SM-', LPAD(n - 20, 3, '0'))
ELSE CONCAT('FG-', LPAD(n - 35, 3, '0'))
END
JOIN item_master item
ON item.item_code = CASE
WHEN n <= 20 THEN CONCAT('RM-', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('SM-', LPAD(n - 20, 3, '0'))
ELSE CONCAT('FG-', LPAD(n - 35, 3, '0'))
END
JOIN warehouse_location location
ON location.location_code = CONCAT('WH', LPAD(1 + MOD(n - 1, 5), 2, '0'), '-R', CHAR(65 + MOD(n - 1, 10)), '-C', LPAD(1 + FLOOR((n - 1) / 10), 2, '0'));

Expand All @@ -191,12 +191,12 @@ SELECT
ELT(1 + MOD(n - 1, 3), 'READY', 'COMPLETED', 'STACKED'),
TIMESTAMP('2026-01-10 09:30:00') + INTERVAL n DAY
FROM seq
JOIN item_master item
ON item.item_code = CASE
WHEN n <= 20 THEN CONCAT('RM-', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('SM-', LPAD(n - 20, 3, '0'))
ELSE CONCAT('FG-', LPAD(n - 35, 3, '0'))
END
JOIN item_master item
ON item.item_code = CASE
WHEN n <= 20 THEN CONCAT('RM-', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('SM-', LPAD(n - 20, 3, '0'))
ELSE CONCAT('FG-', LPAD(n - 35, 3, '0'))
END
JOIN partner_master partner
ON partner.partner_code = CONCAT('SUP-', LPAD(1 + MOD(n - 1, 25), 3, '0'))
JOIN warehouse_location location
Expand Down Expand Up @@ -224,8 +224,8 @@ SELECT
TIMESTAMP('2026-01-20 08:00:00') + INTERVAL n DAY,
TIMESTAMP('2026-01-20 08:00:00') + INTERVAL n DAY
FROM seq
JOIN item_master item
ON item.item_code = CASE WHEN n <= 25 THEN CONCAT('SM-', LPAD(1 + MOD(n - 1, 15), 3, '0')) ELSE CONCAT('FG-', LPAD(1 + MOD(n - 26, 15), 3, '0')) END
JOIN item_master item
ON item.item_code = CASE WHEN n <= 25 THEN CONCAT('SM-', LPAD(1 + MOD(n - 1, 15), 3, '0')) ELSE CONCAT('FG-', LPAD(1 + MOD(n - 26, 15), 3, '0')) END
JOIN factory_routing routing
ON routing.factory_name = CONCAT('창원제', 1 + FLOOR((n - 1) / 25), '공장')
AND routing.line_name = CONCAT(CHAR(65 + MOD(FLOOR((n - 1) / 5), 5)), '라인')
Expand Down Expand Up @@ -263,12 +263,12 @@ SELECT
60 + (n * 7),
TIMESTAMP('2026-02-01 13:00:00') + INTERVAL n DAY
FROM seq
JOIN work_order ON work_order.order_no = CONCAT('WO-2026-', LPAD(n, 4, '0'))
JOIN factory_routing routing
JOIN work_order ON work_order.order_no = CONCAT('WO-2026-', LPAD(n, 4, '0'))
JOIN factory_routing routing
ON routing.factory_name = CONCAT('창원제', 1 + FLOOR((n - 1) / 25), '공장')
AND routing.line_name = CONCAT(CHAR(65 + MOD(FLOOR((n - 1) / 5), 5)), '라인')
AND routing.operation_seq = 1 + MOD(n - 1, 5)
JOIN users worker
JOIN users worker
ON worker.employee_no = CONCAT('user', LPAD(1 + MOD(n + 1, 50), 3, '0'));

INSERT IGNORE INTO inventory_transaction_history (
Expand All @@ -292,12 +292,12 @@ SELECT
worker.user_id,
TIMESTAMP('2026-02-10 11:00:00') + INTERVAL n DAY
FROM seq
JOIN item_master item
ON item.item_code = CASE
WHEN n <= 20 THEN CONCAT('RM-', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('SM-', LPAD(n - 20, 3, '0'))
ELSE CONCAT('FG-', LPAD(n - 35, 3, '0'))
END
JOIN item_master item
ON item.item_code = CASE
WHEN n <= 20 THEN CONCAT('RM-', LPAD(n, 3, '0'))
WHEN n <= 35 THEN CONCAT('SM-', LPAD(n - 20, 3, '0'))
ELSE CONCAT('FG-', LPAD(n - 35, 3, '0'))
END
JOIN warehouse_location location
ON location.location_code = CONCAT('WH', LPAD(1 + MOD(n - 1, 5), 2, '0'), '-R', CHAR(65 + MOD(n - 1, 10)), '-C', LPAD(1 + FLOOR((n - 1) / 10), 2, '0'))
LEFT JOIN work_order ON work_order.order_no = CONCAT('WO-2026-', LPAD(n, 4, '0'))
Expand Down Expand Up @@ -375,8 +375,8 @@ SELECT
CASE WHEN MOD(n, 6) IN (3, 4, 5) THEN CONCAT('더미 오류 로그 ', LPAD(n, 3, '0')) ELSE NULL END,
TIMESTAMP('2026-03-10 10:00:00') + INTERVAL n DAY
FROM seq
JOIN users worker
ON worker.employee_no = CONCAT('user', LPAD(1 + MOD(n + 4, 50), 3, '0'));
JOIN users worker
ON worker.employee_no = CONCAT('user', LPAD(1 + MOD(n + 4, 50), 3, '0'));

INSERT IGNORE INTO dynamic_batch_schedule (
schedule_name, cron_expression, query_id, is_active, last_run_at,
Expand All @@ -397,8 +397,8 @@ SELECT
worker.user_id,
TIMESTAMP('2026-03-20 08:00:00') + INTERVAL n DAY
FROM seq
JOIN ai_query_history query_history
ON query_history.conversation_id = CONCAT('conv-2026-', LPAD(1 + FLOOR((n - 1) / 5), 3, '0'))
JOIN ai_query_history query_history
ON query_history.conversation_id = CONCAT('conv-2026-', LPAD(1 + FLOOR((n - 1) / 5), 3, '0'))
AND query_history.natural_question = CONCAT('2026년 재고와 생산 현황을 조회해줘 ', LPAD(n, 3, '0'))
JOIN users worker
ON worker.employee_no = CONCAT('user', LPAD(1 + MOD(n + 5, 50), 3, '0'));
JOIN users worker
ON worker.employee_no = CONCAT('user', LPAD(1 + MOD(n + 5, 50), 3, '0'));
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,7 @@ void closeWorkOrder_underTargetRequiresRequestFlag() {
.setParameter("lineName", "A라인")
.getResultList();
FactoryRouting firstRouting = lineRoutings.get(0);
FactoryRouting secondRouting = lineRoutings.get(1);
FactoryRouting lastRouting = lineRoutings.get(2);
FactoryRouting lastRouting = lineRoutings.get(lineRoutings.size() - 1);
WarehouseLocation location = em.createQuery("select l from WarehouseLocation l", WarehouseLocation.class).getResultList().get(0);
location.setProductionReceiptDefault(true);
ItemMaster item = createItem("WO-FG-CLOSE", "미달마감 완제품", ItemMaster.ItemType.FG);
Expand All @@ -222,14 +221,13 @@ void closeWorkOrder_underTargetRequiresRequestFlag() {

workOrderService.issueMaterials(workOrder.getOrderNo(), worker.getUserId());

productionExecutionService.createExecution(
worker.getUserId(),
new ProductionExecutionCreateRequest(workOrder.getOrderNo(), firstRouting.getRoutingId(), 9, 0, 60)
);
productionExecutionService.createExecution(
worker.getUserId(),
new ProductionExecutionCreateRequest(workOrder.getOrderNo(), secondRouting.getRoutingId(), 9, 0, 60)
);
for (int index = 0; index < lineRoutings.size() - 1; index++) {
FactoryRouting routing = lineRoutings.get(index);
productionExecutionService.createExecution(
worker.getUserId(),
new ProductionExecutionCreateRequest(workOrder.getOrderNo(), routing.getRoutingId(), 9, 0, 60)
);
}
ProductionExecutionCreateRequest request = new ProductionExecutionCreateRequest(workOrder.getOrderNo(), lastRouting.getRoutingId(), 8, 1, 120);
request.setDefectReason("테스트 불량");
ProductionExecutionResponse execution = productionExecutionService.createExecution(worker.getUserId(), request);
Expand Down
14 changes: 8 additions & 6 deletions backend/src/test/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
spring:
datasource:
url: jdbc:h2:mem:ssafy_pjt;MODE=MySQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE
username: sa
password:
driver-class-name: org.h2.Driver
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
url: jdbc:tc:mysql:8.0:///mallo_test
username: test
password: test

jpa:
hibernate:
ddl-auto: create-drop
Expand All @@ -12,10 +13,11 @@ spring:
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.H2Dialect

sql:
init:
mode: always
data-locations: classpath:data.sql

jwt:
secret: testsecretkeyfordemoapplocaltesting1234567890
Expand All @@ -29,4 +31,4 @@ langchain4j:
base-url: https://gms.ssafy.io/gmsapi/api.openai.com/v1
api-key: test-gms-key
model-name: gpt-4o-mini
temperature: 0
temperature: 0
Loading