๐Ÿค– AI ์ž๋™๋ฐœ์ฃผ์‹œ์Šคํ…œ ํ†ตํ•ฉ ๊ธฐํš์„œ

๋ฒ„์ „: 1.0
์ž‘์„ฑ์ผ: 2026-03-06
์ž‘์„ฑ์ž: ์šฉ๋ฆผ (with ์•ฝ์‚ฌ๋‹˜)
์ƒํƒœ: ๊ธฐํš ์™„๋ฃŒ, ๊ฐœ๋ฐœ ๋Œ€๊ธฐ


๐Ÿ“‹ ๋ชฉ์ฐจ

  1. ๋น„์ „ ๋ฐ ๋ชฉํ‘œ
  2. ํ˜„์žฌ ๊ตฌํ˜„ ํ˜„ํ™ฉ
  3. ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜
  4. AI ํ•™์Šต ์š”์†Œ
  5. ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์„ค๊ณ„
  6. ๋ฐ์ดํ„ฐ ๋ชจ๋ธ
  7. API ์„ค๊ณ„
  8. ์ž๋™ํ™” ๋ ˆ๋ฒจ
  9. ์•Œ๋ฆผ ์‹œ์Šคํ…œ
  10. ๊ฐœ๋ฐœ ๋กœ๋“œ๋งต
  11. ์„ฑ๊ณต ์ง€ํ‘œ

1. ๋น„์ „ ๋ฐ ๋ชฉํ‘œ

๐ŸŽฏ ๋น„์ „

"์•ฝ์‚ฌ๋‹˜์ด ์ฃผ๋ฌธ์— ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์•„๋„ ๋˜๋Š” ์•ฝ๊ตญ"

AI๊ฐ€ ์‚ฌ์šฉ๋Ÿ‰, ์žฌ๊ณ , ๋„๋งค์ƒ ์ƒํ™ฉ, ๊ณผ๊ฑฐ ์ฃผ๋ฌธ ํŒจํ„ด์„ ํ•™์Šตํ•˜์—ฌ:
- ์–ธ์ œ ์ฃผ๋ฌธํ• ์ง€
- ์–ด๋А ๋„๋งค์ƒ์— ์ฃผ๋ฌธํ• ์ง€
- ์–ด๋–ค ๊ทœ๊ฒฉ์œผ๋กœ ์ฃผ๋ฌธํ• ์ง€
- ์–ผ๋งˆ๋‚˜ ์ฃผ๋ฌธํ• ์ง€

๋ชจ๋“  ๊ฒƒ์„ ์ž๋™์œผ๋กœ ๊ฒฐ์ •ํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐ€์น˜

AS-IS TO-BE
๋งค์ผ ์žฌ๊ณ  ํ™•์ธ AI๊ฐ€ ์ž๋™ ๋ชจ๋‹ˆํ„ฐ๋ง
์ˆ˜๋™์œผ๋กœ ๋„๋งค์ƒ ์„ ํƒ AI๊ฐ€ ์ตœ์  ๋„๋งค์ƒ ์„ ํƒ
๊ฒฝํ—˜์— ์˜์กดํ•œ ์ฃผ๋ฌธ๋Ÿ‰ ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ตœ์  ์ฃผ๋ฌธ๋Ÿ‰
์ฃผ๋ฌธ ๋ˆ„๋ฝ/์ง€์—ฐ ๋ฐœ์ƒ ์„ ์ œ์  ์ž๋™ ์ฃผ๋ฌธ
๋ฐฐ์†ก ๋งˆ๊ฐ ๋†“์นจ ๋งˆ๊ฐ์‹œ๊ฐ„ ์ž๋™ ์•Œ๋ฆผ

ํ•ต์‹ฌ ์›์น™

"AI๋Š” ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์•ฝ์‚ฌ๋‹˜์˜ ๋ฐฉ์‹์„ ์ž๋™ํ™”ํ•ฉ๋‹ˆ๋‹ค."


2. ํ˜„์žฌ ๊ตฌํ˜„ ํ˜„ํ™ฉ

2.1 ๋„๋งค์ƒ API (โœ… ์™„๋ฃŒ)

๋„๋งค์ƒ ์žฌ๊ณ ์กฐํšŒ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ฃผ๋ฌธ ์ทจ์†Œ/๋ณต์› ์ž”๊ณ  ์›”๋งค์ถœ
์ง€์˜ค์˜ โœ… โœ… โœ… ํ™•์ •ํฌํ•จ โœ… โœ… โœ…
์ˆ˜์ธ์•ฝํ’ˆ โœ… โœ… โœ… โœ… โœ… โœ…
๋ฐฑ์ œ์•ฝํ’ˆ โœ… โœ… โœ… โณ โœ… โœ…

2.2 ์ฃผ๋ฌธ DB (โœ… ์™„๋ฃŒ)

orders.db
โ”œโ”€โ”€ wholesalers        # ๋„๋งค์ƒ ๋งˆ์Šคํ„ฐ
โ”œโ”€โ”€ orders             # ์ฃผ๋ฌธ ํ—ค๋”
โ”œโ”€โ”€ order_items        # ์ฃผ๋ฌธ ํ’ˆ๋ชฉ
โ”œโ”€โ”€ order_logs         # ์ฃผ๋ฌธ ์ด๋ ฅ
โ”œโ”€โ”€ order_context      # AI ํ•™์Šต์šฉ ์ปจํ…์ŠคํŠธ โญ
โ”œโ”€โ”€ daily_usage        # ์ผ๋ณ„ ์‚ฌ์šฉ๋Ÿ‰ ์‹œ๊ณ„์—ด
โ””โ”€โ”€ order_patterns     # AI ๋ถ„์„ ๊ฒฐ๊ณผ

2.3 ๋ฐฐ์†ก ์Šค์ผ€์ค„ (โœ… ํ™•์ธ ์™„๋ฃŒ)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๋„๋งค์ƒ   โ”‚ ๋ฐฐ์†ก     โ”‚ ์ฃผ๋ฌธ ๋งˆ๊ฐ    โ”‚ ๋„์ฐฉ ์˜ˆ์ •    โ”‚ ๋น„๊ณ      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ์ง€์˜ค์˜   โ”‚ ์˜ค์ „     โ”‚ 10:00        โ”‚ 11:30        โ”‚ ๋‹น์ผ     โ”‚
โ”‚          โ”‚ ์˜คํ›„     โ”‚ 13:00        โ”‚ 15:00        โ”‚ ๋‹น์ผ     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ์ˆ˜์ธ     โ”‚ ์˜คํ›„     โ”‚ 13:00        โ”‚ 14:30        โ”‚ ๋‹น์ผ     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ๋ฐฑ์ œ     โ”‚ ์ต์ผ     โ”‚ 16:00        โ”‚ ๋‹ค์Œ๋‚  15:00 โ”‚ โš ๏ธ ์ต์ผ  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

2.4 UI (โœ… ์™„๋ฃŒ)


3. ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

์ „์ฒด ํ๋ฆ„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     AI ์ž๋™๋ฐœ์ฃผ์‹œ์Šคํ…œ                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ–ผ                       โ–ผ                       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘   โ”‚      โ”‚   AI ๋ถ„์„     โ”‚      โ”‚   ์ž๋™ ์‹คํ–‰    โ”‚
โ”‚               โ”‚      โ”‚               โ”‚      โ”‚               โ”‚
โ”‚ โ€ข POS ํŒ๋งค    โ”‚โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚ โ€ข ์‚ฌ์šฉ๋Ÿ‰ ์˜ˆ์ธก  โ”‚โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚ โ€ข ๋„๋งค์ƒ API  โ”‚
โ”‚ โ€ข ์ฒ˜๋ฐฉ์ „ ์กฐ์ œ  โ”‚      โ”‚ โ€ข ์žฌ๊ณ  ๋ถ„์„   โ”‚      โ”‚ โ€ข ์ฃผ๋ฌธ ์‹คํ–‰   โ”‚
โ”‚ โ€ข ํ˜„์žฌ ์žฌ๊ณ    โ”‚      โ”‚ โ€ข ์ฃผ๋ฌธ ์ถ”์ฒœ   โ”‚      โ”‚ โ€ข ๊ฒฐ๊ณผ ํ”ผ๋“œ๋ฐฑ  โ”‚
โ”‚ โ€ข ๋„๋งค์ƒ ์žฌ๊ณ   โ”‚      โ”‚ โ€ข ํŒจํ„ด ํ•™์Šต   โ”‚      โ”‚               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                       โ”‚                       โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚    ํ•™์Šต ๋ฃจํ”„       โ”‚
                    โ”‚                   โ”‚
                    โ”‚  ์ฃผ๋ฌธ ๊ฒฐ๊ณผ ํ‰๊ฐ€    โ”‚
                    โ”‚  โ†’ ๋ชจ๋ธ ์—…๋ฐ์ดํŠธ   โ”‚
                    โ”‚  โ†’ ์ „๋žต ์กฐ์ •      โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚  โ”‚  PIT3000   โ”‚  โ”‚   SQLite   โ”‚  โ”‚  ์ง€์˜ค์˜    โ”‚  โ”‚   ์ˆ˜์ธ     โ”‚ โ”‚
โ”‚  โ”‚  (MSSQL)   โ”‚  โ”‚  Orders DB โ”‚  โ”‚   API      โ”‚  โ”‚   API      โ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                 โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         ์„œ๋น„์Šค ๋ ˆ์ด์–ด                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  InventorySync  โ”‚  โ”‚  UsageAnalyzer  โ”‚  โ”‚  OrderExecutor  โ”‚  โ”‚
โ”‚  โ”‚  ์žฌ๊ณ  ๋™๊ธฐํ™”     โ”‚  โ”‚  ์‚ฌ์šฉ๋Ÿ‰ ๋ถ„์„    โ”‚  โ”‚  ์ฃผ๋ฌธ ์‹คํ–‰      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  AIPredictor    โ”‚  โ”‚  AIOptimizer    โ”‚  โ”‚  AILearner      โ”‚  โ”‚
โ”‚  โ”‚  ์ˆ˜์š” ์˜ˆ์ธก      โ”‚  โ”‚  ๊ทœ๊ฒฉ/๋„๋งค์ƒ    โ”‚  โ”‚  ํŒจํ„ด ํ•™์Šต      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                 โ”‚
                                 โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         ์ธํ„ฐํŽ˜์ด์Šค ๋ ˆ์ด์–ด                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚   ์›น ๋Œ€์‹œ๋ณด๋“œ    โ”‚  โ”‚  ์•Œ๋ฆผ ์‹œ์Šคํ…œ    โ”‚  โ”‚   ๊ด€๋ฆฌ์ž ์•ฑ     โ”‚  โ”‚
โ”‚  โ”‚  ์žฌ๊ณ /์ฃผ๋ฌธ/AI   โ”‚  โ”‚  ์นดํ†ก/ํ…”๋ ˆ๊ทธ๋žจ  โ”‚  โ”‚  ์ˆ˜๋™ ๊ฐœ์ž…      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

4. AI ํ•™์Šต ์š”์†Œ

4.1 ๊ทœ๊ฒฉ ์„ ํƒ ํ•™์Šต (Spec Selection)

โš ๏ธ ์ค‘์š”: ์ „๋ฌธ์˜์•ฝํ’ˆ(ETC)์€ ๋ณดํ—˜์•ฝ๊ฐ€ ๊ณ ์ •!
- 30T๋“  300T๋“  1T๋‹น ๊ฐ€๊ฒฉ ๋™์ผ
- ๋‹จ๊ฐ€ ํšจ์œจ์€ OTC/๋น„๊ธ‰์—ฌ์—์„œ๋งŒ ์˜๋ฏธ ์žˆ์Œ

ํ•™์Šต ๋ฐ์ดํ„ฐ:
- ์•ฝํ’ˆ๋ณ„ ๊ณผ๊ฑฐ ์ฃผ๋ฌธ ๊ทœ๊ฒฉ (30T, 100T, 300T, 500T)
- ๊ฐ ๊ทœ๊ฒฉ ์„ ํƒ ์‹œ์ ์˜ ์žฌ๊ณ /์‚ฌ์šฉ๋Ÿ‰
- ์„ ํƒ ๊ฒฐ๊ณผ (๋‚จ์€ ์žฌ๊ณ , ๋‹ค์Œ ์ฃผ๋ฌธ๊นŒ์ง€ ๊ธฐ๊ฐ„)
- ๋„๋งค์ƒ๋ณ„ ๊ทœ๊ฒฉ ์žฌ๊ณ  ํ˜„ํ™ฉ

ํ•™์Šต ๋ชฉํ‘œ:
- ์‚ฌ์šฉ๋Ÿ‰ ๋Œ€๋น„ ์ตœ์  ๊ทœ๊ฒฉ ์˜ˆ์ธก
- ์žฌ๊ณ  ์žˆ๋Š” ๊ทœ๊ฒฉ ์šฐ์„  ์„ ํƒ
- ๋‚ญ๋น„ ์ตœ์†Œํ™” (์œ ํ†ต๊ธฐํ•œ ๊ณ ๋ ค)
- ์†Œ๋ถ„ vs ๋Œ€์šฉ๋Ÿ‰ ์„ ํ˜ธ๋„ ํŒŒ์•…

์˜ˆ์‹œ ์‹œ๋‚˜๋ฆฌ์˜ค:
| ํ•„์š”๋Ÿ‰ | ๊ฐ€๋Šฅ ๊ทœ๊ฒฉ | AI ์„ ํƒ | ์ด์œ  |
|--------|-----------|---------|------|
| 280T | 30T(์žฌ๊ณ 50), 100T(ํ’ˆ์ ˆ), 300T(์žฌ๊ณ 10) | 30T x 10 | 100T ํ’ˆ์ ˆ, ์†Œ๋ถ„ ์„ ํ˜ธ |
| 800T | 30T(์žฌ๊ณ 100), 300T(์žฌ๊ณ 5) | 300T x 3 | ๋Œ€๋Ÿ‰, ์žฌ๊ณ  ์ถฉ๋ถ„ |
| 50T | 30T(์žฌ๊ณ 20), 100T(์žฌ๊ณ 10) | 30T x 2 | ์†Œ๋Ÿ‰, ๋น ๋ฅธ ํšŒ์ „ |

4.2 ์žฌ๊ณ  ์ „๋žต ํ•™์Šต (Inventory Strategy)

ํ•™์Šต ๋ฐ์ดํ„ฐ:
- ์ฃผ๋ฌธ ์‹œ์ ์˜ ์žฌ๊ณ  ์ˆ˜์ค€
- ์žฌ๊ณ  ์†Œ์ง„๊นŒ์ง€ ๋‚จ์€ ์ผ์ˆ˜
- ์ฃผ๋ฌธ ํ›„ ์ž…๊ณ ๊นŒ์ง€ ๋ฆฌ๋“œํƒ€์ž„
- ํ’ˆ์ ˆ ๋ฐœ์ƒ ์ด๋ ฅ

ํ•™์Šต ๋ชฉํ‘œ:
- ์•ฝ์‚ฌ๋‹˜์˜ ์žฌ๊ณ  ์„ ํ˜ธ๋„ ํŒŒ์•…
  - ํƒ€์ดํŠธํ˜•: ์ตœ์†Œ ์žฌ๊ณ  ์œ ์ง€ (ํ˜„๊ธˆ ํ๋ฆ„ ์ค‘์‹œ)
  - ์—ฌ์œ ํ˜•: ์•ˆ์ „ ์žฌ๊ณ  ํ™•๋ณด (ํ’ˆ์ ˆ ๋ฐฉ์ง€ ์ค‘์‹œ)

์žฌ๊ณ  ์ „๋žต ํ”„๋กœํŒŒ์ผ:

class InventoryStrategy:
    TIGHT = {
        'safety_days': 2,      # ์•ˆ์ „ ์žฌ๊ณ  2์ผ์น˜
        'reorder_point': 0.8,  # 80% ์†Œ์ง„ ์‹œ ์ฃผ๋ฌธ
        'order_coverage': 7    # 7์ผ์น˜ ์ฃผ๋ฌธ
    }

    MODERATE = {
        'safety_days': 5,
        'reorder_point': 0.6,
        'order_coverage': 14
    }

    CONSERVATIVE = {
        'safety_days': 10,
        'reorder_point': 0.5,
        'order_coverage': 30
    }

4.3 ๋„๋งค์ƒ ์„ ํƒ ํ•™์Šต (Wholesaler Selection)

ํ•™์Šต ๋ฐ์ดํ„ฐ:
- ๋„๋งค์ƒ๋ณ„ ์ฃผ๋ฌธ ๋นˆ๋„
- ๋„๋งค์ƒ๋ณ„ ์žฌ๊ณ  ์ƒํ™ฉ
- ๋„๋งค์ƒ๋ณ„ ๋ฐฐ์†ก ์Šค์ผ€์ค„
- ์›”๋ณ„ ํ•œ๋„ ์‚ฌ์šฉ๋Ÿ‰
- ๋ถ„ํ•  ์ฃผ๋ฌธ ํŒจํ„ด

ํ•™์Šต ๋ชฉํ‘œ:
- ๊ธฐ๋ณธ ๋„๋งค์ƒ ์„ ํ˜ธ๋„
- ์ƒํ™ฉ๋ณ„ ๋Œ€์ฒด ๋„๋งค์ƒ
- ํ•œ๋„ ๊ณ ๋ คํ•œ ๋ถ„๋ฐฐ
- ๋ฐฐ์†ก ์‹œ๊ฐ„ ๊ณ ๋ ค (๊ธด๊ธ‰ ์‹œ)

๋„๋งค์ƒ ์„ ํƒ ๋กœ์ง:

def select_wholesaler(drug_code, quantity, need_by_time=None):
    """
    AI๊ฐ€ ํ•™์Šตํ•œ ๋„๋งค์ƒ ์„ ํƒ ๋กœ์ง

    ์šฐ์„ ์ˆœ์œ„:
    1. ์žฌ๊ณ  (์žˆ๋Š” ๊ณณ ์šฐ์„ )
    2. ๋ฐฐ์†ก (need_by_time ์ถฉ์กฑ ๊ฐ€๋Šฅํ•œ ๊ณณ)
    3. ํ•œ๋„ (์—ฌ์œ  ์žˆ๋Š” ๊ณณ)
    4. ์„ ํ˜ธ๋„ (๊ณผ๊ฑฐ ํŒจํ„ด)
    """
    candidates = []

    for ws in ['geoyoung', 'sooin', 'baekje']:
        score = 0

        # 1. ์žฌ๊ณ  ์ฒดํฌ
        if has_stock(ws, drug_code, quantity):
            score += 100
        else:
            continue  # ์žฌ๊ณ  ์—†์œผ๋ฉด ์ œ์™ธ

        # 2. ๋ฐฐ์†ก ์‹œ๊ฐ„ ์ฒดํฌ
        if need_by_time:
            delivery = get_next_delivery(ws, need_by_time)
            if delivery['can_deliver']:
                score += 50
            else:
                score -= 30  # ๊ฐ์ 

        # 3. ํ•œ๋„ ์ฒดํฌ
        limit_usage = get_limit_usage(ws)
        if limit_usage < 0.9:
            score += 30
        elif limit_usage >= 1.0:
            score -= 50  # ํ•œ๋„ ์ดˆ๊ณผ

        # 4. ํ•™์Šต๋œ ์„ ํ˜ธ๋„
        score += ai_model.preference_score(ws, drug_code) * 20

        candidates.append((ws, score))

    return max(candidates, key=lambda x: x[1])[0]

4.4 ์ฃผ๋ฌธ ํƒ€์ด๋ฐ ํ•™์Šต

ํ•™์Šต ๋ฐ์ดํ„ฐ:
- ํ•˜๋ฃจ ์ค‘ ์ฃผ๋ฌธ ์‹œ์  (์˜ค์ „/์˜คํ›„)
- ์š”์ผ๋ณ„ ์ฃผ๋ฌธ ํŒจํ„ด
- ๋ฐฐ์†ก ๋งˆ๊ฐ ์‹œ๊ฐ„ ์ „ ์ฃผ๋ฌธ ์—ฌ๋ถ€

ํ•™์Šต ๋ชฉํ‘œ:
- ์ตœ์  ์ฃผ๋ฌธ ์‹œ์  ํŒŒ์•…
- ๋ฐฐ์†ก ๋งˆ๊ฐ ๋†“์น˜์ง€ ์•Š๊ธฐ
- ๋ถ„ํ•  ์ฃผ๋ฌธ (์˜ค์ „/์˜คํ›„) ํŒจํ„ด

5. ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์„ค๊ณ„

5.1 ์„ ์ฃผ๋ฌธ ๋ฐ˜์˜ ์‹œ์Šคํ…œ

๋ชฉ์ : ๊ฐ™์€ ๋‚  ์ด๋ฏธ ์ฃผ๋ฌธํ•œ ํ’ˆ๋ชฉ ์ž๋™ ์ฐจ๊ฐ

def calculate_order_qty(drug_code, usage_qty, current_stock):
    # ์˜ค๋Š˜ "์‹ค์ œ๋กœ" ์ฃผ๋ฌธ ์™„๋ฃŒ๋œ ์ˆ˜๋Ÿ‰ ์กฐํšŒ
    today_ordered = get_today_orders(drug_code)

    # ํ•„์š”๋Ÿ‰ = ์‚ฌ์šฉ๋Ÿ‰ - ํ˜„์žฌ๊ณ  - ์„ ์ฃผ๋ฌธ๋Ÿ‰
    needed = usage_qty - current_stock - today_ordered

    if needed > 0:
        return calculate_spec_qty(needed)
    return 0

โš ๏ธ ํ•ต์‹ฌ: ์‹ค์ œ ์ฃผ๋ฌธ๋งŒ ์นด์šดํŠธ

SELECT SUM(oi.total_dose) as today_ordered
FROM order_items oi
JOIN orders o ON oi.order_id = o.id
WHERE oi.drug_code = ?
  AND o.order_date = DATE('now')
  AND o.is_dry_run = 0              -- dry_run ์ œ์™ธ!
  AND oi.status IN ('success', 'submitted')

5.2 ๋„๋งค์ƒ ํ•œ๋„ ๊ด€๋ฆฌ

๋ชฉ์ : ์›”๋ณ„ ๊ฑฐ๋ž˜ ํ•œ๋„ ์„ค์ • ๋ฐ ์ž๋™ ๋ถ„๋ฐฐ

[ํ•œ๋„ ๋„๋‹ฌ ์‹œ ๋™์ž‘]
1. 90% ๋„๋‹ฌ โ†’ ๊ฒฝ๊ณ  ์•Œ๋ฆผ
2. 100% ๋„๋‹ฌ โ†’ ๋‹ค๋ฅธ ๋„๋งค์ƒ์œผ๋กœ ์ž๋™ ์ „ํ™˜
3. ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹จ๊ณ„์—์„œ ๋ฏธ๋ฆฌ ๋ถ„๋ฅ˜

5.3 ๋ฐฐ์†ก ์Šค์ผ€์ค„ ๊ธฐ๋ฐ˜ ์ฃผ๋ฌธ

๋ชฉ์ : ์ฃผ๋ฌธ ๋งˆ๊ฐ์‹œ๊ฐ„ + ๋ฐฐ์†ก ๋„์ฐฉ์‹œ๊ฐ„ ๋ถ„๋ฆฌ ๊ด€๋ฆฌ

AI ํŒ๋‹จ ์˜ˆ์‹œ:

ํ˜„์žฌ ์˜ค์ „ 11์‹œ, "์˜คํ›„ 3์‹œ์— ํ•„์š”"

โ†’ ์ง€์˜ค์˜ ์˜ค์ „: 10์‹œ ๋งˆ๊ฐ ์ง€๋‚จ โŒ
โ†’ ์ง€์˜ค์˜ ์˜คํ›„: 13์‹œ ๋งˆ๊ฐ โ†’ 15:00 ๋„์ฐฉ (โš ๏ธ ๋”ฑ ๋งž์Œ)
โ†’ ์ˆ˜์ธ: 13์‹œ ๋งˆ๊ฐ โ†’ 14:30 ๋„์ฐฉ (โœ… ์—ฌ์œ )
โ†’ ๋ฐฑ์ œ: ๋‚ด์ผ ๋„์ฐฉ โŒ

๊ฒฐ๋ก : ์ˆ˜์ธ ์ถ”์ฒœ (14:30 ๋„์ฐฉ, 30๋ถ„ ์—ฌ์œ )

5.4 ์ฃผ๋ฌธ ์‹คํŒจ ์‹œ ์žฌ์‹œ๋„

์‹œ๋‚˜๋ฆฌ์˜ค 1: ์žฌ๊ณ  ์—†์Œ
- A๋„๋งค์ƒ ์žฌ๊ณ  0 โ†’ B๋„๋งค์ƒ ๊ฒ€์ƒ‰ โ†’ ์žฌ๊ณ  ์žˆ์œผ๋ฉด B๋กœ ์ฃผ๋ฌธ

์‹œ๋‚˜๋ฆฌ์˜ค 2: ์ฃผ๋ฌธ ์˜ค๋ฅ˜
- A๋„๋งค์ƒ API ์˜ค๋ฅ˜ โ†’ 3ํšŒ ์žฌ์‹œ๋„ โ†’ ์‹คํŒจ ์‹œ B๋„๋งค์ƒ

์‹œ๋‚˜๋ฆฌ์˜ค 3: ๋ถ€๋ถ„ ์„ฑ๊ณต
- 10๊ฐœ ํ’ˆ๋ชฉ ์ค‘ 7๊ฐœ ์„ฑ๊ณต, 3๊ฐœ ์‹คํŒจ
- ์‹คํŒจํ•œ 3๊ฐœ โ†’ B๋„๋งค์ƒ์œผ๋กœ ์ž๋™ ์žฌ์‹œ๋„

[๋ฆฌํฌํŠธ]
- ์ตœ์ข… ์ฃผ๋ฌธ ๊ฒฐ๊ณผ ๋ฆฌํฌํŠธ
- ์•Œ๋ฆผ: "A๋„๋งค์ƒ ํ’ˆ์ ˆ๋กœ B๋„๋งค์ƒ์œผ๋กœ ๋ณ€๊ฒฝ๋จ"

6. ๋ฐ์ดํ„ฐ ๋ชจ๋ธ

6.1 ํ•ต์‹ฌ ํ…Œ์ด๋ธ” (๊ธฐ์กด)

-- ์ฃผ๋ฌธ ์ปจํ…์ŠคํŠธ (AI ํ•™์Šต์šฉ)
CREATE TABLE order_context (
    id INTEGER PRIMARY KEY,
    order_item_id INTEGER,

    -- ์•ฝํ’ˆ ์ •๋ณด
    drug_code TEXT,
    product_name TEXT,

    -- ์ฃผ๋ฌธ ์‹œ์  ์ƒํ™ฉ
    stock_at_order INTEGER,
    usage_1d INTEGER,
    usage_7d INTEGER,
    usage_30d INTEGER,
    avg_daily_usage REAL,

    -- ์ฃผ๋ฌธ ๊ฒฐ์ •
    ordered_spec TEXT,
    ordered_qty INTEGER,
    wholesaler_id TEXT,

    -- ์„ ํƒ์ง€ ์ •๋ณด (AI ํ•™์Šต์šฉ)
    available_specs JSON,
    spec_stocks JSON,
    selection_reason TEXT,

    -- ์˜ˆ์ธก vs ์‹ค์ œ
    predicted_days_coverage REAL,
    actual_days_to_reorder INTEGER,

    -- ๊ฒฐ๊ณผ ํ‰๊ฐ€
    was_optimal BOOLEAN,
    stockout_occurred BOOLEAN,

    created_at TIMESTAMP
);

6.2 ์‹ ๊ทœ ํ…Œ์ด๋ธ”

-- ๋„๋งค์ƒ ํ•œ๋„ ๊ด€๋ฆฌ
CREATE TABLE wholesaler_limits (
    id INTEGER PRIMARY KEY,
    wholesaler_id TEXT NOT NULL,
    monthly_limit INTEGER DEFAULT 0,
    warning_threshold REAL DEFAULT 0.9,
    priority INTEGER DEFAULT 1,
    is_active INTEGER DEFAULT 1,
    created_at TIMESTAMP,
    FOREIGN KEY (wholesaler_id) REFERENCES wholesalers(id)
);

-- ๋ฐฐ์†ก ์Šค์ผ€์ค„
CREATE TABLE delivery_schedules (
    id INTEGER PRIMARY KEY,
    wholesaler_id TEXT NOT NULL,
    delivery_seq INTEGER NOT NULL,
    delivery_name TEXT,
    order_cutoff_time TEXT NOT NULL,      -- ์ฃผ๋ฌธ ๋งˆ๊ฐ (HH:MM)
    delivery_days_offset INTEGER DEFAULT 0, -- 0=๋‹น์ผ, 1=์ต์ผ
    delivery_arrival_time TEXT NOT NULL,   -- ๋„์ฐฉ ์˜ˆ์ • (HH:MM)
    weekdays TEXT,                         -- JSON [1,2,3,4,5]
    is_active INTEGER DEFAULT 1,
    UNIQUE(wholesaler_id, delivery_seq)
);

-- ์‹ค์ œ ๋ฐฐ์†ก ์Šค์ผ€์ค„ ๋ฐ์ดํ„ฐ
INSERT INTO delivery_schedules VALUES
('geoyoung', 1, '์˜ค์ „๋ฐฐ์†ก', '10:00', 0, '11:30'),
('geoyoung', 2, '์˜คํ›„๋ฐฐ์†ก', '13:00', 0, '15:00'),
('sooin', 1, '์˜คํ›„๋ฐฐ์†ก', '13:00', 0, '14:30'),
('baekje', 1, '์ต์ผ๋ฐฐ์†ก', '16:00', 1, '15:00');

-- ์›”๋ณ„ ์‚ฌ์šฉ๋Ÿ‰ ์ถ”์ 
CREATE TABLE wholesaler_monthly_usage (
    id INTEGER PRIMARY KEY,
    wholesaler_id TEXT NOT NULL,
    year_month TEXT NOT NULL,
    total_orders INTEGER DEFAULT 0,
    total_amount INTEGER DEFAULT 0,
    UNIQUE(wholesaler_id, year_month)
);

-- ์ฃผ๋ฌธ ์žฌ์‹œ๋„ ๋กœ๊ทธ
CREATE TABLE order_fallback_log (
    id INTEGER PRIMARY KEY,
    order_item_id INTEGER NOT NULL,
    original_wholesaler TEXT NOT NULL,
    original_error TEXT,
    fallback_wholesaler TEXT NOT NULL,
    fallback_result TEXT,
    created_at TIMESTAMP
);

6.3 ๊ธฐ์กด ํ…Œ์ด๋ธ” ํ™•์žฅ

-- orders ํ…Œ์ด๋ธ” ํ™•์žฅ
ALTER TABLE orders ADD COLUMN is_dry_run INTEGER DEFAULT 0;

-- order_items ํ…Œ์ด๋ธ” ํ™•์žฅ
ALTER TABLE order_items ADD COLUMN fallback_from_wholesaler TEXT;
ALTER TABLE order_items ADD COLUMN prior_order_qty INTEGER DEFAULT 0;

7. API ์„ค๊ณ„

7.1 ๋„๋งค์ƒ ๊ด€๋ฆฌ API

์—”๋“œํฌ์ธํŠธ ๋ฉ”์„œ๋“œ ๊ธฐ๋Šฅ
/api/wholesaler/limits GET ํ•œ๋„ ์กฐํšŒ
/api/wholesaler/limits/{id} PUT ํ•œ๋„ ์„ค์ •
/api/wholesaler/schedules GET ๋ฐฐ์†ก ์Šค์ผ€์ค„
/api/wholesaler/can-deliver-by POST ๋ฐฐ์†ก ๊ฐ€๋Šฅ ์—ฌ๋ถ€

7.2 ์ฃผ๋ฌธ API

์—”๋“œํฌ์ธํŠธ ๋ฉ”์„œ๋“œ ๊ธฐ๋Šฅ
/api/order/today/{drug_code} GET ์˜ค๋Š˜ ์ฃผ๋ฌธ๋Ÿ‰
/api/order/recommend-spec POST ๊ทœ๊ฒฉ ์ถ”์ฒœ
/api/order/create POST ์ฃผ๋ฌธ ์ƒ์„ฑ
/api/order/submit POST ์ฃผ๋ฌธ ์ œ์ถœ (dry_run ์ง€์›)
/api/order/retry POST ์‹คํŒจ ์žฌ์‹œ๋„

7.3 AI API

์—”๋“œํฌ์ธํŠธ ๋ฉ”์„œ๋“œ ๊ธฐ๋Šฅ
/api/ai/daily-analysis GET ์ผ์ผ ๋ถ„์„
/api/ai/recommendations GET ์ฃผ๋ฌธ ์ถ”์ฒœ
/api/ai/training-data GET ํ•™์Šต ๋ฐ์ดํ„ฐ
/api/ai/patterns/{drug_code} GET ํŒจํ„ด ๋ถ„์„

8. ์ž๋™ํ™” ๋ ˆ๋ฒจ

Level 0: ์ˆ˜๋™

Level 1: ๋ฐ˜์ž๋™

Level 2: ์กฐ๊ฑด๋ถ€ ์ž๋™

Level 3: ์™„์ „ ์ž๋™

def should_auto_execute(order_plan):
    level = settings.automation_level

    if level == 0:
        return False

    if level == 1:
        return False  # ํ•ญ์ƒ ์Šน์ธ ํ•„์š”

    if level == 2:
        conditions = [
            order_plan['confidence'] > 0.9,
            order_plan['estimated_cost'] < 100000,
            order_plan['drug_code'] in trusted_drugs,
            order_plan['urgency'] != 'critical'
        ]
        return all(conditions)

    if level == 3:
        return not is_anomaly(order_plan)

9. ์•Œ๋ฆผ ์‹œ์Šคํ…œ

์•Œ๋ฆผ ์œ ํ˜•

์œ ํ˜• ์กฐ๊ฑด ์šฐ์„ ์ˆœ์œ„
์Šน์ธ ์š”์ฒญ ์ž๋™ ์‹คํ–‰ ์•ˆ ๋˜๋Š” ์ฃผ๋ฌธ ๋†’์Œ
์ฃผ๋ฌธ ์™„๋ฃŒ ์ž๋™ ์ฃผ๋ฌธ ์‹คํ–‰๋จ ๋ณดํ†ต
ํ•œ๋„ ๊ฒฝ๊ณ  90% ๋„๋‹ฌ ๋†’์Œ
ํ’ˆ์ ˆ ๊ธด๊ธ‰ ์žฌ๊ณ  0, ๋‹น์ผ ํ•„์š” ๊ธด๊ธ‰
๋ฐฐ์†ก ๋งˆ๊ฐ ๋งˆ๊ฐ 30๋ถ„ ์ „ ๋†’์Œ
๋„๋งค์ƒ ๋ณ€๊ฒฝ ํ’ˆ์ ˆ๋กœ ๋‹ค๋ฅธ ๋„๋งค์ƒ ๋ณดํ†ต

์•Œ๋ฆผ ์˜ˆ์‹œ

๐Ÿ“ฆ ์ฃผ๋ฌธ ์Šน์ธ ์š”์ฒญ

์•ฝํ’ˆ: ์ฝฉ์ฝ”๋ฅด์ • 2.5mg
ํ˜„์žฌ๊ณ : 45๊ฐœ (3์ผ์น˜)
์ถ”์ฒœ ์ฃผ๋ฌธ: 300T x 2๋ฐ•์Šค
๋„๋งค์ƒ: ์ง€์˜ค์˜ (์ ์‹ฌ๋ฐฐ์†ก 11:00 ๋งˆ๊ฐ)
์˜ˆ์ƒ ๊ธˆ์•ก: 72,000์›

[์Šน์ธ] [์ˆ˜์ •] [๊ฑฐ์ ˆ]
โš ๏ธ ๋ฐฐ์†ก ๋งˆ๊ฐ ์•Œ๋ฆผ

์ง€์˜ค์˜ ์˜คํ›„๋ฐฐ์†ก ๋งˆ๊ฐ 30๋ถ„ ์ „!
ํ˜„์žฌ ์žฅ๋ฐ”๊ตฌ๋‹ˆ: 5ํ’ˆ๋ชฉ

13:00๊นŒ์ง€ ์ฃผ๋ฌธํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์Œ ๋ฐฐ์†ก์€ ๋‚ด์ผ์ž…๋‹ˆ๋‹ค.

[์ง€๊ธˆ ์ฃผ๋ฌธ] [๋‚˜์ค‘์—]

10. ๊ฐœ๋ฐœ ๋กœ๋“œ๋งต

Phase 1: ํ•ต์‹ฌ ๊ธฐ๋ฐ˜ (1์ฃผ์ฐจ)

Phase 2: ์ฃผ๋ฌธ ์ž๋™ํ™” (2์ฃผ์ฐจ)

Phase 3: UI ๊ฐœ์„  (2์ฃผ์ฐจ)

Phase 4: AI ํ•™์Šต (3์ฃผ์ฐจ)

Phase 5: ์™„์ „ ์ž๋™ํ™” (4์ฃผ์ฐจ~)


11. ์„ฑ๊ณต ์ง€ํ‘œ (KPI)

์ง€ํ‘œ ํ˜„์žฌ ๋ชฉํ‘œ
์ฃผ๋ฌธ ์†Œ์š” ์‹œ๊ฐ„ 30๋ถ„/์ผ 0๋ถ„ (์ž๋™)
ํ’ˆ์ ˆ ๋ฐœ์ƒ๋ฅ  5% <1%
์žฌ๊ณ  ํšŒ์ „์œจ - +20%
๋ฐฐ์†ก ๋งˆ๊ฐ ๋†“์นจ ๊ฐ€๋” 0ํšŒ
์ฃผ๋ฌธ ๋น„์šฉ ์ ˆ๊ฐ - 5-10% (OTC)

๐Ÿ“š ์ฐธ๊ณ  ๋ฌธ์„œ


๐Ÿ‰ ์šฉ๋ฆผ: ์ด ๋ฌธ์„œ๋Š” AI_ERP_AUTO_ORDER_SYSTEM.md(๋น„์ „/AI๋ชจ๋ธ)์™€
์ž๋™๋ฐœ์ฃผ์‹œ์Šคํ…œ_๊ณ ๋„ํ™”_๊ธฐํš์„œ_v2.md(API/DB์ƒ์„ธ)๋ฅผ ํ†ตํ•ฉํ•œ ๋งˆ์Šคํ„ฐ ๊ธฐํš์„œ์ž…๋‹ˆ๋‹ค.