diff --git a/PIPE_DATABASE_TABLES.md b/PIPE_DATABASE_TABLES.md new file mode 100644 index 0000000..06e35ae --- /dev/null +++ b/PIPE_DATABASE_TABLES.md @@ -0,0 +1,255 @@ +# ๐Ÿ—„๏ธ PIPE ๊ด€๋ฆฌ ์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ” ๊ฐ€์ด๋“œ + +## ๐Ÿ“‹ ํ…Œ์ด๋ธ” ๊ฐœ์š” + +PIPE ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์€ **7๊ฐœ์˜ ์ „์šฉ ํ…Œ์ด๋ธ”**๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ ๊ณ ์œ ํ•œ ์—ญํ• ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. + +--- + +## ๐Ÿ”ง **1. pipe_cutting_plans** +**์šฉ๋„**: PIPE Cutting Plan์˜ ๋‹จ๊ด€ ์ •๋ณด ์ €์žฅ + +### **์ฃผ์š” ์ปฌ๋Ÿผ** +- `job_no`: ์ž‘์—… ๋ฒˆํ˜ธ +- `area`: ๊ตฌ์—ญ ์ •๋ณด (#01, #02 ๋“ฑ) +- `drawing_name`: ๋„๋ฉด๋ช… (P&ID-001) +- `line_no`: ๋ผ์ธ๋ฒˆํ˜ธ (LINE-A-001) +- `material_grade`: ์žฌ์งˆ (A106 GR.B) +- `schedule_spec`: ์Šค์ผ€์ค„ (SCH40, SCH80) +- `nominal_size`: ํ˜ธ์นญ ํฌ๊ธฐ (4", 6") +- `length_mm`: ๊ธธ์ด (mm ๋‹จ์œ„) +- `end_preparation`: ๋๋‹จ ๊ฐ€๊ณต (๋ฌด๊ฐœ์„ , ํ•œ๊ฐœ์„ , ์–‘๊ฐœ์„ ) + +### **์‚ฌ์šฉ ์‹œ์ ** +- Cutting Plan ์ž‘์„ฑ ์‹œ ๋‹จ๊ด€ ์ •๋ณด ์ €์žฅ +- ๊ตฌ์—ญ๋ณ„ ๋„๋ฉด ํ• ๋‹น ์™„๋ฃŒ ํ›„ +- ๋ผ์ธ๋ฒˆํ˜ธ ์ž…๋ ฅ ์™„๋ฃŒ ํ›„ + +--- + +## ๐Ÿ”„ **2. pipe_revision_comparisons** +**์šฉ๋„**: PIPE ๋ฆฌ๋น„์ „ ๋น„๊ต ๊ฒฐ๊ณผ ๋ฐ ํ†ต๊ณ„ ์ €์žฅ + +### **์ฃผ์š” ์ปฌ๋Ÿผ** +- `job_no`: ์ž‘์—… ๋ฒˆํ˜ธ +- `current_file_id`: ํ˜„์žฌ ํŒŒ์ผ ID +- `previous_cutting_plan_id`: ์ด์ „ Cutting Plan ID +- `total_drawings`: ์ „์ฒด ๋„๋ฉด ์ˆ˜ +- `changed_drawings`: ๋ณ€๊ฒฝ๋œ ๋„๋ฉด ์ˆ˜ +- `total_segments`: ์ „์ฒด ๋‹จ๊ด€ ์ˆ˜ +- `added_segments`: ์ถ”๊ฐ€๋œ ๋‹จ๊ด€ ์ˆ˜ +- `removed_segments`: ์‚ญ์ œ๋œ ๋‹จ๊ด€ ์ˆ˜ +- `modified_segments`: ์ˆ˜์ •๋œ ๋‹จ๊ด€ ์ˆ˜ + +### **์‚ฌ์šฉ ์‹œ์ ** +- ์ƒˆ๋กœ์šด BOM ์—…๋กœ๋“œ ์‹œ (Cutting Plan ์ž‘์„ฑ ํ›„) +- ๊ธฐ์กด Cutting Plan๊ณผ ์‹ ๊ทœ BOM ๋น„๊ต ์‹œ +- ๋ฆฌ๋น„์ „ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋ถ„์„ ์‹œ + +--- + +## ๐Ÿ“ **3. pipe_revision_changes** +**์šฉ๋„**: PIPE ๋ฆฌ๋น„์ „ ๋ณ€๊ฒฝ์‚ฌํ•ญ ์ƒ์„ธ ์ •๋ณด ์ €์žฅ + +### **์ฃผ์š” ์ปฌ๋Ÿผ** +- `comparison_id`: ๋น„๊ต ๊ฒฐ๊ณผ ID (pipe_revision_comparisons ์ฐธ์กฐ) +- `drawing_name`: ๋„๋ฉด๋ช… +- `change_type`: ๋ณ€๊ฒฝ ์œ ํ˜• (added, removed, modified, unchanged) +- `old_*`: ์ด์ „ ๋ฐ์ดํ„ฐ (๋ผ์ธ๋ฒˆํ˜ธ, ์žฌ์งˆ, ๊ธธ์ด ๋“ฑ) +- `new_*`: ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ (๋ผ์ธ๋ฒˆํ˜ธ, ์žฌ์งˆ, ๊ธธ์ด ๋“ฑ) +- `change_reason`: ๋ณ€๊ฒฝ ์‚ฌ์œ  + +### **์‚ฌ์šฉ ์‹œ์ ** +- ๋ฆฌ๋น„์ „ ๋น„๊ต ์ˆ˜ํ–‰ ์‹œ ๊ฐ ๋‹จ๊ด€๋ณ„ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๊ธฐ๋ก +- ๋ณ€๊ฒฝ์‚ฌํ•ญ ์ƒ์„ธ ๋ถ„์„ ์‹œ +- ๋ฆฌ๋น„์ „ ์ด๋ ฅ ์ถ”์  ์‹œ + +--- + +## ๐Ÿ“ธ **4. pipe_issue_snapshots** +**์šฉ๋„**: ์ด์Šˆ ๊ด€๋ฆฌ์šฉ ์Šค๋ƒ…์ƒท ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ €์žฅ + +### **์ฃผ์š” ์ปฌ๋Ÿผ** +- `job_no`: ์ž‘์—… ๋ฒˆํ˜ธ +- `snapshot_name`: ์Šค๋ƒ…์ƒท ์ด๋ฆ„ +- `is_active`: ํ™œ์„ฑ ์ƒํƒœ +- `is_locked`: ์ž ๊ธˆ ์ƒํƒœ (์ด์Šˆ ๊ด€๋ฆฌ ์‹œ์ž‘ ์‹œ true) +- `total_segments`: ์ด ๋‹จ๊ด€ ์ˆ˜ +- `total_drawings`: ์ด ๋„๋ฉด ์ˆ˜ +- `created_at`: ์ƒ์„ฑ ์‹œ๊ฐ„ +- `locked_at`: ์ž ๊ธˆ ์‹œ๊ฐ„ + +### **์‚ฌ์šฉ ์‹œ์ ** +- Cutting Plan ํ™•์ • ์‹œ ์ž๋™ ์ƒ์„ฑ +- ์ด์Šˆ ๊ด€๋ฆฌ ์‹œ์ž‘ ์‹œ ์ž ๊ธˆ +- ๋ฆฌ๋น„์ „ ๋ณดํ˜ธ ํ™œ์„ฑํ™” ์‹œ + +--- + +## ๐Ÿ”’ **5. pipe_issue_segments** +**์šฉ๋„**: ์Šค๋ƒ…์ƒท๋œ ๋‹จ๊ด€ ์ •๋ณด ์ €์žฅ (๊ณ ์ • ๋ฐ์ดํ„ฐ) + +### **์ฃผ์š” ์ปฌ๋Ÿผ** +- `snapshot_id`: ์Šค๋ƒ…์ƒท ID (pipe_issue_snapshots ์ฐธ์กฐ) +- `area`: ๊ตฌ์—ญ ์ •๋ณด +- `drawing_name`: ๋„๋ฉด๋ช… +- `line_no`: ๋ผ์ธ๋ฒˆํ˜ธ +- `material_grade`: ์žฌ์งˆ +- `length_mm`: ๊ธธ์ด +- `end_preparation`: ๋๋‹จ ๊ฐ€๊ณต +- `original_cutting_plan_id`: ์›๋ณธ Cutting Plan ID + +### **์‚ฌ์šฉ ์‹œ์ ** +- Cutting Plan ํ™•์ • ์‹œ ํ˜„์žฌ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ +- ์ด์Šˆ ๊ด€๋ฆฌ ํŽ˜์ด์ง€์—์„œ ๊ธฐ์ค€ ๋ฐ์ดํ„ฐ๋กœ ์‚ฌ์šฉ +- ๋ฆฌ๋น„์ „๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ณ ์ •๋œ ๋ฐ์ดํ„ฐ ์ œ๊ณต + +--- + +## ๐Ÿ“‹ **6. pipe_drawing_issues** +**์šฉ๋„**: ๋„๋ฉด ์ „๋ฐ˜์ ์ธ ์ด์Šˆ ์ €์žฅ + +### **์ฃผ์š” ์ปฌ๋Ÿผ** +- `snapshot_id`: ์Šค๋ƒ…์ƒท ID (pipe_issue_snapshots ์ฐธ์กฐ) +- `area`: ๊ตฌ์—ญ ์ •๋ณด +- `drawing_name`: ๋„๋ฉด๋ช… +- `issue_description`: ์ด์Šˆ ์„ค๋ช… (์ž์œ  ํ…์ŠคํŠธ) +- `severity`: ์‹ฌ๊ฐ๋„ (low, medium, high, critical) +- `status`: ์ƒํƒœ (open, in_progress, resolved) +- `resolution_notes`: ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• +- `reported_by`: ๋ณด๊ณ ์ž + +### **์‚ฌ์šฉ ์‹œ์ ** +- ํ˜„์žฅ์—์„œ ๋„๋ฉด ์ „์ฒด์— ๋Œ€ํ•œ ๋ฌธ์ œ ๋ฐœ๊ฒฌ ์‹œ +- ๋ฐฐ๊ด€ ๊ฐ„์„ญ, ๋ผ์šฐํŒ… ๋ณ€๊ฒฝ ๋“ฑ ์ „๋ฐ˜์  ์ด์Šˆ ๊ธฐ๋ก +- ์„ค๊ณ„ ๋ณ€๊ฒฝ ์š”์ฒญ ์‹œ + +### **์˜ˆ์‹œ** +``` +๊ตฌ์—ญ: #01 +๋„๋ฉด: P&ID-001 +์ด์Šˆ: "๋„๋ฉด A ์ „์ฒด์ ์œผ๋กœ ๋ฐฐ๊ด€ ๊ฐ„์„ญ์ด ์‹ฌํ•จ. ํ˜„์žฅ ์—ฌ๊ฑด์ƒ ์ผ๋ถ€ ๋ฃจํŠธ ๋ณ€๊ฒฝ ํ•„์š”" +``` + +--- + +## ๐Ÿ”ง **7. pipe_segment_issues** +**์šฉ๋„**: ๊ฐœ๋ณ„ ๋‹จ๊ด€๋ณ„ ์ด์Šˆ ์ €์žฅ + +### **์ฃผ์š” ์ปฌ๋Ÿผ** +- `snapshot_id`: ์Šค๋ƒ…์ƒท ID (pipe_issue_snapshots ์ฐธ์กฐ) +- `segment_id`: ๋‹จ๊ด€ ID (pipe_issue_segments ์ฐธ์กฐ) +- `issue_description`: ์ด์Šˆ ์„ค๋ช… +- `issue_type`: ์ด์Šˆ ์œ ํ˜• (cutting, installation, material, routing, other) +- `length_change`: ๊ธธ์ด ๋ณ€๊ฒฝ๋Ÿ‰ (+/- mm) +- `new_length`: ์ตœ์ข… ๊ธธ์ด +- `material_change`: ์žฌ์งˆ ๋ณ€๊ฒฝ ์ •๋ณด +- `severity`: ์‹ฌ๊ฐ๋„ +- `status`: ์ƒํƒœ + +### **์‚ฌ์šฉ ์‹œ์ ** +- ๊ฐœ๋ณ„ ๋‹จ๊ด€์—์„œ ๋ฌธ์ œ ๋ฐœ๊ฒฌ ์‹œ +- ํ˜„์žฅ ์ ˆ๋‹จ, ์„ค์น˜ ๋ฌธ์ œ ๋“ฑ ๊ตฌ์ฒด์  ์ด์Šˆ ๊ธฐ๋ก +- ๋‹จ๊ด€๋ณ„ ์ˆ˜์ •์‚ฌํ•ญ ์ถ”์  + +### **์˜ˆ์‹œ** +``` +๊ตฌ์—ญ: #01 +๋„๋ฉด: P&ID-001 +๋ผ์ธ๋ฒˆํ˜ธ: LINE-A-001 +์ด์Šˆ: "์„ค์น˜๊ฐ€ ํž˜๋“ค์–ด 30mm ์ ˆ๋‹จํ•จ" +๊ธธ์ด ๋ณ€๊ฒฝ: -30mm +์ตœ์ข… ๊ธธ์ด: 1470mm +``` + +--- + +## ๐Ÿ”— **ํ…Œ์ด๋ธ” ๊ด€๊ณ„๋„** + +``` +pipe_cutting_plans (๋‹จ๊ด€ ์ •๋ณด) + โ†“ +pipe_revision_comparisons (๋ฆฌ๋น„์ „ ๋น„๊ต) + โ†“ +pipe_revision_changes (๋ณ€๊ฒฝ์‚ฌํ•ญ ์ƒ์„ธ) + +pipe_cutting_plans (๋‹จ๊ด€ ์ •๋ณด) + โ†“ (ํ™•์ • ์‹œ ์Šค๋ƒ…์ƒท) +pipe_issue_snapshots (์Šค๋ƒ…์ƒท ๋ฉ”ํƒ€) + โ†“ +pipe_issue_segments (๊ณ ์ •๋œ ๋‹จ๊ด€ ์ •๋ณด) + โ†“ +pipe_segment_issues (๋‹จ๊ด€๋ณ„ ์ด์Šˆ) + +pipe_issue_snapshots (์Šค๋ƒ…์ƒท ๋ฉ”ํƒ€) + โ†“ +pipe_drawing_issues (๋„๋ฉด๋ณ„ ์ด์Šˆ) +``` + +--- + +## ๐ŸŽฏ **๋ฐ์ดํ„ฐ ํ๋ฆ„** + +### **1. Cutting Plan ์ž‘์„ฑ** +``` +BOM ์—…๋กœ๋“œ โ†’ PIPE ๋ฐ์ดํ„ฐ ์ถ”์ถœ โ†’ pipe_cutting_plans ์ €์žฅ +``` + +### **2. ๋ฆฌ๋น„์ „ ๋ฐœ์ƒ** +``` +์ƒˆ BOM ์—…๋กœ๋“œ โ†’ ๊ธฐ์กด ๋ฐ์ดํ„ฐ ๋น„๊ต โ†’ pipe_revision_comparisons + pipe_revision_changes ์ €์žฅ +``` + +### **3. Cutting Plan ํ™•์ •** +``` +ํ™•์ • ๋ฒ„ํŠผ ํด๋ฆญ โ†’ pipe_issue_snapshots ์ƒ์„ฑ โ†’ pipe_issue_segments ๋ณต์‚ฌ (๊ณ ์ •) +``` + +### **4. ์ด์Šˆ ๊ด€๋ฆฌ** +``` +ํ˜„์žฅ ์ด์Šˆ ๋ฐœ์ƒ โ†’ pipe_drawing_issues (๋„๋ฉด๋ณ„) ๋˜๋Š” pipe_segment_issues (๋‹จ๊ด€๋ณ„) ์ €์žฅ +``` + +--- + +## ๐Ÿ”’ **๋ฆฌ๋น„์ „ ๋ณดํ˜ธ ๋ฉ”์ปค๋‹ˆ์ฆ˜** + +### **ํ™•์ • ์ „** +- `pipe_cutting_plans`: ๋ฆฌ๋น„์ „ ์‹œ ๋ณ€๊ฒฝ๋จ โŒ +- Excel ๋‚ด๋ณด๋‚ด๊ธฐ: ํ˜„์žฌ ๋ฐ์ดํ„ฐ ๊ธฐ์ค€ (๋ณ€๋™ ๊ฐ€๋Šฅ) + +### **ํ™•์ • ํ›„** +- `pipe_issue_snapshots`: ์ž ๊ธˆ ์ƒํƒœ ๐Ÿ”’ +- `pipe_issue_segments`: ๊ณ ์ •๋œ ๋ฐ์ดํ„ฐ โœ… +- Excel ๋‚ด๋ณด๋‚ด๊ธฐ: ์Šค๋ƒ…์ƒท ๋ฐ์ดํ„ฐ ๊ธฐ์ค€ (๊ณ ์ •) +- ์ด์Šˆ ๊ด€๋ฆฌ: ๊ณ ์ •๋œ ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ์ง„ํ–‰ + +--- + +## ๐Ÿ“Š **์ž๋™ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜** + +๋ชจ๋“  PIPE ๊ด€๋ จ ํ…Œ์ด๋ธ”์€ `backend/scripts/analyze_and_fix_schema.py`์— ํฌํ•จ๋˜์–ด ์žˆ์–ด **์ž๋™์œผ๋กœ ์ƒ์„ฑ**๋ฉ๋‹ˆ๋‹ค. + +### **๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํฌํ•จ ์‚ฌํ•ญ** +- โœ… 7๊ฐœ ํ…Œ์ด๋ธ” ์ž๋™ ์ƒ์„ฑ +- โœ… ๋ชจ๋“  ์ธ๋ฑ์Šค ์ž๋™ ์ƒ์„ฑ +- โœ… ์™ธ๋ž˜ํ‚ค ์ œ์•ฝ์กฐ๊ฑด ์„ค์ • +- โœ… ๊ธฐ๋ณธ๊ฐ’ ๋ฐ ์ œ์•ฝ์กฐ๊ฑด ์„ค์ • + +### **๋ฐฐํฌ ์‹œ ์ž๋™ ์‹คํ–‰** +```bash +# Docker ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ ์‹œ ์ž๋™ ์‹คํ–‰ +./start.sh โ†’ analyze_and_fix_schema.py โ†’ PIPE ํ…Œ์ด๋ธ” ์ƒ์„ฑ +``` + +--- + +## ๐ŸŽ‰ **ํ•ต์‹ฌ ์žฅ์ ** + +1. **์™„์ „ํ•œ ๋ฆฌ๋น„์ „ ๋ณดํ˜ธ**: ํ™•์ • ํ›„ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€ +2. **์ฒด๊ณ„์  ์ด์Šˆ ๊ด€๋ฆฌ**: ๋„๋ฉด๋ณ„/๋‹จ๊ด€๋ณ„ ๊ตฌ๋ถ„ ๊ด€๋ฆฌ +3. **์ž๋™ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜**: ๋ฐฐํฌ ์‹œ ์ž๋™ ํ…Œ์ด๋ธ” ์ƒ์„ฑ +4. **์„ฑ๋Šฅ ์ตœ์ ํ™”**: ๋ชจ๋“  ์ฃผ์š” ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค ์„ค์ • +5. **๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ**: ์™ธ๋ž˜ํ‚ค ์ œ์•ฝ์กฐ๊ฑด์œผ๋กœ ๊ด€๊ณ„ ๋ณด์žฅ + +์ด์ œ **์™„๋ฒฝํ•œ PIPE ๊ด€๋ฆฌ ์‹œ์Šคํ…œ**์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ธฐ๋ฐ˜์ด ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๐Ÿš€ diff --git a/PIPE_DEVELOPMENT_GUIDE.md b/PIPE_DEVELOPMENT_GUIDE.md new file mode 100644 index 0000000..7a3acad --- /dev/null +++ b/PIPE_DEVELOPMENT_GUIDE.md @@ -0,0 +1,1123 @@ +# ๐Ÿ”ง PIPE Cutting Plan & ์ด์Šˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ + +## ๐Ÿ“‹ ๋ชฉ์ฐจ +1. [์‹œ์Šคํ…œ ๊ฐœ์š”](#์‹œ์Šคํ…œ-๊ฐœ์š”) +2. [์ „์ฒด ์›Œํฌํ”Œ๋กœ์šฐ](#์ „์ฒด-์›Œํฌํ”Œ๋กœ์šฐ) +3. [๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„](#๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค-์„ค๊ณ„) +4. [ํŽ˜์ด์ง€๋ณ„ ์ƒ์„ธ ์„ค๊ณ„](#ํŽ˜์ด์ง€๋ณ„-์ƒ์„ธ-์„ค๊ณ„) +5. [API ์—”๋“œํฌ์ธํŠธ](#api-์—”๋“œํฌ์ธํŠธ) +6. [๋ฆฌ๋น„์ „ ๊ด€๋ฆฌ ๋กœ์ง](#๋ฆฌ๋น„์ „-๊ด€๋ฆฌ-๋กœ์ง) +7. [๊ฐœ๋ฐœ ์šฐ์„ ์ˆœ์œ„](#๊ฐœ๋ฐœ-์šฐ์„ ์ˆœ์œ„) +8. [๊ธฐ์ˆ  ์Šคํƒ](#๊ธฐ์ˆ -์Šคํƒ) + +--- + +## ๐ŸŽฏ ์‹œ์Šคํ…œ ๊ฐœ์š” + +### **ํ•ต์‹ฌ ๋ชฉ์ ** +- PIPE ์ž์žฌ์˜ ์ฒด๊ณ„์ ์ธ Cutting Plan ๊ด€๋ฆฌ +- ๊ตฌ์—ญ๋ณ„/๋„๋ฉด๋ณ„ ๋‹จ๊ด€ ์ •๋ณด ๊ด€๋ฆฌ +- ๋ฆฌ๋น„์ „ ์‹œ ๋ณ€๊ฒฝ์‚ฌํ•ญ ์ถ”์  ๋ฐ ๋น„๊ต +- ํ˜„์žฅ ์ด์Šˆ ๋ฐ ๋ฌธ์ œ์  ์ฒด๊ณ„์  ๊ธฐ๋ก + +### **์ฃผ์š” ํŠน์ง•** +- **2๋‹จ๊ณ„ ์›Œํฌํ”Œ๋กœ์šฐ**: ๊ตฌ์—ญ ํ• ๋‹น โ†’ ๋ผ์ธ๋ฒˆํ˜ธ ์ž…๋ ฅ +- **์Šค๋งˆํŠธ ๋ฆฌ๋น„์ „**: ๊ธฐ์กด ๋ฐ์ดํ„ฐ์™€ ์‹ ๊ทœ BOM ์ž๋™ ๋น„๊ต +- **ํ˜„์žฅ ์ด์Šˆ ๊ด€๋ฆฌ**: ๋„๋ฉด๋ณ„/๋‹จ๊ด€๋ณ„ ๋ฌธ์ œ์  ์ถ”์  +- **Excel ์—ฐ๋™**: ์™„์ „ํ•œ ๋ฐ์ดํ„ฐ ๋‚ด๋ณด๋‚ด๊ธฐ ์ง€์› + +--- + +## ๐Ÿ”„ ์ „์ฒด ์›Œํฌํ”Œ๋กœ์šฐ + +```mermaid +graph TD + A[BOM ์—…๋กœ๋“œ] --> B{PIPE ๋ฐ์ดํ„ฐ ์ถ”์ถœ} + B --> C[1๋‹จ๊ณ„: ๊ตฌ์—ญ๋ณ„ ๋„๋ฉด ํ• ๋‹น] + C --> D[2๋‹จ๊ณ„: ๋ผ์ธ๋ฒˆํ˜ธ ์ž…๋ ฅ] + D --> E[3๋‹จ๊ณ„: ๋‹จ๊ด€ ์ •๋ณด ํ™•์ธ] + E --> F[Cutting Plan ์ €์žฅ] + + F --> G{์ƒˆ๋กœ์šด ๋ฆฌ๋น„์ „?} + G -->|Yes| H[4๋‹จ๊ณ„: ๋ฆฌ๋น„์ „ ๋น„๊ต] + G -->|No| I[์ด์Šˆ ๊ด€๋ฆฌ ํŽ˜์ด์ง€] + + H --> J[๋ณ€๊ฒฝ์‚ฌํ•ญ ํ™•์ธ/์ˆ˜์ •] + J --> K[5๋‹จ๊ณ„: ๋ณ€๊ฒฝ ๋„๋ฉด ์š”์•ฝ] + K --> L[ํŒŒ์ดํ”„ ๊ตฌ๋งค๋Ÿ‰ ์žฌ๊ณ„์‚ฐ] + L --> I + + I --> M[ํ˜„์žฅ ์ด์Šˆ ์ž…๋ ฅ] + M --> N[Excel ๋‚ด๋ณด๋‚ด๊ธฐ] +``` + +--- + +## ๐Ÿ—„๏ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„ + +### **1. pipe_cutting_plans** (๋‹จ๊ด€ ์ •๋ณด) +```sql +CREATE TABLE pipe_cutting_plans ( + id SERIAL PRIMARY KEY, + job_no VARCHAR(50) NOT NULL, + file_id INTEGER REFERENCES files(id), + + -- ๊ธฐ๋ณธ ์ •๋ณด + area VARCHAR(10), -- #01, #02 ๋“ฑ + drawing_name VARCHAR(100) NOT NULL, -- P&ID-001 + line_no VARCHAR(50) NOT NULL, -- LINE-A-001 + + -- ํŒŒ์ดํ”„ ์ •๋ณด + material_grade VARCHAR(50), -- A106 GR.B + schedule_spec VARCHAR(20), -- SCH40, SCH80 + nominal_size VARCHAR(50), -- 4", 6", 8" + length_mm DECIMAL(10,3) NOT NULL, -- 1500.0 + + -- ๋๋‹จ ์ •๋ณด + end_preparation VARCHAR(20), -- ๋ฌด๊ฐœ์„ , ํ•œ๊ฐœ์„ , ์–‘๊ฐœ์„  + + -- ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + created_by VARCHAR(100), + + -- ์ธ๋ฑ์Šค + INDEX idx_cutting_plans_job (job_no), + INDEX idx_cutting_plans_area_drawing (area, drawing_name), + INDEX idx_cutting_plans_material (material_grade, nominal_size) +); +``` + +### **2. pipe_revision_comparisons** (๋ฆฌ๋น„์ „ ๋น„๊ต) +```sql +CREATE TABLE pipe_revision_comparisons ( + id SERIAL PRIMARY KEY, + job_no VARCHAR(50) NOT NULL, + current_file_id INTEGER REFERENCES files(id), + previous_cutting_plan_id INTEGER REFERENCES pipe_cutting_plans(id), + + -- ๋น„๊ต ๊ฒฐ๊ณผ + comparison_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + total_drawings INTEGER, -- ์ „์ฒด ๋„๋ฉด ์ˆ˜ + changed_drawings INTEGER, -- ๋ณ€๊ฒฝ๋œ ๋„๋ฉด ์ˆ˜ + unchanged_drawings INTEGER, -- ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๋„๋ฉด ์ˆ˜ + + -- ๋‹จ๊ด€ ๋ณ€๊ฒฝ ํ†ต๊ณ„ + total_segments INTEGER, -- ์ „์ฒด ๋‹จ๊ด€ ์ˆ˜ + added_segments INTEGER, -- ์ถ”๊ฐ€๋œ ๋‹จ๊ด€ + removed_segments INTEGER, -- ์‚ญ์ œ๋œ ๋‹จ๊ด€ + modified_segments INTEGER, -- ์ˆ˜์ •๋œ ๋‹จ๊ด€ + unchanged_segments INTEGER, -- ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๋‹จ๊ด€ + + -- ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ + created_by VARCHAR(100), + is_applied BOOLEAN DEFAULT FALSE, + applied_at TIMESTAMP, + applied_by VARCHAR(100) +); +``` + +### **3. pipe_revision_changes** (๋ฆฌ๋น„์ „ ๋ณ€๊ฒฝ ์ƒ์„ธ) +```sql +CREATE TABLE pipe_revision_changes ( + id SERIAL PRIMARY KEY, + comparison_id INTEGER REFERENCES pipe_revision_comparisons(id), + + -- ๋ณ€๊ฒฝ ์ •๋ณด + drawing_name VARCHAR(100) NOT NULL, + change_type VARCHAR(20) NOT NULL, -- 'added', 'removed', 'modified', 'unchanged' + + -- ์ด์ „ ๋ฐ์ดํ„ฐ (์ˆ˜์ •/์‚ญ์ œ์˜ ๊ฒฝ์šฐ) + old_line_no VARCHAR(50), + old_material_grade VARCHAR(50), + old_schedule_spec VARCHAR(20), + old_nominal_size VARCHAR(50), + old_length_mm DECIMAL(10,3), + old_end_preparation VARCHAR(20), + + -- ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ (์ถ”๊ฐ€/์ˆ˜์ •์˜ ๊ฒฝ์šฐ) + new_line_no VARCHAR(50), + new_material_grade VARCHAR(50), + new_schedule_spec VARCHAR(20), + new_nominal_size VARCHAR(50), + new_length_mm DECIMAL(10,3), + new_end_preparation VARCHAR(20), + + -- ๋ณ€๊ฒฝ ์‚ฌ์œ  + change_reason TEXT, + + -- ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +### **4. pipe_drawing_issues** (๋„๋ฉด ์ „๋ฐ˜ ์ด์Šˆ) +```sql +CREATE TABLE pipe_drawing_issues ( + id SERIAL PRIMARY KEY, + job_no VARCHAR(50) NOT NULL, + area VARCHAR(10) NOT NULL, + drawing_name VARCHAR(100) NOT NULL, + + -- ์ด์Šˆ ์ •๋ณด + issue_description TEXT NOT NULL, + severity VARCHAR(20) DEFAULT 'medium', -- 'low', 'medium', 'high', 'critical' + status VARCHAR(20) DEFAULT 'open', -- 'open', 'in_progress', 'resolved' + + -- ํ•ด๊ฒฐ ์ •๋ณด + resolution_notes TEXT, + resolved_by VARCHAR(100), + resolved_at TIMESTAMP, + + -- ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ + reported_by VARCHAR(100), + reported_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +### **5. pipe_segment_issues** (๋‹จ๊ด€๋ณ„ ์ด์Šˆ) +```sql +CREATE TABLE pipe_segment_issues ( + id SERIAL PRIMARY KEY, + job_no VARCHAR(50) NOT NULL, + area VARCHAR(10) NOT NULL, + drawing_name VARCHAR(100) NOT NULL, + line_no VARCHAR(50) NOT NULL, + + -- ์›๋ณธ ์ •๋ณด + original_material_info VARCHAR(100), + original_length DECIMAL(10,3), + + -- ์ด์Šˆ ์ •๋ณด + issue_description TEXT NOT NULL, + issue_type VARCHAR(50), -- 'cutting', 'installation', 'material', 'routing', 'other' + + -- ๋ณ€๊ฒฝ์‚ฌํ•ญ (์žˆ๋Š” ๊ฒฝ์šฐ) + length_change DECIMAL(10,3), -- +/- ๋ณ€๊ฒฝ๋Ÿ‰ + new_length DECIMAL(10,3), -- ์ตœ์ข… ๊ธธ์ด + material_change VARCHAR(100), -- ์žฌ์งˆ ๋ณ€๊ฒฝ ์ •๋ณด + + -- ์ด์Šˆ ๊ด€๋ฆฌ + severity VARCHAR(20) DEFAULT 'medium', + status VARCHAR(20) DEFAULT 'open', + + -- ํ•ด๊ฒฐ ์ •๋ณด + resolution_notes TEXT, + resolved_by VARCHAR(100), + resolved_at TIMESTAMP, + + -- ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ + cutting_plan_id INTEGER REFERENCES pipe_cutting_plans(id), + reported_by VARCHAR(100), + reported_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +--- + +## ๐Ÿ“„ ํŽ˜์ด์ง€๋ณ„ ์ƒ์„ธ ์„ค๊ณ„ + +### **1. PIPE Cutting Plan ๋ฉ”์ธ ํŽ˜์ด์ง€** +**ํŒŒ์ผ**: `frontend/src/pages/revision/PipeCuttingPlanPage.jsx` + +#### **1๋‹จ๊ณ„: ๊ตฌ์—ญ๋ณ„ ๋„๋ฉด ํ• ๋‹น** +```javascript +// UI ๊ตฌ์กฐ +
+

๐Ÿ“‚ 1๋‹จ๊ณ„: ๊ตฌ์—ญ๋ณ„ ๋„๋ฉด ํ• ๋‹น

+ + {/* ๊ตฌ์—ญ ์ž…๋ ฅ */} +
+ setCurrentArea(e.target.value)} + /> + +
+ + {/* ๋„๋ฉด ์„ ํƒ */} +
+

๐Ÿ“‹ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋„๋ฉด ๋ชฉ๋ก

+ {availableDrawings.map(drawing => ( + + ))} +
+ + {/* ๊ตฌ์—ญ๋ณ„ ํ• ๋‹น ํ˜„ํ™ฉ */} +
+ {areas.map(area => ( +
+

{area.name}

+
+ {area.drawings.map(drawing => ( + + {drawing} + + + ))} +
+
+ ))} +
+ + +
+``` + +#### **2๋‹จ๊ณ„: ๋ผ์ธ๋ฒˆํ˜ธ ์ž…๋ ฅ** +```javascript +
+

๐Ÿ”ข 2๋‹จ๊ณ„: ๋ผ์ธ๋ฒˆํ˜ธ ์ž…๋ ฅ

+ + {/* ๊ตฌ์—ญ/๋„๋ฉด ์„ ํƒ */} +
+ + + +
+ + {/* ๋‹จ๊ด€ ์ •๋ณด ํ…Œ์ด๋ธ” */} +
+ + + + + + + + + + + + + {pipeSegments.map((segment, index) => ( + + + + + + + + + ))} + +
๋ผ์ธ๋ฒˆํ˜ธ์žฌ์งˆ๊ทœ๊ฒฉ๊ธธ์ด(mm)๋๋‹จ๊ฐ€๊ณต์•ก์…˜
+ updateSegmentLineNo(index, e.target.value)} + placeholder="LINE-A-001" + /> + {segment.material_grade}{segment.schedule_spec} {segment.nominal_size}{segment.length_mm} + + + +
+
+ +
+ + +
+
+``` + +#### **3๋‹จ๊ณ„: ๋‹จ๊ด€ ์ •๋ณด ํ™•์ธ** +```javascript +
+

โœ… 3๋‹จ๊ณ„: ๋‹จ๊ด€ ์ •๋ณด ํ™•์ธ

+ + {/* ์ „์ฒด ์š”์•ฝ */} +
+
+

๐Ÿ“Š ์ „์ฒด ํ˜„ํ™ฉ

+

์ด ๊ตฌ์—ญ: {areas.length}๊ฐœ

+

์ด ๋„๋ฉด: {totalDrawings}๊ฐœ

+

์ด ๋‹จ๊ด€: {totalSegments}๊ฐœ

+
+
+ + {/* ๊ตฌ์—ญ๋ณ„ ์ƒ์„ธ */} + {areas.map(area => ( +
+

๐Ÿ—๏ธ {area.name} ๊ตฌ์—ญ

+ {area.drawings.map(drawing => ( +
+
๐Ÿ“‹ {drawing}
+ + + + + + + + + + + {getSegmentsForDrawing(area.name, drawing).map(segment => ( + + + + + + + ))} + +
๋ผ์ธ๋ฒˆํ˜ธ์žฌ์งˆ/๊ทœ๊ฒฉ๊ธธ์ด๋๋‹จ๊ฐ€๊ณต
{segment.line_no}{segment.material_grade} {segment.schedule_spec} {segment.nominal_size}{segment.length_mm}mm{segment.end_preparation}
+
+ ))} +
+ ))} + +
+ + +
+
+``` + +### **2. ๋ฆฌ๋น„์ „ ๋น„๊ต ํŽ˜์ด์ง€** +**ํŒŒ์ผ**: `frontend/src/pages/revision/PipeRevisionComparisonPage.jsx` + +#### **4๋‹จ๊ณ„: ๋ฆฌ๋น„์ „ ๋น„๊ต** +```javascript +
+

๐Ÿ”„ 4๋‹จ๊ณ„: ๋ฆฌ๋น„์ „ ๋น„๊ต

+ + {/* ๋น„๊ต ์š”์•ฝ */} +
+
+
+

โž• ์ถ”๊ฐ€๋œ ๋‹จ๊ด€

+ {comparisonResult.added_segments} +
+
+

โž– ์‚ญ์ œ๋œ ๋‹จ๊ด€

+ {comparisonResult.removed_segments} +
+
+

๐Ÿ”ง ์ˆ˜์ •๋œ ๋‹จ๊ด€

+ {comparisonResult.modified_segments} +
+
+

โœ… ๋ณ€๊ฒฝ์—†์Œ

+ {comparisonResult.unchanged_segments} +
+
+
+ + {/* ๋ณ€๊ฒฝ๋œ ๋„๋ฉด๋งŒ ํ‘œ์‹œ */} +
+

๐Ÿ“‹ ๋ณ€๊ฒฝ๋œ ๋„๋ฉด ๋ชฉ๋ก

+ {changedDrawings.map(drawing => ( +
+
๐Ÿ“„ {drawing.name}
+ + + + + + + + + + + + + {drawing.segments.map(segment => ( + + + + + + + + + ))} + +
์ƒํƒœ๋ผ์ธ๋ฒˆํ˜ธ์žฌ์งˆ/๊ทœ๊ฒฉ๊ธธ์ด๋๋‹จ๊ฐ€๊ณต๋ณ€๊ฒฝ์‚ฌํ•ญ
+ + {getStatusLabel(segment.change_type)} + + {segment.line_no}{segment.material_info}{segment.length_mm}mm{segment.end_preparation} + {segment.change_type !== 'unchanged' && ( +
+ {segment.changes.map(change => ( +
+ {change.field}: + {change.old_value} โ†’ {change.new_value} +
+ ))} +
+ )} +
+
+ ))} +
+ +
+ + +
+
+``` + +#### **5๋‹จ๊ณ„: ๋ณ€๊ฒฝ ๋„๋ฉด ์š”์•ฝ** +```javascript +
+

๐Ÿ“Š 5๋‹จ๊ณ„: ๋ณ€๊ฒฝ ๋„๋ฉด ์š”์•ฝ

+ + {/* ๋ณ€๊ฒฝ ๋„๋ฉด๋งŒ ์ง‘์ค‘ ํ‘œ์‹œ */} +
+

โš ๏ธ ๊ฒ€ํ† ๊ฐ€ ํ•„์š”ํ•œ ๋„๋ฉด๋“ค

+ {changedDrawingsOnly.map(drawing => ( +
+
+
๐Ÿ“„ {drawing.name}
+
+ +{drawing.added_count} + -{drawing.removed_count} + ~{drawing.modified_count} +
+
+ +
+
๐Ÿ“ˆ ํŒŒ์ดํ”„ ๊ตฌ๋งค๋Ÿ‰ ์˜ํ–ฅ
+ {drawing.material_impacts.map(impact => ( +
+ {impact.material} + + {impact.length_change > 0 ? '+' : ''}{impact.length_change}m + + + ({impact.percentage_change > 0 ? '+' : ''}{impact.percentage_change}%) + +
+ ))} +
+
+ ))} +
+ + {/* ์ „์ฒด ๊ตฌ๋งค๋Ÿ‰ ์žฌ๊ณ„์‚ฐ */} +
+

๐Ÿ’ฐ ํŒŒ์ดํ”„ ๊ตฌ๋งค๋Ÿ‰ ์žฌ๊ณ„์‚ฐ

+
+
+
+
์ด์ „ ๊ตฌ๋งค ๊ณ„ํš
+ {previousPurchasePlan.map(item => ( +
+ {item.material} + {item.total_length}m +
+ ))} +
+
+
์‹ ๊ทœ ๊ตฌ๋งค ๊ณ„ํš
+ {newPurchasePlan.map(item => ( +
+ {item.material} + {item.total_length}m + {item.additional_needed > 0 && ( + + (+{item.additional_needed}m ์ถ”๊ฐ€ ํ•„์š”) + + )} +
+ ))} +
+
+
+
+ +
+ + +
+
+``` + +### **3. ๋‹จ๊ด€ ์ด์Šˆ ๊ด€๋ฆฌ ํŽ˜์ด์ง€** +**ํŒŒ์ผ**: `frontend/src/pages/PipeIssueManagementPage.jsx` + +```javascript +
+
+

๐Ÿ› ๏ธ ๋‹จ๊ด€ ์ด์Šˆ ๊ด€๋ฆฌ

+

ํ˜„์žฅ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํŒŒ์ดํ”„ ๊ด€๋ จ ์ด์Šˆ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค

+
+ + {/* ๊ฒ€์ƒ‰/ํ•„ํ„ฐ ์„น์…˜ */} +
+
+ + + + + +
+
+ + {/* ๋„๋ฉด ์ „๋ฐ˜ ์ด์Šˆ ์„น์…˜ */} +
+

๐Ÿ“‹ ๋„๋ฉด ์ „๋ฐ˜ ์ด์Šˆ

+ + {/* ๊ธฐ์กด ์ด์Šˆ ๋ชฉ๋ก */} +
+ {drawingIssues.map(issue => ( +
+
+ + {issue.severity.toUpperCase()} + + + {issue.status.toUpperCase()} + +
+
+

{issue.issue_description}

+
+ ๋ณด๊ณ ์ž: {issue.reported_by} | {issue.reported_at} +
+
+
+ + + {issue.status === 'open' && ( + + )} +
+
+ ))} +
+ + {/* ์ƒˆ ์ด์Šˆ ์ถ”๊ฐ€ */} +
+

โž• ์ƒˆ ๋„๋ฉด ์ด์Šˆ ์ถ”๊ฐ€

+