Skip to content

About

project repository for n8n project

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

ย 

History

31 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ’ณ ๊ฐ€์ƒ ์นด๋“œ ๊ฒฐ์ œ ์•Œ๋ฆผ ์‹œ์Šคํ…œ (Virtual Card Payment Notification System)

ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ์ง€๊ธˆ๊นŒ์ง€ ํ•™์Šตํ•œ JDBC, MVC ํŒจํ„ด, MySQL, Docker ๊ธฐ์ˆ ์„ ์ข…ํ•ฉ์ ์œผ๋กœ ๋ณต์Šตํ•˜๊ณ , n8n ์ž๋™ํ™” ๋„๊ตฌ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๋„์ž…ํ•˜์—ฌ ๊ฐ€์ƒ์˜ ์นด๋“œ ๊ฒฐ์ œ ์•Œ๋ฆผ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํ•œ๋‹ค.
์ด๋ฅผ ํ†ตํ•ด ๋ฐฑ์—”๋“œ ๋กœ์ง ๊ตฌํ˜„๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™, ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ์—์„œ์˜ ์šด์˜, ๊ทธ๋ฆฌ๊ณ  DevOps ๊ด€์ ์˜ ๋กœ๊ทธ ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ์•Œ๋ฆผ ์ž๋™ํ™”๊นŒ์ง€์˜ ์ „ ๊ณผ์ •์„ ๊ฒฝํ—˜ํ•œ๋‹ค.


1. ๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

1) ํŒ€์› ์†Œ๊ฐœ

์‚ฌ์žฌํ—Œ ์ด๋ช…์ง„ ์ด์ฑ„์œ 
GitHub GitHub GitHub

2) ์ฃผ์ œ

์นด๋“œ ๊ฒฐ์ œ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋กœ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์—ฌ Slack์œผ๋กœ ๊ฒฐ์ œ ๋‚ด์—ญ(์„ฑ๊ณต/์‹คํŒจ)์„ ์‹ค์‹œ๊ฐ„ ๋ฐœ์†กํ•˜๋Š” ์‹œ์Šคํ…œ์ด๋‹ค.

3) ๊ธฐํš ์˜๋„

  • ๐Ÿฆ ๊ธˆ์œต IT ๋„๋ฉ”์ธ ์‹ค์Šต: ์šฐ๋ฆฌ FISA(๊ธˆ์œต IT ์•„์นด๋ฐ๋ฏธ)์˜ ํŠน์„ฑ์„ ์‚ด๋ ค ๊ฐ„์ด ๊ฒฐ์ œ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•œ๋‹ค.
  • ๐Ÿ“š ๋ฐฐ์šด ์ง€์‹์˜ ํ™œ์šฉ: Java๋กœ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ณ , JDBC๋ฅผ ํ†ตํ•ด MySQL๊ณผ ์—ฐ๋™ํ•œ๋‹ค. ํŠนํžˆ '๋กœ๊ทธ(Log) ๊ธฐ๋ก'์„ DB ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค๋Š” ๊ฒƒ์— ์˜์˜๋ฅผ ๋‘”๋‹ค.
  • โ™พ๏ธ DevOps ๊ด€์  ์ ์šฉ: ํด๋ผ์šฐ๋“œ ์—”์ง€๋‹ˆ์–ด๋ง ๊ณผ์ •์˜ ํŠน์„ฑ์— ๋งž์ถฐ, ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ์Œ“๋Š” ๊ฒƒ์„ ๋„˜์–ด ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•˜๊ณ , ์˜ค๋ฅ˜๋ฅผ ํƒ์ง€ํ•˜์—ฌ, ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” ์ž๋™ํ™” ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•œ๋‹ค.

4) ํ•ต์‹ฌ ๊ธฐ์ˆ  ์Šคํƒ

๊ตฌ๋ถ„ ๊ธฐ์ˆ  ์„ค๋ช…
์–ธ์–ด Java ๊ฒฐ์ œ ๋กœ์ง ๊ตฌํ˜„ ๋ฐ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
DB MySQL ๊ฒฐ์ œ ๋กœ๊ทธ ์ €์žฅ ๋ฐ ๊ด€๋ฆฌ
์ž๋™ํ™” ํˆด n8n DB ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ Slack ์•Œ๋ฆผ ์ž๋™ํ™”
์ธํ”„๋ผ Docker ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ DB ์ปจํ…Œ์ด๋„ˆํ™”
์•Œ๋ฆผ ์ „์†ก Slack ์•Œ๋ฆผ ์ˆ˜์‹  ์ฑ„๋„

2. ๐Ÿค– n8n ๋„์ž… ๋ฐฐ๊ฒฝ

1) n8n์ด๋ž€?

์‚ฌ์šฉ์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ๊ฑฐ์˜ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ๋‹ค์–‘ํ•œ ์•ฑ๊ณผ ์„œ๋น„์Šค๋ฅผ ์—ฐ๊ฒฐํ•ด ์—…๋ฌด๋ฅผ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์›Œํฌํ”Œ๋กœ์šฐ ์ž๋™ํ™” ๋„๊ตฌ์ด๋‹ค. ๋…ธ๋“œ(Node) ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ ๊ธฐ๋Šฅ์„ ์—ฐ๊ฒฐํ•˜์—ฌ ์ž‘์—… ์ˆœ์„œ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

2) ์™œ n8n์„ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?

  1. DevOps & Backend ์ž๋™ํ™”: ์„œ๋ฒ„ ๋ชจ๋‹ˆํ„ฐ๋ง ์•Œ๋ฆผ(CloudWatch, Grafana ์—ฐ๋™), ๊ฐ„๋‹จํ•œ ๋ฐฑ์—”๋“œ API ๊ตฌ์„ฑ, GitHub ์ด์Šˆ ์—ฐ๋™ ๋“ฑ ๊ฐœ๋ฐœ ์šด์˜ ํšจ์œจ์„ ๋†’์ด๋Š” ๋ฐ ์ตœ์ ํ™”๋˜์–ด ์žˆ๋‹ค.
  2. ๋ฌด๋ฃŒ ์ž๊ฐ€ ํ˜ธ์ŠคํŒ…: Docker ๋“ฑ์„ ํ†ตํ•ด ๋‚ด ์„œ๋ฒ„์— ์ง์ ‘ ์˜ฌ๋ ค ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋น„์šฉ ์—†์ด ํ™œ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.
  3. ๊ฐœ๋ฐœ์ž ์นœํ™”์ : ๋‹จ์ˆœ ์—ฐ๊ฒฐ์„ ๋„˜์–ด JavaScript๋ฅผ ํ™œ์šฉํ•œ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€๊ณต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  4. MCP์™€์˜ ์ฐจ๋ณ„์ : ์ตœ๊ทผ ํ™”๋‘์ธ MCP(Model-Context Protocol)๊ฐ€ AI์™€ ๋„๊ตฌ์˜ ์—ฐ๊ฒฐ ํ‘œ์ค€์ด๋ผ๋ฉด, n8n์€ ๊ตฌ์ฒด์ ์ธ ์ž‘์—… ๋กœ์ง(Workflow)์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์ดˆ์ ์„ ๋งž์ถ˜๋‹ค.

3. ๐Ÿ—๏ธ ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜

๋ณธ ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ์„œ๋น„์Šค(MySQL, n8n)๋Š” Docker ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ ์ƒ์—์„œ ๊ตฌ๋™๋œ๋‹ค.

1) ๊ธฐ๋ณธ ๊ตฌ์กฐ

๊ตฌ๋ถ„ ๊ตฌ์„ฑ/๋„๊ตฌ ์„ค๋ช…
IDE Eclipse ๊ฐœ๋ฐœ ๋ฐ ๋””๋ฒ„๊น… ํ™˜๊ฒฝ
๋นŒ๋“œ ๋„๊ตฌ Maven ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋ฐ ๋นŒ๋“œ ์ž๋™ํ™”
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค MySQL JDBC ๊ฒฐ์ œ ๋กœ๊ทธ ์ €์žฅ์†Œ, JDBC๋กœ ์—ฐ๋™
๋กœ๊น… slf4j Log4j2 ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ ์ˆ˜์ง‘/๊ด€๋ฆฌ
์ž๋™ํ™”/์›Œํฌํ”Œ๋กœ์šฐ n8n DB ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ Slack ์•Œ๋ฆผ ์ž๋™ํ™” ์›Œํฌํ”Œ๋กœ์šฐ ์‹คํ–‰
์ปจํ…Œ์ด๋„ˆํ™” Docker docker-compose MySQL, n8n, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ปจํ…Œ์ด๋„ˆ๋กœ ๋ฐฐํฌ/์šด์˜
์•Œ๋ฆผ ์ฑ„๋„ Slack ๊ฒฐ์ œ ์„ฑ๊ณต/์‹คํŒจ ์•Œ๋ฆผ ์ˆ˜์‹  ์ฑ„๋„

2) ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ

๊ฒฐ์ œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ payment_logs ํ…Œ์ด๋ธ” ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

CREATE TABLE IF NOT EXISTS payment_logs (
    log_id INT AUTO_INCREMENT PRIMARY KEY,
    card_number VARCHAR(20),        -- ์นด๋“œ๋ฒˆํ˜ธ
    amount DECIMAL(10, 0),          -- ๊ฒฐ์ œ๊ธˆ์•ก
    merchant_name VARCHAR(50),      -- ๊ฐ€๋งน์ 
    status VARCHAR(10),             -- SUCCESS, FAIL
    message VARCHAR(100),           -- ๋กœ๊ทธ ๋ฉ”์‹œ์ง€ (์—๋Ÿฌ ์›์ธ ๋“ฑ)
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,    -- ๊ฒฐ์ œ ์‹œ๊ฐ„
    is_alerted BOOLEAN DEFAULT FALSE -- Slack ์•Œ๋ฆผ ๋ฐœ์†ก ์—ฌ๋ถ€
);

4. ๐Ÿ’ธ ๊ฒฐ์ œ ๋ฉ”์„ธ์ง€ ๋ช…์„ธ

1) ๊ฐ€๋งน์  ์ข…๋ฅ˜

  • ์Šคํƒ€๋ฒ…์Šค
  • GS25
  • ์ฟ ํŒก
  • ๋ฐฐ๋‹ฌ์˜๋ฏผ์กฑ
  • ์นด์นด์˜คํƒ์‹œ
  • FISA ๊ตฌ๋‚ด์‹๋‹น

2) ๊ฒฐ์ œ ์‹คํŒจ ์‚ฌ์œ  ์ข…๋ฅ˜

  • ์ž”์•ก๋ถ€์กฑ
  • ํ•œ๋„์ดˆ๊ณผ
  • ๋„๋‚œ๋ถ„์‹ค์นด๋“œ
  • ํ†ต์‹ ์‹œ๊ฐ„์ดˆ๊ณผ
  • CVC์˜ค๋ฅ˜

3) ๊ฒฐ์ œ ์„ฑ๊ณต ์˜ˆ์‹œ

log_id card_number amount merchant_name status message created_at is_alerted
31 9448---1001 4000 woori_atm SUCCESS ๊ฒฐ์ œ ์ •์ƒ ์Šน์ธ 2026-01-15 17:31:15 FALSE
32 4700---8910 12000 cu SUCCESS ๊ฒฐ์ œ ์ •์ƒ ์Šน์ธ 2026-01-16 09:23:15 FALSE

4) ๊ฒฐ์ œ ์‹คํŒจ ์˜ˆ์‹œ

log_id card_number amount merchant_name status message created_at is_alerted
19 9448---1001 24000 emart FAIL ์ž”์•ก๋ถ€์กฑ 2026-01-15 17:31:15 TRUE
20 4700---8910 3000 cu FAIL ํ•œ๋„์ดˆ๊ณผ 2026-01-16 09:23:15 TRUE
21 9448---1001 13000 woori_atm FAIL ๋„๋‚œ๋ถ„์‹ค์นด๋“œ 2026-01-17 13:17:12 TRUE
33 9448---1001 500000 netflix FAIL ํ†ต์‹ ์‹œ๊ฐ„์ดˆ๊ณผ 2026-01-17 13:17:12 TRUE
34 3200---1717 1700 cu FAIL CVC์˜ค๋ฅ˜ 2026-01-17 13:17:12 TRUE

5) ์Šฌ๋ž™ ๋ฐœ์†ก ๋ฉ”์‹œ์ง€ ์˜ˆ์‹œ

๐Ÿšจ [๊ฒฐ์ œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ]
์นด๋“œ๋ฒˆํ˜ธ: 8384-****-****-6028
๊ธˆ์•ก: 36000์›
์‚ฌ์œ : ๊ฒฐ์ œ ์Šน์ธ ๊ฑฐ์ ˆ๋จ (ํ†ต์‹ ์‹œ๊ฐ„์ดˆ๊ณผ)
๊ฒฐ์ œ ์„ฑ๊ณต
์นด๋“œ๋ฒˆํ˜ธ: 7753-****-****-6977
๊ธˆ์•ก: 85000์›
๊ฒฐ์ œ์‹œ๊ฐ: 2026-01-19 17:49:01

5. โš™๏ธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ (Setup)

5.1. Docker ํ™˜๊ฒฝ (docker-compose)

1) ๊ฐ€์ƒ๋จธ์‹  ์ƒ์„ฑ

  • ubuntu server 24.04.3

2) docker ์„ค์น˜

# docker.io ์„ค์น˜
sudo apt update
sudo apt install docker.io

# ๋กœ๊ทธ์ธ(๋„์ปค ํ—ˆ๋ธŒ ๊ณ„์ •)
docker login

# docker-compose ์„ค์น˜(์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ•œ ๋ฒˆ์— ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๋„๊ตฌ)
sudo apt install docker-compose

3) docker-compose.yml ์ƒ์„ฑ

version: '3'

services:
  # 1. MySQL ์ปจํ…Œ์ด๋„ˆ
  mysql-db:
    image: mysql:8.0
    container_name: fisa-mysql
    environment:
      MYSQL_ROOT_PASSWORD: root  # ๋ฃจํŠธ ๋น„๋ฐ€๋ฒˆํ˜ธ
      MYSQL_DATABASE: fisa_db    # ์‹œ์ž‘ํ•  ๋•Œ ๋งŒ๋“ค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ด๋ฆ„
      TZ: Asia/Seoul             # ์‹œ๊ฐ„๋Œ€๋ฅผ ํ•œ๊ตญ์œผ๋กœ ์„ค์ •
    ports:
      - "3306:3306"              # ์™ธ๋ถ€์ ‘์†ํฌํŠธ:๋‚ด๋ถ€ํฌํŠธ
    volumes:
      - ./mysql_data:/var/lib/mysql # DB ๋ฐ์ดํ„ฐ ๋ณด๊ด€ ์žฅ์†Œ
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci # ํ•œ๊ธ€ ๊นจ์ง ๋ฐฉ์ง€

  # 2. n8n ์ปจํ…Œ์ด๋„ˆ
  n8n:
    image: n8nio/n8n
    container_name: fisa-n8n
    ports:
      - "5678:5678"
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true   # ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ์ผœ๊ธฐ
      - N8N_BASIC_AUTH_USER=admin    # n8n ์•„์ด๋”” - ์‹ค์ œ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ
      - N8N_BASIC_AUTH_PASSWORD=pass # n8n ๋น„๋ฐ€๋ฒˆํ˜ธ - ์‹ค์ œ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ
      - GENERIC_TIMEZONE=Asia/Seoul  # ์‹œ๊ฐ„๋Œ€ ์„ค์ •
    volumes:
      - ./n8n_data:/home/node/.n8n   # ์›Œํฌํ”Œ๋กœ์šฐ ์ €์žฅ์œ„์น˜
    dns:                             # DNS ์ฃผ์†Œ ์ง€์ •
      - 8.8.8.8                      # ๊ตฌ๊ธ€ DNS 1 (Trouble Shooting 2 ์ฐธ๊ณ )
      - 8.8.4.4                      # ๊ตฌ๊ธ€ DNS 2
    depends_on:
      - mysql-db                     # DB๊ฐ€ ์ผœ์ง„ ํ›„ ์‹คํ–‰

4) ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ๋ฐ ์‹คํ–‰

docker-compose up -d

# ์„ค์น˜ ํ™•์ธ
# ์•„๋ž˜ ๋ช…๋ น์–ด ์‹คํ–‰์‹œ fisa-mysql๊ณผ fisa-n8n ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ
docker ps

๐Ÿšจ Trouble Shooting 1: ๊ถŒํ•œ ๋ฌธ์ œ
docker-compose up -d ํ›„ n8n ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋กœ์ปฌ์˜ ./n8n_data ๋””๋ ‰ํ† ๋ฆฌ ๊ถŒํ•œ ๋ฌธ์ œ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.
n8n์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ €์žฅํ•˜๋Š” ./n8n_data ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ root ๊ถŒํ•œ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด, ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์— ๋ชจ๋“  ์‚ฌ์šฉ์ž ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋‹ค์‹œ ์‹œ๋„ํ•œ๋‹ค.

sudo chmod -R 777 ./n8n_data

5) ๊ฐ€์ƒ๋จธ์‹  ํฌํŠธํฌ์›Œ๋”ฉ ์„ค์ •

๐Ÿšจ ์ฃผ์˜์‚ฌํ•ญ
๊ฒŒ์ŠคํŠธ IP๋Š” ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ๋ณธ์ธ ์‰˜์—์„œ ip ์ฃผ์†Œ๋ฅผ ํ•„ํžˆ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

๊ทœ์น™ ๋ช… ํ˜ธ์ŠคํŠธ IP ํ˜ธ์ŠคํŠธ ํฌํŠธ ๊ฒŒ์ŠคํŠธ IP(์˜ˆ์‹œ) ๊ฒŒ์ŠคํŠธ ํฌํŠธ ๋น„๊ณ 
mysql docker 127.0.0.1 3306 10.0.2.15 3306
n8n docker 127.0.0.1 5678 10.0.2.15 5678

5.2. DB ํ™˜๊ฒฝ ๊ตฌ์„ฑ

  • docker exec -it fisa-mysql mysql -u root -p ๋ช…๋ น์œผ๋กœ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ์˜ mysql ์‰˜๋กœ ์ด๋™
  • ์•„๋ž˜ ์ฟผ๋ฆฌ ๋ฌธ์„ ์ž…๋ ฅํ•˜์—ฌ ํ…Œ์ด๋ธ” ์ƒ์„ฑ
USE fisa_db;

CREATE TABLE IF NOT EXISTS payment_logs (
    log_id INT AUTO_INCREMENT PRIMARY KEY,
    card_number VARCHAR(20),
    amount DECIMAL(10, 0),
    merchant_name VARCHAR(50),
    status VARCHAR(10),     
    message VARCHAR(100),           
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_alerted BOOLEAN DEFAULT FALSE 
);

5.3. n8n ํ™˜๊ฒฝ ๊ตฌ์„ฑ

1) ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰

docker-compose up -d

2) ๋ธŒ๋ผ์šฐ์ €์—์„œ n8n ์—ด๊ธฐ

  • ๋ธŒ๋ผ์šฐ์ €์— localhost:5678 ์ž…๋ ฅ

3) ๊ฐ€์ž…

  • ๋ฉ”์ผ, ๋น„๋ฐ€๋ฒˆํ˜ธ, ์ด๋ฆ„ ์ž…๋ ฅํ•˜์—ฌ ๊ฐ€์ž…

์ด๋ฉ”์ผ ์ธ์ฆ ๊ณผ์ •์€ ์—†์œผ๋‹ˆ, ์•„๋ฌด๋ ‡๊ฒŒ๋‚˜ ๋งŒ๋“ค์–ด๋„ ๊ดœ์ฐฎ๋‹ค.

4) MySQL Credential ์ถ”๊ฐ€

  1. ์ขŒ์ธก + ๋ฒ„ํŠผ ํด๋ฆญ
  2. Credential ํด๋ฆญ
  3. mysql ๊ฒ€์ƒ‰ ํ›„ continue
  4. ์•„๋ž˜์™€ ๊ฐ™์ด ์ž…๋ ฅ ํ›„ save
    • Host: mysql-db

      ๐Ÿšจ ์ฃผ์˜์‚ฌํ•ญ
      docker์ƒ์—์„œ mysql์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ host ์ด๋ฆ„์— container ์ด๋ฆ„์ด ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.

    • Database: fisa_db
    • User: root
    • Password: root
    • Port: 3306

5) Slack API ๋ฐœ๊ธ‰

  1. Slack API ์‚ฌ์ดํŠธ ์ ‘์† -> Create New App -> From scratch.
  2. App Name: (์•„๋ฌด๊ฑฐ๋‚˜), ์›Œํฌ์ŠคํŽ˜์ด์Šค ์„ ํƒ -> Create.
  3. ์™ผ์ชฝ ๋ฉ”๋‰ด OAuth & Permissions ํด๋ฆญ.
  4. ์•„๋ž˜๋กœ ์Šคํฌ๋กคํ•ด์„œ Scopes -> Bot Token Scopes์— chat:write ๊ถŒํ•œ ์ถ”๊ฐ€.
  5. ๋งจ ์œ„๋กœ ์˜ฌ๋ ค์„œ Install to Workspace ํด๋ฆญ -> ํ—ˆ์šฉ.
  6. ์ƒ์„ฑ๋œ Bot User OAuth Token (xoxb-๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ’)์„ ๋ณต์‚ฌ
  7. n8n์œผ๋กœ ๋Œ์•„์™€์„œ Credentials -> Slack API ์ถ”๊ฐ€ -> Access Token ๋ž€์— ๋ถ™์—ฌ๋„ฃ๊ณ  ์ €์žฅ.

๐Ÿšจ Trouble Shooting 2: Slack Webhook ์‚ฌ์šฉ์‹œ ์ฃผ์˜์‚ฌํ•ญ
n8n์— slack ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, HTTP Request ๋…ธ๋“œ์— Slack API์—์„œ ๋ฐ›์€ Webhook url๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.
๋‹ค๋งŒ ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ๋•Œ, n8n ๋„์ปค ์ปจํ…Œ์ด๋„ˆ๊ฐ€ DNS ์„œ๋ฒ„๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
docker-compose down ๋ช…๋ น์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ฉˆ์ถ˜ ํ›„, docker-compose.yml ์— DNS ์ฃผ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๋‹ค์‹œ ์ž‘๋™์‹œํ‚ค๋‹ˆ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค.
์ด์™€ ๋‹ฌ๋ฆฌ n8n์— Slack ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์—์„œ๋Š” ๋ณ„๋„์˜ ์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค.
๋”ฐ๋ผ์„œ, ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” HTTP Request ๋…ธ๋“œ์— Slack webhook URL์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, Slack ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.

6) n8n workflow ๊ตฌ์„ฑ

  1. ๊ฒฐ์ œ ์˜ค๋ฅ˜ ๋ฐœ์†ก ๋…ธ๋“œ

    • schedule trigger ๋…ธ๋“œ ์ถ”๊ฐ€

      • trigger interval: minutes (๋ถ„ ๋‹จ์œ„๋กœ ์ž‘์—… ๋ฐ˜๋ณต)
      • seconds between triggers: 1(1๋ถ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์„ค์ •)
    • mysql: execute a sql query ๋…ธ๋“œ ์ถ”๊ฐ€

      • Query ์นธ์— ์•„๋ž˜ sql์„ ์ž…๋ ฅ

        -- ๊ฒฐ์ œ ์‹คํŒจ ๊ธฐ๋ก์„ DB์—์„œ ๊ฐ€์ ธ์˜ด
        SELECT * FROM payment_logs 
        WHERE (status = 'FAIL' OR status = 'ERROR') 
        AND is_alerted = 0;
    • slack: send a message ๋…ธ๋“œ ์ถ”๊ฐ€

      • Credential: ๋ฐฉ๊ธˆ ๋งŒ๋“  Slack bot ๊ณ„์ • ์„ ํƒ

      • Resource: Message, Operation: Send , Send message to : Channel

      • Channel: ์•Œ๋ฆผ ๋ฐ›์„ ์ฑ„๋„ ์„ ํƒ

      • Message Type: Simple text message ์„ ํƒ ํ›„ ์•„๋ž˜ ํ…์ŠคํŠธ ์ž…๋ ฅ

        ๐Ÿšจ [๊ฒฐ์ œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ]
        ์นด๋“œ๋ฒˆํ˜ธ: {{ $json.card_number }}
        ๊ธˆ์•ก: {{ $json.amount }}์›
        ์‚ฌ์œ : {{ $json.message }}
    • mysql: execute a sql query ๋…ธ๋“œ ์ถ”๊ฐ€

      • Query ์นธ์— ์•„๋ž˜ sql์„ ์ž…๋ ฅ

        -- ์•Œ๋ฆผ ๋ณด๋‚ธ ๋กœ๊ทธ ์ฒ˜๋ฆฌ์™„๋ฃŒ ํ‘œ์‹œ
        UPDATE payment_logs 
        SET is_alerted = 1 
        WHERE log_id = {{ $('Execute a SQL query').item.json.log_id }};
  2. ๊ฒฐ์ œ ์„ฑ๊ณต ๋ฐœ์†ก ๋…ธ๋“œ

    • schedule trigger ๋…ธ๋“œ ์ถ”๊ฐ€

      • trigger interval: minutes (๋ถ„ ๋‹จ์œ„๋กœ ์ž‘์—… ๋ฐ˜๋ณต)
      • seconds between triggers: 10(10๋ถ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์„ค์ •)
    • mysql: execute a sql query ๋…ธ๋“œ ์ถ”๊ฐ€

      • Query ์นธ์— ์•„๋ž˜ sql์„ ์ž…๋ ฅ

        -- ๊ฒฐ์ œ ์„ฑ๊ณต ๊ธฐ๋ก์„ DB์—์„œ ๊ฐ€์ ธ์˜ด
        SELECT * FROM payment_logs 
        WHERE (status = 'SUCCESS') 
        AND is_alerted = 0;
    • slack: send a message ๋…ธ๋“œ ์ถ”๊ฐ€

      • Credential: ๋ฐฉ๊ธˆ ๋งŒ๋“  Slack bot ๊ณ„์ • ์„ ํƒ

      • Resource: Message, Operation: Send , Send message to : Channel

      • Channel: ์•Œ๋ฆผ ๋ฐ›์„ ์ฑ„๋„ ์„ ํƒ

      • Message Type: Simple text message ์„ ํƒ ํ›„ ์•„๋ž˜ ํ…์ŠคํŠธ ์ž…๋ ฅ

        ๊ฒฐ์ œ ์„ฑ๊ณต
        ์นด๋“œ๋ฒˆํ˜ธ: {{ $json.card_number }} 
        ๊ธˆ์•ก: {{ $json.amount }}์› 
        ๊ฒฐ์ œ์‹œ๊ฐ: {{ $json.created_at }}
    • mysql: execute a sql query ๋…ธ๋“œ ์ถ”๊ฐ€

      • Query ์นธ์— ์•„๋ž˜ sql์„ ์ž…๋ ฅ

        -- ์•Œ๋ฆผ ๋ณด๋‚ธ ๋กœ๊ทธ ์ฒ˜๋ฆฌ์™„๋ฃŒ ํ‘œ์‹œ
        UPDATE payment_logs 
        SET is_alerted = 1 
        WHERE log_id = {{ $('Execute a SQL query1').item.json.log_id }};

7) ์™„์„ฑ๋œ n8n ์›Œํฌํ”Œ๋กœ์šฐ ๋ชจ์Šต

n8n-workflow.png

6. ๐Ÿ’ป ํ•ต์‹ฌ ๋กœ์ง ๋ฐ ์„ธ๋ถ€ ์‚ฌํ•ญ

6.1. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(๋žœ๋ค ๊ฒฐ์ œ ๊ธฐ๋ก ์ƒ์„ฑ) ๋ช…์„ธ

์ด ํ”„๋กœ์ ํŠธ์— ์ ์šฉ๋œ ๋žœ๋ค ๋กœ์ง์€ ์‹ค์ œ ๊ฒฐ์ œ ํ™˜๊ฒฝ์—์„œ ์ผ์–ด๋‚  ๋ฒ•ํ•œ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ๋‹ค.

๋‹จ์ˆœํ•œ ๋”๋ฏธ ๋ฐ์ดํ„ฐ ์‚ฝ์ž…์ด ์•„๋‹Œ, ์‹ค์ œ ์กด์žฌํ•  ๋ฒ•ํ•œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋งŒ๋“ค์–ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ๋งž๋„๋ก ์ƒ์„ฑํ•œ ๋’ค SQL๋ฌธ์œผ๋กœ DB์— ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ด๋‹ค.

์•„๋ž˜๋Š” ์ž๋ฐ”์˜ java.util.Random ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋œ 4๊ฐ€์ง€ ํ•ต์‹ฌ ๋กœ์ง์ด๋‹ค.


1) ์žฅ์•  ๋ฐœ์ƒ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ (ํ™•๋ฅ  ์ œ์–ด ๋กœ์ง)

์ด ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋‹ค. n8n์ด "์—๋Ÿฌ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์Šฌ๋ž™์„ ๋ณด๋‚ด๋Š”์ง€" ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด, ๊ฐ€๋” ์—๋Ÿฌ๊ฐ€ ํ„ฐ์ ธ์•ผ ํ•œ๋‹ค.

boolean isFail = random.nextInt(5) == 0;
  • ์ž‘๋™ ์›๋ฆฌ:
    • random.nextInt(5)๋Š” 0 ์ด์ƒ 5 ๋ฏธ๋งŒ์˜ ์ •์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (์ฆ‰, 0, 1, 2, 3, 4 ์ค‘ ํ•˜๋‚˜)
    • 5๊ฐœ์˜ ์ˆซ์ž ์ค‘ 0์ด ๋‚˜์˜ฌ ํ™•๋ฅ ์€ ์ˆ˜ํ•™์ ์œผ๋กœ 1/5, ์ฆ‰ 20% ์ด๋‹ค.
  • ์˜๋ฏธ:
    • ๊ฒฐ์ œ 5๊ฑด ์ค‘ ์•ฝ 1๊ฑด ๊ผด๋กœ ๊ณ ์˜์ ์ธ ๊ฒฐ์ œ ์‹คํŒจ(FAIL)๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
    • ๋‚˜๋จธ์ง€ 80%๋Š” ์ •์ƒ ์Šน์ธ(SUCCESS)์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.
    • ์ด ๋น„์œจ์„ ์กฐ์ ˆํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด nextInt(10)์œผ๋กœ ๋ฐ”๊พธ๋ฉด 10% ํ™•๋ฅ ์ด ๋˜๊ณ , nextInt(5) <= 1; ๊ณผ ๊ฐ™์ด ์กฐ๊ฑด๋ฌธ ๋ฒ”์œ„๋ฅผ ์กฐ์ ˆํ•˜๋ฉด 40%๊ฐ€ ๋œ๋‹ค.

2) ๊ฒฐ์ œ ๊ธˆ์•ก ๋žœ๋ค ์ƒ์„ฑ

1์›, 2์› ๊ฐ™์€ ๋น„ํ˜„์‹ค์ ์ธ ๊ธˆ์•ก์ด ์•„๋‹ˆ๋ผ, ์‹ค์ œ ์นด๋“œ ๊ฒฐ์ œ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ธˆ์•ก์„ ๋งŒ๋“ ๋‹ค.

int amount = (random.nextInt(100) + 1) * 1000;
  • ์ž‘๋™ ์›๋ฆฌ:
    • nextInt(100): 0๋ถ€ํ„ฐ 99๊นŒ์ง€์˜ ๋žœ๋คํ•œ ์ •์ˆ˜๊ฐ€ ๋‚˜์˜จ๋‹ค.
    • + 1: 0์›์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์ตœ์†Œ 1๋‹จ์œ„๋ฅผ ๋งŒ๋“ ๋‹ค. (1~100)
    • 1000: ์ฒœ ์› ๋‹จ์œ„๋กœ ๋งŒ๋“ ๋‹ค.
  • ๊ฒฐ๊ณผ: ์ตœ์†Œ 1,000์›์—์„œ ์ตœ๋Œ€ 100,000์› ์‚ฌ์ด์˜ ๊ธˆ์•ก์ด 1,000์› ๋‹จ์œ„๋กœ ์ƒ์„ฑ๋œ๋‹ค. (์˜ˆ: 15,000์›, 42,000์›)

3) ๊ฐ€๋งน์  ๋ฐ ์—๋Ÿฌ ์‚ฌ์œ  ๋žœ๋ค ์„ ํƒ (๋ฐฐ์—ด ์ธ๋ฑ์‹ฑ)

์‹ค์ œ ์กด์žฌํ•˜๋Š” ์ƒํ˜ธ๋ช…๊ณผ ์กด์žฌํ•  ๋ฒ•ํ•œ ์˜ค๋ฅ˜๋ช…๋“ค์„ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘” ๋ฐฐ์—ด์—์„œ ๋žœ๋ค์œผ๋กœ ๋ฝ‘๊ณ , ์กฐํ•ฉํ•˜์—ฌ ๊ฒฐ์ œ ๊ธฐ๋ก์„ ์ƒ์„ฑํ•œ๋‹ค.

String[] merchants = {"์Šคํƒ€๋ฒ…์Šค", "GS25", "์ฟ ํŒก", ...};
return merchants[random.nextInt(merchants.length)];
  • ์ž‘๋™ ์›๋ฆฌ:
    • ๋ฐฐ์—ด์— ๋ฐ์ดํ„ฐ๊ฐ€ 6๊ฐœ ์žˆ๋‹ค๋ฉด length๋Š” 6์ด๋‹ค.
    • nextInt(6)์€ 0๋ถ€ํ„ฐ 5๊นŒ์ง€์˜ ๋žœ๋คํ•œ ์ •์ˆ˜๊ฐ€ ๋‚˜์˜จ๋‹ค.
    • merchants[2] ์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ, ๋žœ๋คํ•œ index์˜ ๊ฐ€๊ฒŒ ์ด๋ฆ„์„ ๊บผ๋‚ธ๋‹ค.
  • ๊ฒฐ๊ณผ: 6๊ฐœ์˜ ๊ฐ€๋งน์  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋žœ๋ค์œผ๋กœ ๋‚˜์˜จ๋‹ค.
  • ์—๋Ÿฌ ์ฝ”๋“œ("์ž”์•ก๋ถ€์กฑ", "ํ•œ๋„์ดˆ๊ณผ" ๋“ฑ) ๋„ ๋˜‘๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์„ ํƒ๋œ๋‹ค.

4) ์นด๋“œ ๋ฒˆํ˜ธ ์ƒ์„ฑ (๋ฌธ์ž์—ด ํฌ๋งทํŒ…)

๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ๋ฅผ ์œ„ํ•ด ๊ฐ€์šด๋ฐ ์ˆซ์ž๋ฅผ ๊ฐ€๋ฆฐ(Masking) ์นด๋“œ ๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

String.format("%04d-****-****-%04d", 
        random.nextInt(9000) + 1000,  // ์•ž 4์ž๋ฆฌ
        random.nextInt(9000) + 1000); // ๋’ค 4์ž๋ฆฌ
  • ์ž‘๋™ ์›๋ฆฌ:
    • nextInt(9000): 0๋ถ€ํ„ฐ 8999๊นŒ์ง€์˜ ๋žœ๋คํ•œ ์ •์ˆ˜๊ฐ€ ๋‚˜์˜จ๋‹ค.
    • + 1000: ๊ทธ ๊ฒฐ๊ณผ์— ๋”ํ•˜๋ฉด 1000 ~ 9999 ๋ฒ”์œ„์˜ ์ •์ˆ˜๊ฐ€ ๋œ๋‹ค. (๋ฌด์กฐ๊ฑด 4์ž๋ฆฌ ์ˆซ์ž ๋ณด์žฅ)
  • ๊ฒฐ๊ณผ: 1234-****-****-5678 ํ˜•ํƒœ์˜ ๋žœ๋ค ์นด๋“œ ๋ฒˆํ˜ธ ๋ฌธ์ž์—ด์ด ์™„์„ฑ๋œ๋‹ค.

5) ์˜ˆ์‹œ: ์ด ๋กœ์ง์ด ๋งŒ๋“œ๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค

์ด Java ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ์ด ๋ฌด์ž‘์œ„๋กœ ๋ฐ˜๋ณต๋œ๋‹ค.

  1. 80% ํ™•๋ฅ ๋กœ: "์Šคํƒ€๋ฒ…์Šค"์—์„œ "15,000์›" ๊ฒฐ์ œ ์„ฑ๊ณต (๋กœ๊ทธ: INFO) โ†’ DB ์ €์žฅ โ†’ n8n์—์„œ ์„ฑ๊ณต ํŒŒ์ดํ”„๋ผ์ธ ์ž‘๋™ โ†’ ์Šฌ๋ž™ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก
  2. 20% ํ™•๋ฅ ๋กœ: "์ฟ ํŒก"์—์„œ "52,000์›" ๊ฒฐ์ œ ์‹คํŒจ, ์‚ฌ์œ ๋Š” "์ž”์•ก๋ถ€์กฑ" (๋กœ๊ทธ: WARN) โ†’ DB ์ €์žฅ โ†’ n8n์—์„œ ์‹คํŒจ ํŒŒ์ดํ”„๋ผ์ธ ์ž‘๋™ โ†’ ๐Ÿšจ ์Šฌ๋ž™ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก

6.2. ๋””์ž์ธ ํŒจํ„ด ๋ช…์„ธ

1) MVC ํŒจํ„ด์ด๋ž€

MVC(Model-View-Controller) ํŒจํ„ด์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์„ธ ๊ฐ€์ง€ ์—ญํ• ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ฐœ๋ฐœ ๋ฐ ์œ ์ง€๋ณด์ˆ˜์˜ ํšจ์œจ์„ฑ์„ ๋†’์ด๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

  • Model (๋ชจ๋ธ): ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ์ดํ„ฐ์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋‹ด๋‹นํ•œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ๊ทœ์น™์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.
  • View (๋ทฐ): ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ง€๋Š” ํ™”๋ฉด(UI) ์„ ๋‹ด๋‹นํ•œ๋‹ค. ๋ชจ๋ธ์ด ์ฒ˜๋ฆฌํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๊ฑฐ๋‚˜, ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆผ์„ ์ถœ๋ ฅํ•˜๋Š” ์—ญํ• ์ด๋‹ค.
  • Controller (์ปจํŠธ๋กค๋Ÿฌ): ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ(Input) ์„ ๋ฐ›์•„ ๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์ง€ํœ˜์ž ์—ญํ• ์„ ํ•œ๋‹ค.
    ๋ฌด์—‡์„ ์ฒ˜๋ฆฌํ• ์ง€ ๋ชจ๋ธ์—๊ฒŒ ์ง€์‹œํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์–ด๋–ค ๋ทฐ๋กœ ๋ณด์—ฌ์ค„์ง€ ๊ฒฐ์ •ํ•œ๋‹ค.

2) MVC ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ ์ด์œ 

  1. ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ (Separation of Concerns)
    • ๋žœ๋ค ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋กœ์ง(Service), DB์— ์ €์žฅํ•˜๋Š” ๋กœ์ง(DAO), ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋กœ์ง(View)์ด ์„ž์ด์ง€ ์•Š๋„๋ก ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ธ๋‹ค.
  2. ์œ ์ง€๋ณด์ˆ˜ ๋ฐ ํ™•์žฅ์„ฑ
    • ์ถ”ํ›„ DB๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(Service)์€ ์ˆ˜์ •ํ•  ํ•„์š” ์—†์ด DAO๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค.
    • ์ฝ˜์†” ์ถœ๋ ฅ ๋Œ€์‹  ์›น ํ™”๋ฉด์œผ๋กœ ํ™•์žฅํ•˜๋”๋ผ๋„ View ๊ณ„์ธต๋งŒ ๊ต์ฒดํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์œ ์—ฐํ•œ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
      • ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๋Š” view๋ฅผ ๋‹จ์ˆœํžˆ ์ฝ˜์†” ์ถœ๋ ฅ์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.
  3. ํ˜‘์—… ํšจ์œจ์„ฑ
    • ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ(DTO)์™€ ๋กœ์ง(Service), ํ™”๋ฉด(View)์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์–ด, ๊ฐ ์ปดํฌ๋„ŒํŠธ๋ณ„๋กœ ๋ช…ํ™•ํ•œ ์—ญํ•  ์ •์˜๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

3) ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ

n8n_project
   +---src
   |   +---controller
   |   |       PaymentController.java
   |   |
   |   +---model
   |   |   +---dao
   |   |   |       PaymentLogsDAO.java
   |   |   |
   |   |   +---domain
   |   |   |       PaymentLogsDTO.java
   |   |   |       RanDataDTO.java
   |   |   |
   |   |   \---service
   |   |           PaymentService.java
   |   |
   |   +---util
   |   |       DBUtil.java
   |   |       RandomUtil.java
   |   |
   |   \---view
   |           PaymentFailView.java
   |           PaymentStartView.java
               PaymentSuccessView.java
   ...

4) ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ ์š”์†Œ(Model, View, Controller)์˜ ์—ญํ• 

๐ŸŸข Model (Data & Business Logic)

์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ์ฝ”์–ด๋กœ์„œ ๋ฐ์ดํ„ฐ์™€ ๋กœ์ง์„ ์ „๋‹ดํ•œ๋‹ค. ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” model ํŒจํ‚ค์ง€ ํ•˜์œ„์— dao, domain, service๋ฅผ ๋‘์–ด ๊ด€๋ฆฌํ•œ๋‹ค.

  • domain (DTO)
    • PaymentLogsDTO.java: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ payment_log ํ…Œ์ด๋ธ”๊ณผ 1:1๋กœ ๋งคํ•‘๋˜๋Š” ๋ฐ์ดํ„ฐ ์ „์†ก ๊ฐ์ฒด์ด๋‹ค.
    • RanDataDTO.java: ๋žœ๋ค ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ์œ„ํ•œ ํ•„๋“œ๋ฅผ ๋‹ด๋Š” ๊ฐ์ฒด์ด๋‹ค.
  • dao (Data Access Object)
    • PaymentLogsDAO.java: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(MySQL)์— ์ง์ ‘ ์—ฐ๊ฒฐํ•˜์—ฌ INSERT SQL ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • service (Business Logic)
    • PaymentService.java: RandomUtil์„ ์ด์šฉํ•ด ๊ฒฐ์ œ ์ •๋ณด๋ฅผ ๋ฌด์ž‘์œ„๋กœ ์ƒ์„ฑํ•˜๊ณ , ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ PaymentLogsDAO์—๊ฒŒ ์ „๋‹ฌํ•˜์—ฌ ์ €์žฅ์„ ์š”์ฒญํ•˜๋Š” ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๐Ÿ”ต View (User Interface)

์‚ฌ์šฉ์ž(๊ฐœ๋ฐœ์ž/๊ด€๋ฆฌ์ž)์—๊ฒŒ ์‹œ์Šคํ…œ์˜ ๋™์ž‘ ์ƒํƒœ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค.

  • PaymentStartView.java: ์•ฑ์˜ ์‹œ์ž‘์ ์œผ๋กœ, ์‹œ์ž‘์„ ์•Œ๋ ค์ฃผ๋Š” ๋ฌธ์žฅ์„ ์ถœ๋ ฅํ•œ๋‹ค.
  • PaymentSuccessView.java: ๋ฐ์ดํ„ฐ๊ฐ€ DB์— ์ •์ƒ์ ์œผ๋กœ ์ €์žฅ๋˜์—ˆ์„ ๋•Œ, ์„ฑ๊ณต ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
  • PaymentFailView.java: DB ์—ฐ๊ฒฐ ์‹คํŒจ๋‚˜ ์ €์žฅ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ, ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

๐Ÿ”ด Controller

๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉฐ, ํ”„๋กœ์ ํŠธ์˜ ์ „์ฒด ํ๋ฆ„์„ ์ œ์–ดํ•œ๋‹ค.

  • PaymentController.java
    1. PaymentService๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(๋ฐ์ดํ„ฐ ์ƒ์„ฑ ๋ฐ ์ €์žฅ)์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์ง€์‹œํ•œ๋‹ค.
    2. ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ PaymentSuccessView ๋˜๋Š” PaymentFailView๋ฅผ ์„ ํƒํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™”๋ฉด์— ๋„์šด๋‹ค.

๐ŸŸก Util

ํ”„๋กœ์ ํŠธ ์ „๋ฐ˜์—์„œ ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

  • DBUtil.java: JDBC ๋“œ๋ผ์ด๋ฒ„ ๋กœ๋”ฉ ๋ฐ Connection ๊ฐ์ฒด ์ƒ์„ฑ/๋ฐ˜ํ™˜ ๋“ฑ ์ค‘๋ณต๋˜๋Š” DB ์—ฐ๊ฒฐ ์ฝ”๋“œ๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค.
  • RandomUtil.java: ์ƒ์  ์ด๋ฆ„, ๊ฒฐ์ œ ์ƒํƒœ, ์นด๋“œ ๋ฒˆํ˜ธ ๋“ฑ์„ ๋ฌด์ž‘์œ„๋กœ ์ถ”์ถœํ•˜๋Š” ๋กœ์ง์„ ์ œ๊ณตํ•˜์—ฌ Service์˜ ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

7. ๐Ÿ“ธ ํ”„๋กœ์ ํŠธ ๊ฒฐ๊ณผ ํ™”๋ฉด

Java ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ์ •์ƒ์ ์œผ๋กœ MySQL์— ์นด๋“œ ๊ฒฐ์ œ ๊ธฐ๋ก์ด ์ €์žฅ๋˜๊ณ , n8n ์›Œํฌํ”Œ๋กœ์šฐ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™๋œ๋‹ค.
๋˜ํ•œ ์ฃผ๊ธฐ์ ์œผ๋กœ Slack ์ฑ„๋„์— ๊ฒฐ์ œ ๊ธฐ๋ก์ด ๋„์ฐฉํ•˜๊ณ , ๊ฒฐ์ œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ ์ฆ‰์‹œ ๋ฉ”์‹œ์ง€๊ฐ€ ๋„์ฐฉํ•˜๋Š” ๋ชจ์Šต์ด๋‹ค.

image.png


About

project repository for n8n project

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages