2. 아키텍처
코드베이스가 어떻게 구성되어 있고, 반드시 지켜야 하는 규칙은 무엇인지. 권위 있는 원본은
ARCHITECTURE.md— 여기서는 인계 핵심만 요약합니다.
2.1 모노레포 구조
- Turborepo + Bun workspaces. 메인 앱은
apps/web(Nuxt 4) 하나, 나머지는packages/*공유 패키지. packages/:ui(공유 컴포넌트),logger(환경별 로깅),eslint-config,typescript-config,vitest-config,e2e-web(Playwright)- 진입점 파일:
apps/web/nuxt.config.ts— Nuxt 설정(모듈, i18n, Tailwind, Nitro)apps/web/server/routes/rpc/[...].ts— 모든 API의 단일 진입점apps/web/server/orpc/routers/index.ts— 전체 API 구조apps/web/prisma/schema.prisma— DB 스키마
2.2 API 레이어 — oRPC
- 모든 API는 단일
/rpc엔드포인트로 서비스 (타입 안전 RPC). - 흐름:
클라이언트 → /rpc/[...] → RPCHandler → 라우터 → 미들웨어 체인 → 핸들러 - 인증 3단계 base procedure:
pub(공개) /authed(로그인) /admin(관리자) - SSR 분기:
02.orpc.client.ts(CSR, RPCLink HTTP) vs02.orpc.server.ts(SSR, createRouterClient 직접 호출 — 네트워크 우회) - 상태 관리: TanStack Vue Query.
useFetch대신 oRPCqueryOptions/mutationOptions사용(반응형 입력은computed()로 래핑).
2.3 인증 — Better Auth
- Better Auth 기반. SSR에서는 세션 쿠키
__session으로 인증. - 7개 라우트 미들웨어로 역할별 접근 제어 (auth 중심).
- SSR 세션은
02.orpc.server.ts에서 context에 주입.
2.4 보고서 시스템
- 리포트 A/B/C/D, 3개 독립 API 경로:
| API | 경로 | 사용처 |
|---|---|---|
$orpc.reports.* | routers/reports/ | 개인 (/my/reports) |
$orpc.org.reports.* | routers/org/reports.ts | 기업 (/org/[orgId]/reports) |
$orpc.admin.reports.* | routers/admin/reports.ts | 관리자 (/admin/reports) |
- 데이터 흐름:
DB → Router → useReportData composable → Report[A|B|C|D].vue - ⚠️ 3중 동기화 규칙: 보고서 필드 추가 시 스키마(3) · 라우터(3) · 페이지(4) 모두 수정. 한 곳이라도 빠지면 데이터가 UI에 안 나타남.
2.5 데이터 모델
- Prisma ORM, 스키마:
apps/web/prisma/schema.prisma - 핵심 엔티티: User/Account/Session(Better Auth), Organization, DiagnosisRequest, DiagnosisSession, Report(A/B/C/D), Voucher(이용권), ReportComment(CSV 시드)
2.6 아키텍처 불변식
코드베이스 전체에서 반드시 지켜야 하는 제약 (출처:
ARCHITECTURE.md§Architecture Invariants)
useFetch금지 — 새 API는 oRPC만.console직접 사용 금지 —@repo/logger의createModuleLogger(tag).npx금지 —bunx사용.- 보고서 API 3중 동기화 (위 2.4).
- 상품명 통일 — 공식명칭만 사용.
- oRPC 미들웨어 체인 —
.$context<T>()를 체인 중간에 쓰면 끊김. base procedure에서만. - Auth 리다이렉트 루프 방지 — 인증 미완료 페이지에서 로그인 이동 시
signOut()후 이동 (9장 참조). - Tailwind v4 동적 클래스 제한 — JIT 정적 스캔만. 동적 문자열 조합 금지, CVA 사용.