diff --git a/workflow/01_conversation/coldmail_ir_notification_sync.md b/workflow/01_conversation/coldmail_ir_notification_sync.md new file mode 100644 index 0000000..cf196f8 --- /dev/null +++ b/workflow/01_conversation/coldmail_ir_notification_sync.md @@ -0,0 +1,26 @@ +# coldmail_ir_notification_sync 워크플로우 + +## 목적 +콜드메일 수신 시 IR 자료 포함 여부를 판별하고, Slack에 요약 알림 + IR 분석 버튼을 게시한다. + +## 흐름 +``` +Webhook In → Format Coldmail Data → Post Basic Notification → Has IR Deck? → (true) Add IR Analysis Button + → (false) 종료 +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Webhook In | `POST /notifications/coldmail-ir` 수신 | +| Format Coldmail Data | 회사명, 발신자, 제목, 요약, IR 문서 유무 추출 | +| Post Basic Notification | Slack 채널에 콜드메일 요약 게시 | +| Has IR Deck? | `has_ir_deck && selected_document_id` 조건 분기 | +| Add IR Analysis Button | 스레드에 IR 지표 추출/밸류에이션 버튼 추가 | + +## 엔드포인트 +- 인바운드: `POST /notifications/coldmail-ir` (n8n webhook) +- 아웃바운드: Slack `chat.postMessage` (기본 알림 + IR 버튼) + +## 관련 문서 +- [slack_basic_dialogue](./slack_basic_dialogue.md) diff --git a/workflow/01_conversation/slack_action_extractor_request.md b/workflow/01_conversation/slack_action_extractor_request.md new file mode 100644 index 0000000..330a481 --- /dev/null +++ b/workflow/01_conversation/slack_action_extractor_request.md @@ -0,0 +1,27 @@ +# slack_action_extractor_request 워크플로우 + +## 목적 +Slack 메시지에서 "할 일/액션/todo/action" 의도를 감지하면, skill-slack의 액션 추출 API를 호출하여 결과를 스레드에 회신한다. + +## 흐름 +``` +Slack Trigger → Detect Action Intent → Action Request? → (true) Call skill-slack Extract Actions → Build Action Reply → Reply to Slack + → (false) 종료 +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Slack Trigger | 채널 메시지 이벤트 수신 | +| Detect Action Intent | 정규식으로 액션 키워드 감지, channel/user 유효성 확인 | +| Call skill-slack Extract Actions | `POST :8502/api/v1/extract-actions` 호출 (24h, auto_assign, priority_detection) | +| Build Action Reply | 추출된 액션 아이템을 번호 목록 텍스트로 포맷 | +| Reply to Slack | 원래 스레드에 결과 회신 | + +## 엔드포인트 +- 아웃바운드: `POST http://192.168.219.52:8502/api/v1/extract-actions` +- 아웃바운드: Slack `chat.postMessage` (스레드 회신) + +## 관련 문서 +- [slack_thread_summary_request](./slack_thread_summary_request.md) +- [slack_basic_dialogue](./slack_basic_dialogue.md) diff --git a/workflow/01_conversation/slack_thread_summary_request.md b/workflow/01_conversation/slack_thread_summary_request.md new file mode 100644 index 0000000..002f150 --- /dev/null +++ b/workflow/01_conversation/slack_thread_summary_request.md @@ -0,0 +1,27 @@ +# slack_thread_summary_request 워크플로우 + +## 목적 +Slack 메시지에서 "요약/정리/digest/summary" 의도를 감지하면, skill-slack의 요약 API를 호출하여 결과를 스레드에 회신한다. + +## 흐름 +``` +Slack Trigger → Detect Summary Intent → Summary Request? → (true) Call skill-slack Summarize → Build Summary Reply → Reply to Slack + → (false) 종료 +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Slack Trigger | 채널 메시지 이벤트 수신 | +| Detect Summary Intent | 정규식으로 요약 키워드 감지, channel/user 유효성 확인 | +| Call skill-slack Summarize | `POST :8502/api/v1/summarize` 호출 (24h, include_files=true) | +| Build Summary Reply | 요약 텍스트 추출 | +| Reply to Slack | 원래 스레드에 결과 회신 | + +## 엔드포인트 +- 아웃바운드: `POST http://192.168.219.52:8502/api/v1/summarize` +- 아웃바운드: Slack `chat.postMessage` (스레드 회신) + +## 관련 문서 +- [slack_action_extractor_request](./slack_action_extractor_request.md) +- [slack_basic_dialogue](./slack_basic_dialogue.md) diff --git a/workflow/02_skills/skill_calendar_request.md b/workflow/02_skills/skill_calendar_request.md new file mode 100644 index 0000000..3309903 --- /dev/null +++ b/workflow/02_skills/skill_calendar_request.md @@ -0,0 +1,28 @@ +# skill_calendar_request 워크플로우 + +## 목적 +캘린더 스킬의 webhook 브릿지. 일정 생성(create) 또는 조회(query) 요청을 skill-calendar API로 전달하고 결과를 반환한다. + +## 흐름 +``` +Webhook In → Normalize Payload → Action Type → (create) Create Event → Return Result + → (else) Query Events → Return Result +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Webhook In | `POST /skills/calendar/request` 수신 | +| Normalize Payload | action(create/query), user_id, event_data, query 추출 | +| Action Type | action === "create" 분기 | +| Create Event | `POST :8512/api/events` (X-User-Id 헤더) | +| Query Events | `GET :8512/api/events?query=...` (X-User-Id 헤더) | +| Return Result | webhook 응답 반환 | + +## 엔드포인트 +- 인바운드: `POST /skills/calendar/request` (n8n webhook) +- 아웃바운드: `http://192.168.219.52:8512/api/events` (GET/POST) + +## 관련 문서 +- [skill_email_send_request](./skill_email_send_request.md) +- [skill_news_briefing_request](./skill_news_briefing_request.md) diff --git a/workflow/02_skills/skill_email_send_request.md b/workflow/02_skills/skill_email_send_request.md new file mode 100644 index 0000000..704dc26 --- /dev/null +++ b/workflow/02_skills/skill_email_send_request.md @@ -0,0 +1,24 @@ +# skill_email_send_request 워크플로우 + +## 목적 +이메일 발송 스킬의 webhook 브릿지. 요청 payload를 그대로 skill-email API에 전달하고 결과를 반환한다. + +## 흐름 +``` +Webhook In → Call skill-email → Return Response +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Webhook In | `POST /skills/email/send` 수신 | +| Call skill-email | `POST :8501/api/v1/send` (body 그대로 전달) | +| Return Response | webhook 응답 반환 | + +## 엔드포인트 +- 인바운드: `POST /skills/email/send` (n8n webhook) +- 아웃바운드: `POST http://192.168.219.52:8501/api/v1/send` + +## 관련 문서 +- [skill_calendar_request](./skill_calendar_request.md) +- [skill_slack_send_message_bridge](./skill_slack_send_message_bridge.md) diff --git a/workflow/02_skills/skill_news_briefing_request.md b/workflow/02_skills/skill_news_briefing_request.md new file mode 100644 index 0000000..56b7614 --- /dev/null +++ b/workflow/02_skills/skill_news_briefing_request.md @@ -0,0 +1,24 @@ +# skill_news_briefing_request 워크플로우 + +## 목적 +뉴스 브리핑 스킬의 webhook 브릿지. 요청 payload를 그대로 skill-news API에 전달하고 결과를 반환한다. + +## 흐름 +``` +Webhook In → Call skill-news → Return Response +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Webhook In | `POST /skills/news/briefing` 수신 | +| Call skill-news | `POST :8505/api/v1/briefing` (body 그대로 전달) | +| Return Response | webhook 응답 반환 | + +## 엔드포인트 +- 인바운드: `POST /skills/news/briefing` (n8n webhook) +- 아웃바운드: `POST http://192.168.219.52:8505/api/v1/briefing` + +## 관련 문서 +- [skill_calendar_request](./skill_calendar_request.md) +- [scheduled_daily_briefing](../04_scheduler/scheduled_daily_briefing.md) diff --git a/workflow/02_skills/skill_slack_send_message_bridge.md b/workflow/02_skills/skill_slack_send_message_bridge.md new file mode 100644 index 0000000..e7b6542 --- /dev/null +++ b/workflow/02_skills/skill_slack_send_message_bridge.md @@ -0,0 +1,25 @@ +# skill_slack_send_message_bridge 워크플로우 + +## 목적 +Slack 메시지 발송 브릿지. 내부 서비스가 Slack 메시지를 보내야 할 때 이 webhook을 통해 n8n Slack 노드로 발송한다. + +## 흐름 +``` +Webhook In → Normalize Payload → Post to Slack → Return Response +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Webhook In | `POST /skills/slack/send` 수신 | +| Normalize Payload | channel, text, thread_ts, blocks 추출 | +| Post to Slack | Slack `chat.postMessage` (스레드 지원) | +| Return Response | `{success, channel, thread_ts}` 반환 | + +## 엔드포인트 +- 인바운드: `POST /skills/slack/send` (n8n webhook) +- 아웃바운드: Slack `chat.postMessage` + +## 관련 문서 +- [skill_email_send_request](./skill_email_send_request.md) +- [slack_basic_dialogue](../01_conversation/slack_basic_dialogue.md) diff --git a/workflow/03_rag/companyx_grounding_pipeline.json b/workflow/03_rag/companyx_grounding_pipeline.json index 013d865..199c174 100644 --- a/workflow/03_rag/companyx_grounding_pipeline.json +++ b/workflow/03_rag/companyx_grounding_pipeline.json @@ -160,7 +160,9 @@ "main": [[{ "node": "Return Grounded Answer", "type": "main", "index": 0 }]] } }, - "settings": {}, + "settings": { + "notes": "260319: rb8001 /api/message 경로에 프롬프트 DB v3 및 neutral constraints 생략이 적용되었으나, 이 워크플로우는 LLM Answer with Context 노드에서 system_instruction을 직접 지정(skip_default_prompt 동등)하므로 rb8001 기본 프롬프트가 주입되지 않는다. 따라서 260319 변경의 실질적 영향 없음." + }, "pinData": {}, "meta": { "templateCredsSetupCompleted": true, diff --git a/workflow/04_scheduler/scheduled_daily_briefing.md b/workflow/04_scheduler/scheduled_daily_briefing.md new file mode 100644 index 0000000..287254f --- /dev/null +++ b/workflow/04_scheduler/scheduled_daily_briefing.md @@ -0,0 +1,31 @@ +# scheduled_daily_briefing 워크플로우 + +## 목적 +평일 09:10에 네이버 + 동남아 스타트업 헤드라인을 수집하여 Slack 채널에 자동 게시한다. + +## 흐름 +``` +09:10 Trigger (월~금) → Build Runtime Context → [병렬] Call Naver Headlines API + Call SEA Headlines API + → Describe Actual Path → APIs Reachable? → (true) Build Runtime Summary → Slack Delivery View + → (false) Build Fallback Summary → Slack Delivery View +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| 09:10 Trigger | cron `10 9 * * 1-5` (평일 09:10) | +| Build Runtime Context | scheduler 메타 정보 설정 (channel, job wrapper, state store) | +| Call Naver Headlines API | `POST :8505/api/news/naver/startup-headlines` (format=slack) | +| Call SEA Headlines API | `POST :8505/api/news/sea/headlines` (format=json) | +| Describe Actual Path | 두 API 결과를 합산하여 실행 경로 요약 | +| APIs Reachable? | 양쪽 모두 200인지 확인 | +| Slack Delivery View | 최종 결과를 Slack 채널에 게시 | + +## 엔드포인트 +- 아웃바운드: `POST http://192.168.219.52:8505/api/news/naver/startup-headlines` +- 아웃바운드: `POST http://192.168.219.52:8505/api/news/sea/headlines` +- 아웃바운드: Slack `chat.postMessage` (채널: C09C98KK2TT) + +## 관련 문서 +- [skill_news_briefing_request](../02_skills/skill_news_briefing_request.md) diff --git a/workflow/04_scheduler/scheduled_healthcheck_alert.md b/workflow/04_scheduler/scheduled_healthcheck_alert.md new file mode 100644 index 0000000..ce3b11e --- /dev/null +++ b/workflow/04_scheduler/scheduled_healthcheck_alert.md @@ -0,0 +1,25 @@ +# scheduled_healthcheck_alert 워크플로우 + +## 목적 +10분마다 rb8001의 health 엔드포인트를 확인하고, 실패 시 Slack 알림을 보낸다. + +## 흐름 +``` +Schedule Trigger (*/10 * * * *) → Check rb8001 Health → Health Failed? → (true) Send Alert + → (false) 종료 +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Schedule Trigger | cron `*/10 * * * *` (매 10분) | +| Check rb8001 Health | `GET :8001/health` | +| Health Failed? | statusCode !== 200 분기 | +| Send Alert | Slack C_ALERTS 채널에 장애 알림 | + +## 엔드포인트 +- 아웃바운드: `GET http://192.168.219.52:8001/health` +- 아웃바운드: Slack `chat.postMessage` (채널: C_ALERTS) + +## 관련 문서 +- [service_health_check](../05_admin/service_health_check.md) diff --git a/workflow/04_scheduler/scheduled_rag_reindex_retry.md b/workflow/04_scheduler/scheduled_rag_reindex_retry.md new file mode 100644 index 0000000..4b991e4 --- /dev/null +++ b/workflow/04_scheduler/scheduled_rag_reindex_retry.md @@ -0,0 +1,25 @@ +# scheduled_rag_reindex_retry 워크플로우 + +## 목적 +6시간마다 RAG 재인덱싱 실패 큐를 확인하고, pending 상태인 항목을 최대 20건까지 재시도한다. + +## 흐름 +``` +Schedule Trigger (0 */6 * * *) → Load Retry Queue → Call Reindex API → Mark Done +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Schedule Trigger | cron `0 */6 * * *` (6시간마다) | +| Load Retry Queue | PostgreSQL에서 `rag_retry_queue` pending 항목 최대 20건 조회 | +| Call Reindex API | `POST :8508/api/reindex` (timeout 120초, X-User-Id: system) | +| Mark Done | 성공 시 `status = 'done'`, `processed_at = NOW()` 업데이트 | + +## 엔드포인트 +- 아웃바운드: `POST http://192.168.219.52:8508/api/reindex` +- DB: PostgreSQL `rag_retry_queue` 테이블 (SELECT, UPDATE) + +## 관련 문서 +- [rag_upload_indexing_pipeline](../03_rag/rag_upload_indexing_pipeline.md) +- [skill_embedding_bridge](../03_rag/skill_embedding_bridge.md) diff --git a/workflow/05_admin/diary_reflection_pipeline.json b/workflow/05_admin/diary_reflection_pipeline.json index 355211a..303aab2 100644 --- a/workflow/05_admin/diary_reflection_pipeline.json +++ b/workflow/05_admin/diary_reflection_pipeline.json @@ -99,6 +99,9 @@ "Generate Diary (rb8001)": { "main": [[{ "node": "Get Diary Content", "type": "main", "index": 0 }]] }, "Get Diary Content": { "main": [[{ "node": "Post to Slack", "type": "main", "index": 0 }]] } }, + "settings": { + "notes": "260319: rb8001 /api/diary/generate 내부에서 llm_service.process_request()가 task_type=chat, context={}로 호출됨. 프롬프트 DB v3 활성 프롬프트가 system prompt로 주입되며, neutral 감정일 때 감정 constraints가 생략된다. 이전 하드코딩 프롬프트 대비 일기 톤에 변화 가능." + }, "pinData": {}, "meta": { "templateCredsSetupCompleted": true, "instanceId": "robeing-admin" } } diff --git a/workflow/05_admin/diary_reflection_pipeline.md b/workflow/05_admin/diary_reflection_pipeline.md new file mode 100644 index 0000000..81d3ff8 --- /dev/null +++ b/workflow/05_admin/diary_reflection_pipeline.md @@ -0,0 +1,37 @@ +# diary_reflection_pipeline 워크플로우 + +## 목적 +매일 새벽 2시에 전날의 로빙 일기를 자동 생성하고 Slack에 요약을 게시한다. 수동 트리거도 지원한다. + +## 흐름 +``` +Daily at 2AM ─┐ +Manual Trigger ─┤→ Set Yesterday Date → Generate Diary (rb8001) → Get Diary Content → Post to Slack +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Daily at 2AM | cron `0 2 * * *` | +| Manual Trigger | `POST /admin/diary/trigger` (수동 실행용) | +| Set Yesterday Date | 전날 날짜(YYYY-MM-DD) 계산 | +| Generate Diary (rb8001) | `POST :8001/api/diary/generate` (timeout 300초) | +| Get Diary Content | `GET :8001/api/diary/{date}?robeing_id=rb8001` | +| Post to Slack | 일기 요약 + 감정 + 대시보드 링크를 Slack에 게시 | + +## 엔드포인트 +- 인바운드: `POST /admin/diary/trigger` (n8n webhook, 수동) +- 아웃바운드: `POST http://192.168.219.52:8001/api/diary/generate` +- 아웃바운드: `GET http://192.168.219.52:8001/api/diary/{date}` +- 아웃바운드: Slack `chat.postMessage` + +## 260319 변경 영향 + +이 워크플로우는 rb8001의 `/api/diary/generate`를 호출한다. 내부적으로 `llm_service.process_request()`가 `task_type=chat`, `context={}`로 실행되므로: + +- **프롬프트 DB v3 주입: 적용됨** -- DB `prompt_versions` 활성 프롬프트가 일기 생성 시 system prompt로 주입된다. +- **neutral 감정 constraints 생략: 적용됨** -- 일기 생성 시 감정이 neutral이면 감정 constraints가 생략된다. +- 이전(~260318)에는 하드코딩 프롬프트 + 모든 감정에 constraints 주입이었으므로, 일기 톤에 변화가 있을 수 있다. + +## 관련 문서 +- [service_health_check](./service_health_check.md) diff --git a/workflow/05_admin/service_health_check.md b/workflow/05_admin/service_health_check.md new file mode 100644 index 0000000..24893ec --- /dev/null +++ b/workflow/05_admin/service_health_check.md @@ -0,0 +1,39 @@ +# service_health_check 워크플로우 + +## 목적 +10분마다 robeing 전체 서비스(gateway, auth, rb8001, skill-email, skill-news, skill-rag-file, skill-calendar)의 health를 확인하고, DOWN인 서비스가 있으면 Slack에 장애 알림을 보낸다. + +## 흐름 +``` +Every 10 mins → Service List → Check Health → Assess Status → Is Down? → (true) Alert Slack + → (false) 종료 +``` + +## 주요 노드 +| 노드 | 설명 | +|---|---| +| Every 10 mins | 10분 간격 스케줄 | +| Service List | 7개 서비스의 name + health URL 배열 생성 | +| Check Health | 각 서비스 `GET {url}` 호출 (timeout 5초, 에러 시 continue) | +| Assess Status | statusCode 200/201이면 UP, 그 외 DOWN | +| Is Down? | DOWN일 때만 알림 분기 | +| Alert Slack | 서비스명, 상태 코드 포함 장애 알림 | + +## 감시 대상 +| 서비스 | URL | +|---|---| +| robeing-gateway | `http://192.168.219.45:8100/health` | +| auth-server | `http://192.168.219.45:9000/health` | +| rb8001 | `http://192.168.219.52:8001/health` | +| skill-email | `http://192.168.219.52:8501/healthz` | +| skill-news | `http://192.168.219.52:8505/healthz` | +| skill-rag-file | `http://192.168.219.52:8508/healthz` | +| skill-calendar | `http://192.168.219.52:8512/health` | + +## 엔드포인트 +- 아웃바운드: 위 7개 서비스 health URL +- 아웃바운드: Slack `chat.postMessage` (장애 시) + +## 관련 문서 +- [scheduled_healthcheck_alert](../04_scheduler/scheduled_healthcheck_alert.md) +- [diary_reflection_pipeline](./diary_reflection_pipeline.md)