๋ณด๊ณ ID: agency-v2-s2b-20260503 ์์ฑ์ผ: 2026-05-03 ์์ฑ์: Claude (์์ CEO) Sprint: S2-B (npm install + nest build + PM2 + E2E)
S2-A (์ธํ๋ผ + skeleton) ์งํ ์๋ S2-B ์งํ. NestJS api-gateway ๋น๋ + PM2 ์๊ตฌ ๊ฐ๋ + Auth E2E + Agency CRUD E2E 6/6 + PG 4-tier user + DB ๊ถํ ๋ถ๋ฆฌ + sha256 manifest ๋ชจ๋ ์ค์ธก ๊ฒ์ฆ PASS. ๊ฑฐ์ง ์์ฑ 0๊ฑด, PENDING 8๊ฑด ์ ์ง ๋ช ์.
| ์์ญ | ๊ฒ์ฆ ๊ฒฐ๊ณผ |
|---|---|
| npm install workspaces | 413 packages / 303MB / 18s |
| nest build | dist/main.js + ๋ชจ๋ ๋ชจ๋ ์ปดํ์ผ |
| PM2 ์๊ตฌ ๋ฑ๋ก | agency-v2-api online pid 3964435, 103.6MB, autorestart |
| health endpoint | {"status":"ok","db":true,...} |
| Auth register E2E | ์ฌ์ฉ์ cmopnf87... ์์ฑ + JWT 263 chars |
| Auth login E2E | JWT ๋ฐ๊ธ, role STAFF ์ ํ |
| RolesGuard (STAFFโ403) | GET /agencies โ "Forbidden / insufficient_role" โ |
| SUPER_ADMIN promote | DB UPDATE ๊ฒ์ฆ |
| re-login (SUPER_ADMIN JWT) | role=SUPER_ADMIN |
| Agency CRUD POST ร 2 | alpha (id cmopng12b...) + beta (id cmopng14c...) |
| Agency CRUD GET list | 2๊ฐ array, ordered by createdAt desc |
| Agency CRUD GET :id | single agency |
| Agency CRUD PATCH | name ์ ๋ฐ์ดํธ + updatedAt ๋ณ๊ฒฝ |
| Agency CRUD DELETE | status=ARCHIVED soft delete |
| DB SELECT ํ๊ท | alpha ARCHIVED / beta ACTIVE ์ ํ |
| PG 4-tier user ์์ฑ | super/rw/ro/audit (4 roles) |
| RO UPDATE ๊ฑฐ๋ถ ๊ฒ์ฆ | "permission denied for table User" โ |
| DATABASE_URL superโrw | .env ๋ณ๊ฒฝ + PM2 restart |
| ํ๊ท (rw user) | Auth + CRUD ์ ์ ์๋ |
| sha256 manifest first record | 61 files / 13569 bytes JSON |
| manifest verify | "OK: 61 files unchanged" |
| ํธ๋ ์ด๋ฉ ๋ฌด์ค๋จ | gunja-pair-hedge / multi-tenant / gate-pair-hedge / gate-admin active active |
| hospital ๋ค๋ฅธ PM2 | 28 online (27 + agency-v2-api 1) |
| # | ํญ๋ชฉ | ์ฌ์ |
|---|---|---|
| 1 | agency_db (v1) DROP | starium_postgres connection pool ๋ง์ฑ ๊ฐ๋ (40/40 retry fail). PG max_connections ์กฐ์ ๋๋ restart sprint ํ์. agency_v2 ๋ณ๋ DB๋ผ ๋น์ฆ๋์ค ์ํฅ 0 |
| 2 | Docker ์ฑ ์ปจํ ์ด๋ build | Dockerfile ์์ฑ๋์ผ๋ build ๋ฏธ์๋. ํ์ฌ PM2 ํธ์คํธ ์ง์ ์คํ โ ๋ณด์ spec L3 (Docker ๊ฒฉ๋ฆฌ)๋ S5๋ก ๋ฏธ๋ฃธ (๋ณ๊ฒฝ ์์์ง ํ ์ผ๊ด ์ปจํ ์ด๋ํ) |
| 3 | Multi-tenant Prisma middleware | Auth + Agencies ์ธ ๋ชจ๋ ์ถ๊ฐ (clients/leads ๋ฑ) ์ ํจ๊ป โ S3 |
| 4 | OAuth ์ค client (Google/Kakao/Naver) | ์ฌ์ฉ์ ์ธ๋ถ ์ฝ์ ์ก์ (Phase 2) |
| 5 | LLM API key (xAI/Gemini/Groq) | ์ฌ์ฉ์ ์ธ๋ถ ์ก์ , S3์์ ์ฌ์ฉ |
| 6 | hospital-tamper-watch path ์ถ๊ฐ | ๋ณด์ spec L1, ๋ณ๋ ๋ณด์ sprint |
| 7 | Web Next.js | S5 |
| 8 | bot-connector | S3 |
docker exec -i ... <<< "..." ๋๋ heredoc๋ก ํด๊ฒฐ[1] POST /api/v1/auth/register
body: {email, password, name}
โ 201 Created
โ {accessToken, user: {sub, email, role: "STAFF", agencyId: null}}
[2] POST /api/v1/auth/login
โ 200 OK + JWT 263 chars
[3] GET /api/v1/agencies (STAFF JWT)
โ 403 Forbidden + {message: "insufficient_role"}
โ
RolesGuard ์ ์ ๋์
[4] DB: UPDATE "User" SET role='SUPER_ADMIN' WHERE email=...
โ UPDATE 1
[5] POST /api/v1/auth/login (์ฌ๋ก๊ทธ์ธ)
โ 200 + JWT (role: "SUPER_ADMIN")
[6] POST /api/v1/agencies (SUPER_ADMIN JWT)
body: {name, slug}
โ 201 Created + {id, name, slug, status: "ACTIVE", createdAt, updatedAt}
[7] GET /api/v1/agencies โ 200 + 2 agencies array
[8] GET /api/v1/agencies/:id โ 200 + single
[9] PATCH /api/v1/agencies/:id โ 200 + updated name
[10] DELETE /api/v1/agencies/:id โ 200 + status: "ARCHIVED" (soft delete)
[11] DB SELECT verify
test-alpha: ARCHIVED / test-beta: ACTIVE
| ๋ณด์ spec layer | ์ ์ฉ ์ํ |
|---|---|
| L1 ld.so.preload immutable | hospital ํธ์คํธ ๊ทธ๋๋ก (S1 sprint ๊ฒฐ๊ณผ) |
| L2 SSH ๊ฐํ | ๋ณ๋ sprint (fail2ban ๋ฑ) |
| L3 Docker ๊ฒฉ๋ฆฌ | data services๋ง Docker, ์ฑ์ PM2 โ S5์์ ์ผ๊ด ์ปจํ ์ด๋ํ |
| L4 npm audit + sha256 manifest | manifest ์ฒซ record (61 files OK) โ |
| L5 DB user 4-tier | super/rw/ro/audit ์์ฑ + DATABASE_URL=rw ์ ์ฉ โ |
| L6 ์ํฌ๋ฆฟ ๊ด๋ฆฌ | .env 0600 / OAuth/LLM placeholder. sops/age๋ Phase 2 |
| L7 nginx WAF | conf ์์ฑ๋จ, ํ์ฑํ๋ ์ฌ์ฉ์ ๋๋ S3 |
| L8 auditd | ๋ณ๋ sprint |
| L9 OAuth scope ์ต์ | ํด๋ผ์ด์ธํธ ๋ฐ๊ธ ํ ์ ์ฉ |
| L10 Build server ๋ถ๋ฆฌ | ํธ์คํธ build (paperclip ๋๋ GitHub Actions๋ก ์ด์ ๋๊ธฐ) |
| L11 health monitor cron | health endpoint ์์ฑ๋จ, cron ๋ฑ๋ก์ ๋ณ๋ |
โ L4 + L5 ๋ณธ sprint ์์ฑ. ๋๋จธ์ง ์ ์ง.
/opt/star365-hq/docs/04-report/agency-v2-s2b-20260503.report.md (๋ณธ ๋ณด๊ณ ์)~/.claude/projects/-opt/memory/agency-v2-s2b-build-e2e-20260503.md/opt/agency-v2/apps/api-gateway/dist/ (nest build ๊ฒฐ๊ณผ)/opt/agency-v2/ecosystem.config.cjs (PM2)/opt/agency-v2/.integrity-manifest.json (61 files sha256)/opt/agency-v2/logs/ (PM2 log)agency.starium.site SSL + sites-enabled ๋ฑ๋ก)S2-B = 23๊ฑด ์ค์ธก PASS + 4 ์ด์ ํด๊ฒฐ + 8 PENDING ์ ์ง ๋ช ์.
agency-v2๊ฐ ์ค ์๋ํ๋ NestJS API + PG + Redis + MinIO + JWT Auth + Role-based access control + 4-tier DB user + integrity manifest ๊น์ง ์์ฑ๋จ. CRUD 6๊ฐ ์ก์ ๋ชจ๋ E2E PASS.
S3์์ ํต์ฌ ๋ชจ๋ ์ถ๊ฐ ์์ ์ Multi-tenant middleware ์ ์ฉ + AI orchestrator ๊ฐ๋ โ ๋น์ฆ๋์ค ๊ฐ์น ์ฆ์ ์ฒด๊ฐ ์์.
โ S2-B ๋ณด๊ณ ๋ โ