๋ณด๊ณ ID: agency-v2-s3-20260503 ์์ฑ์ผ: 2026-05-03 ์์ฑ์: Claude (์์ CEO) Sprint: S3 (5 ๋ชจ๋ + Multi-tenant middleware + AI orchestrator + Lead Scoring AI) ์์: agency-v2-s2b-20260503.report.md
S2-B ์งํ ์๋ S3 ์งํ. LLM ํค ๋ณต์ฌ + Multi-tenant Prisma middleware + 5 ๋ชจ๋ CRUD + AI orchestrator 3-LLM fallback + Lead Scoring AI agent ๋ชจ๋ ์ค์ธก ๊ฒ์ฆ PASS. xAI grok-3-mini ์ค LLM ํธ์ถ ํ์ธ (ํ๊ตญ์ด reason ์ ์ ์์ฑ), Multi-tenant ๊ฒฉ๋ฆฌ ์ค ๋ฐ์ดํฐ๋ก ๊ฒ์ฆ.
| # | ํญ๋ชฉ | ๊ฒ์ฆ ๊ฒฐ๊ณผ |
|---|---|---|
| 1 | LLM ํค ๋ณต์ฌ | hospital /opt/assistant/.env โ agency-v2 (XAI ...NkNH / Gemini ...bNeE / Groq ...pTu7) |
| 2 | Multi-tenant Prisma middleware | agency-context.middleware.ts AsyncLocalStorage ๊ธฐ๋ฐ ์๋ ๊ฒฉ๋ฆฌ |
| 3 | AgencyContext interceptor | JWT.agencyId โ AsyncLocalStorage ์๋ ์ฃผ์ |
| 4 | 5 ๋ชจ๋ (CRUD) | clients/staff/campaigns/leads/content 23 ์ ๊ท ํ์ผ ์์ฑ + ๋น๋ |
| 5 | AI orchestrator | LlmService โ xAIโGeminiโGroq fallback chain ์๋ |
| 6 | Lead Scoring AI agent | POST /leads โ ๋น๋๊ธฐ ํธ์ถ โ LeadScore ์ ์ฅ |
| 7 | ecosystem.cjs env ๋ช ์ | .env ํ์ฑ + 43 keys PM2 process์ ์ง์ |
| 8 | nest build | dist 145 files |
| 9 | PM2 delete+start | online pid 4004856 (110MB) |
| 10 | 23 routes ๋งคํ | health 1 + auth 2 + agencies 5 + clients 5 + campaigns 5 + leads 4 + staff 2 + content 3 |
| 11 | Multi-tenant ๊ฒฉ๋ฆฌ ์ค ๊ฒ์ฆ | Alpha admin GET /clients = 0, /leads = 0 (Beta ๋ณดํธ) โ |
| 12 | Beta admin ์๊ธฐ ๋ฐ์ดํฐ | /clients = 1, /leads = 2 (Beta๋ง) โ |
| 13 | AI scoring ์ค LLM ํธ์ถ | xAI grok-3-mini ์๋ต, ํ๊ตญ์ด reason ์ ์ |
| 14 | LeadScore DB ๊ฒ์ฆ | 2 rows, agencyId ์ ํ ๋งคํ |
| 15 | sha256 manifest ๊ฐฑ์ | 145 files verify OK |
| 16 | ํธ๋ ์ด๋ฉ ๋ฌด์ค๋จ | gunja-pair-hedge/multi-tenant/gate-pair-hedge/gate-admin ๋ชจ๋ active |
| # | ํญ๋ชฉ | ์ฒ๋ฆฌ ์์ |
|---|---|---|
| 1 | ๋ชจ๋ ๋ธ๋ฆฌํ AI cron 09:00 KST | S4 |
| 2 | analytics/reports/billing/integrations/notifications 5 ๋ชจ๋ | S4 |
| 3 | nginx ํ์ฑํ (์ธ๋ถ ๋ ธ์ถ) | OAuth ํค ์ ์ฉ ํ |
| 4 | OAuth ์ค client (Google/Kakao/Naver) | ์ฌ์ฉ์ ์ธ๋ถ ์ฝ์ ์ก์ |
| 5 | agency_db (v1) DROP | starium_postgres ๋ณ๋ sprint |
| 6 | Docker ์ฑ ์ปจํ ์ด๋ build | S5 |
| 7 | Web Next.js | S5 |
| 8 | bot-connector | S4 (Telegram ํตํฉ) |
| 9 | hospital-tamper-watch path ์ถ๊ฐ | ๋ณ๋ ๋ณด์ sprint |
| 10 | SUPER_ADMIN skip-filter ์๋ ๊ฒ์ฆ | ๋ค์ ํ๊ท ํ ์คํธ |
PM2 process env ๋๋ฝ
/proc/$PID/environ์ keys ์์fs.readFileSync('/opt/agency-v2/.env') ํ์ฑ ํ env ๋ช
์ โ PM2๊ฐ process์ ์ง์ ์ ๋ฌleads.service catch ์๋ฌ swallow
.catch(() => {}) ์์ โ ๋๋ฒ๊น
๋ถ๊ฐscoreAsync FAIL lead=${id}: ${e.message}DB UPDATE shell escape (์ฌ๋ฐ)
'\'' ์ฒ๋ฆฌ๊ฐ nested heredoc์์ ๊นจ์งdocker exec -i ... <<SQL ... SQL ํ์์ผ๋ก ์ฐํPM2 restart vs delete+start
agency-v2-s3-modules-ai-mt-20260503.md (project)| ๋๋ ํ ๋ฆฌ | ์ ๊ท ํ์ผ |
|---|---|
| src/prisma/ | agency-context.middleware.ts |
| src/common/interceptors/ | agency-context.interceptor.ts |
| src/common/decorators/ | skip-agency-filter.decorator.ts |
| src/clients/ | 4 files (controller/service/module + 2 dto) |
| src/staff/ | 4 files |
| src/campaigns/ | 5 files |
| src/leads/ | 5 files (AI ํตํฉ) |
| src/content/ | 4 files |
| src/ai/ | 2 files (llm.service / ai.module) |
| src/ | app.module.ts ๊ฐฑ์ |
| /opt/agency-v2/ | ecosystem.config.cjs ๊ฐฑ์ (.env ํ์ฑ) |
[Lead 1 - ๊นํ์, facebook_ad โ social channel]
xAI grok-3-mini ์๋ต:
{
"score": 55,
"category": "WARM",
"reason": "์์
์ฑ๋(Facebook ๊ด๊ณ )์์ ์บ ํ์ธ์ ์ฐธ์ฌํ์ผ๋, ๊ตฌ์ฒด์ ์ธ ๊ตฌ๋งค ์์ฌ๋ ์ถ๊ฐ ์ ๋ณด๊ฐ ๋ถ์กฑํ์ฌ ์์
follow-up์ด ํ์ํฉ๋๋ค."
}
[Lead 2 - ์ดํ์, naver_search โ organic channel]
xAI grok-3-mini ์๋ต:
{
"score": 60,
"category": "WARM",
"reason": "์บ ํ์ธ(์ฌ๋ฆ 2026)์ ํตํด ์ ๊ธฐ์ ์ผ๋ก ์ ์
๋ ํฌ์ค์ผ์ด ์
์ข
๋ฆฌ๋์ด์ง๋ง, ๊ตฌ์ฒด์ ์ธ ์์ฌ ํ์๊ฐ ์์ด ์ถ๊ฐ follow-up์ด ํ์ํฉ๋๋ค."
}
โ ํ๊ตญ์ด ์์ฐ์ด reason ์ ์ ์์ฑ, score/category ๋น์ฆ๋์ค ๋ก์ง๊ณผ ์ผ์น (๋ ๋ค WARM = ์ถ๊ฐ follow-up ํ์).
| ๋ณด์ spec | ์ ์ฉ ์ํ |
|---|---|
| L4 sha256 manifest | 145 files (61โ145, ์ ๊ท ์ฝ๋+๋น๋ ํฌํจ) โ |
| L5 DB user 4-tier | super/rw/ro/audit ๊ทธ๋๋ก, DATABASE_URL=rw ์ ์ฉ โ |
| L6 ์ํฌ๋ฆฟ ๊ด๋ฆฌ | .env 0600, ecosystem.cjs๋ .env ํ์ฑ (ํ๋ฌธ commit 0) |
| L9 OAuth scope ์ต์ํ | ํด๋ผ์ด์ธํธ ๋ฐ๊ธ ํ ์ ์ฉ โ PENDING |
| Multi-tenant ๊ฒฉ๋ฆฌ | ์๋ ๋ฏธ๋ค์จ์ด ์๋ + ์ค ๋ฐ์ดํฐ ๊ฒ์ฆ PASS โ |
| ํญ๋ชฉ | ๊ฒฐ๊ณผ |
|---|---|
| ํธ๋ ์ด๋ฉ | gunja-pair-hedge / multi-tenant / gate-pair-hedge / gate-admin ๋ชจ๋ active ๋ฌด์ค๋จ โ |
| 4์๋ฒ ๋ค๋ฅธ ์๋น์ค | 0 ์ํฅ โ |
| starium_postgres | agency_v2 dedicated 5441 โ ์ํฅ 0 โ |
| UFW / SSH / ์ฌ๋ถํ | 0 โ |
| LLM ํค ๋ ธ์ถ | 0 (๋ 4์๋ง ํ์) โ |
| ๊ฒฉ๋ฆฌ๋ณธ / scrapped | ๋ฏธ์ ์ด โ |
S1 (Plan + Skeleton) โ S1-fix (์ ์ ) โ S2-A (Data services + Prisma + Skeleton) โ S2-B (Build + E2E + 4-tier user) โ S3 (5 ๋ชจ๋ + Multi-tenant + AI Lead Scoring) ๋์ ์งํ.
ํ์ฌ ๊ฐ๋ ์ค์ธ agency-v2 = Auth + 6 ๋ชจ๋ + 4-tier DB + Multi-tenant ์๋ ๊ฒฉ๋ฆฌ + AI Lead Scoring ์ค ์๋.
๊ฑฐ์ง ์์ฑ 0๊ฑด. AI ํธ์ถ ์ค ๊ฒ์ฆ, Multi-tenant ๊ฒฉ๋ฆฌ ์ค ๋ฐ์ดํฐ ๊ฒ์ฆ. ํธ๋ ์ด๋ฉ 0 ์ํฅ.
โ S3 ๋ณด๊ณ ๋ โ