ArchitectureMonorepo 구조

Monorepo 구조

기준 FE v0.20.0 (linkmusic-frontend-space) — 2026-06-04. pnpm workspace.

Overview

linkmusic-frontend-space 는 pnpm workspace 모노레포. Turborepo 미도입 — 1인 + 패키지 5개 규모에서 pnpm -r 로 충분. 백엔드는 별도 git 레포 (linkmusic-msa-space-was) — 같은 워크스페이스 부모 폴더 (linkmusic-space/) 에서 함께 보지만 한 commit에 섞지 않는다.

구조

linkmusic-frontend-space/   (FE git repo)
├── apps/
│   ├── admin/              Next.js 16 · App Router · iron-session BFF · 운영사 백오피스 (admin.linkmusic.space)
│   ├── space/              Next.js 16 · App Router · iron-session BFF · 매장 클라이언트 (본사+점장 · space.linkmusic.io)
│   └── docs/               Next.js 15 · Nextra v3 · MDX (이 문서)
├── packages/
│   ├── ui/                 OKLCH v2 토큰 + shells + atoms (source-only · no build)
│   ├── api-client/         orval generated · OpenAPI 단일 소스 · `pnpm sync` 진입점
│   └── config/             eslint + tsconfig (base · next · react-lib) + tailwind preset
├── pnpm-workspace.yaml     packages: apps/* · packages/*
├── tsconfig.base.json
├── package.json            workspace root scripts (dev · build · lint · typecheck · sync-api)
├── .nvmrc                  20.20.2 (engines.node 최소 호환 patch)
└── .npmrc                  engine-strict=true · strict-peer-dependencies=false

워크스페이스 root scripts

{
  "scripts": {
    "dev": "pnpm --filter @linkmusic/admin dev",
    "dev:space": "pnpm --filter @linkmusic/space dev",
    "build": "pnpm -r build",
    "lint": "pnpm -r lint",
    "typecheck": "pnpm -r typecheck",
    "test": "pnpm -r test",
    "sync-api": "pnpm --filter @linkmusic/api-client sync"
  }
}

패키지 간 의존

  • workspace:* 로 명시
  • @linkmusic/uisource-onlynext.config.mjstranspilePackages 로 처리

워크스페이스 부모 (linkmusic-space/)

linkmusic-space/   ← 부모 폴더 (git repo 아님)
├── linkmusic-frontend-space/        FE 레포 (이 레포)
├── linkmusic-msa-space-was/         BE 레포 (Kotlin · Spring)
├── design_handoff_linkmusic/        디자인 handoff (다른 디렉토리)
├── docs/                            SPEC · 기획 · jira task
│   ├── specs/
│   ├── planning/
│   └── jira/
└── CLAUDE.md                        워크스페이스 가이드

이 부모 폴더 자체는 git 레포 X — 두 레포를 한 IDE 에서 함께 보기 위함.

Constraints

  • 두 레포 변경을 한 commit 에 섞지 말 것. FE / BE 각자 commit.
  • 백엔드 OpenAPI 가 단일 소스packages/api-client 는 generated. 수기 type 정의 금지.
  • Tailwind 토큰 단일 소스packages/ui/src/styles/tokens.css (Layer 1 · 2 · 3). apps 는 import만.
  • font import 는 apps globals.css 에서 — Tailwind v4 가 :root theme layer 를 emit 하므로 ui 패키지 내부 @import 가 다른 룰 뒤로 밀려 경고가 남. apps/admin·apps/docs globals.css 의 최상단이 책임 ([[feedback-9]]).
  • Node 버전 핀.nvmrc + engines.node 패치 버전. Vercel monorepo 의 sub-app Root Directory 도 각자 .nvmrc 사본 + engines.node + packageManager ([[feedback-9]]).
  • apps/space 의 auth/BFF 는 apps/admin 복제lib/{env,session,refresh,csrf,error,theme-cookie, query-provider,load-me,backend} · api/backend/[...path] · api/auth/* · middleware.ts 를 앱별로 복제한다 (SPEC #050 §D2). admin 무회귀 + 세션 형상 독립이 목적. 공유 패키지 추출은 후속 리팩터(§F4). 복제 시 군더더기 제거: space backend.tscallBackend + auth 4 helper + backendHqMe 만, session 은 임퍼소네이션 필드 제외(cookie lm_space_session), middleware isPublic 은 admin 의 impersonation bypass 제외.

워크플로우

  • 새 패키지 추가 시 pnpm-workspace.yamlpackages: 패턴은 이미 apps/* · packages/* 매칭이므로 변경 불필요.
  • 새 SPEC 작업 시 feature/<slug> 브랜치. develop 에 squash, developmain 은 merge commit.
  • 한 commit 에 BE / FE 섞지 말 것 — /commit skill 이 변경 레포 분류.

Roadmap

  • Turborepo 도입은 빌드 캐시 필요 시점 (현재 빌드 < 30s).
  • Storybook for packages/ui (시각 카탈로그).
  • changesets 도입 검토 (현재는 GitHub Release 로 release 관리).

References

  • linkmusic-frontend-space/pnpm-workspace.yaml
  • linkmusic-frontend-space/package.json
  • linkmusic-frontend-space/tsconfig.base.json
  • 워크스페이스 CLAUDE.md
  • SPEC #006 §2-2