Skip to content

Commit 81f642f

Browse files
sumi-0011claudesumi
authored
feat: Tailwind 마이그레이션 및 FSD 아키텍처 리팩토링 (#373)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: sumi <sumi@sumiui-MacBookAir.local>
1 parent b3bf9c4 commit 81f642f

255 files changed

Lines changed: 1517 additions & 1264 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
description: apps/web 프로젝트 코드 작성 시 FSD-inspired 하이브리드 아키텍처 규칙을 적용합니다.
3+
globs:
4+
- apps/web/src/**/*.ts
5+
- apps/web/src/**/*.tsx
6+
alwaysApply: false
7+
---
8+
9+
# apps/web FSD 아키텍처 규칙
10+
11+
## 레이어 구조와 의존성
12+
13+
apps/web은 FSD-inspired 하이브리드 아키텍처를 사용합니다.
14+
15+
```
16+
src/
17+
├── app/ # 라우팅 + 조합 (Next.js App Router)
18+
├── widgets/ # 독립적 대규모 UI 블록
19+
├── features/ # 사용자 액션 기능
20+
├── entities/ # 비즈니스 엔티티
21+
├── shared/ # 범용 기반 코드
22+
├── components/ # [레거시] 새 파일 추가 금지
23+
└── middleware.ts
24+
```
25+
26+
의존성 규칙: `app/ → widgets/ → features/ → entities/ → shared/`
27+
28+
## 핵심 규칙
29+
30+
1. **상위 레이어는 하위 레이어만 import 가능**
31+
- features/는 entities/와 shared/만 import
32+
- entities/는 shared/만 import
33+
- shared/는 외부 패키지만 import
34+
35+
2. **같은 레이어 슬라이스 간 import 금지**
36+
- entities/persona/에서 entities/guild/ import 불가
37+
- features/auction/에서 features/feedback/ import 불가
38+
39+
3. **components/ 디렉토리에 새 파일 추가 금지**
40+
- 새 코드는 반드시 적절한 FSD 레이어에 배치
41+
- 도메인 무관 UI → shared/ui/
42+
- 도메인 관련 UI → entities/*/ui/
43+
- 기능 UI → features/*/ui/
44+
- 대규모 조합 블록 → widgets/
45+
46+
4. **각 슬라이스는 barrel index.ts 제공**
47+
```typescript
48+
// entities/persona/index.ts
49+
export * from './ui';
50+
export * from './model';
51+
```
52+
53+
## 새 코드 배치 기준
54+
55+
| 코드 유형 | 배치 위치 | 예시 |
56+
|---|---|---|
57+
| 라우트 전용 UI | `app/[locale]/*/_components/` | 페이지별 폼, 섹션 |
58+
| 범용 UI (도메인 무관) | `shared/ui/` | Modal, Button |
59+
| 엔티티 UI | `entities/*/ui/` | PersonaItem, GuildCard |
60+
| 엔티티 쿼리/로직 | `entities/*/model/` | useGetAllPersona |
61+
| 사용자 액션 | `features/*/model/` | useRegisterProduct |
62+
| API 호출 함수 | `features/*/api/` 또는 `shared/api/` | github.ts |
63+
| 독립 대규모 블록 | `widgets/*/` | GNB |
64+
| 유틸리티 | `shared/utils/` | image.ts, string.ts |
65+
| 상수/설정 | `shared/config/` | env.ts, route.ts |
66+
| hooks (범용) | `shared/hooks/` | usePagination |
67+
68+
## 슬라이스 내부 구조
69+
70+
```
71+
features/auction/
72+
├── api/ # API 호출 함수
73+
├── model/ # hooks, 상태, 비즈니스 로직
74+
├── ui/ # UI 컴포넌트
75+
└── index.ts # public API (barrel export)
76+
```
77+
78+
## import 스타일
79+
80+
```typescript
81+
// 외부 패키지
82+
import { useQuery } from '@tanstack/react-query';
83+
import { getAllPersona } from '@gitanimals/api';
84+
85+
// FSD 레이어 (절대경로 @/)
86+
import GNB from '@/widgets/gnb/GNB';
87+
import { AnimalCard } from '@/entities/persona';
88+
import { getPersonaImage } from '@/shared/utils/image';
89+
90+
// 같은 슬라이스 내 (상대경로)
91+
import { useGetAllPersona } from './useGetAllPersona';
92+
```
93+
94+
## `@gitanimals/*` 패키지
95+
96+
모노레포 패키지는 외부 shared 계층으로 취급합니다.
97+
entities, features에서 직접 import 허용:
98+
99+
```typescript
100+
import { getAllPersona } from '@gitanimals/api'; // OK
101+
import { cn } from '@gitanimals/ui-tailwind'; // OK
102+
import { userQueries } from '@gitanimals/react-query'; // OK
103+
```
104+
105+
## 상세 가이드
106+
107+
전체 아키텍처 가이드는 `apps/web/ARCHITECTURE.md`를 참조하세요.

.github/workflows/chromatic.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Chromatic - UI Storybook
2+
3+
on:
4+
push:
5+
branches:
6+
- dev
7+
paths:
8+
- 'packages/ui/tailwind/**'
9+
10+
env:
11+
DEFAULT_NODE_VERSION: '20.11.0'
12+
PNPM_VERSION: '9.0.6'
13+
14+
jobs:
15+
chromatic:
16+
name: Publish Storybook
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Install pnpm
25+
uses: pnpm/action-setup@v4
26+
with:
27+
version: ${{ env.PNPM_VERSION }}
28+
run_install: false
29+
30+
- name: Setup Node
31+
uses: actions/setup-node@v4
32+
with:
33+
node-version: ${{ env.DEFAULT_NODE_VERSION }}
34+
cache: 'pnpm'
35+
36+
- name: Install dependencies
37+
run: pnpm install
38+
39+
- name: Run Chromatic
40+
uses: chromaui/action@latest
41+
with:
42+
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
43+
workingDir: packages/ui/tailwind
44+
exitOnceUploaded: true

CLAUDE.md

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,32 @@ GitAnimals is a monorepo that allows users to raise virtual pets through GitHub
2121
- `packages/util/*` - Utility packages (common, typescript)
2222

2323
**Key Technologies:**
24-
- **Styling:** PandaCSS with Shadow Panda preset for component styling
25-
- **State Management:** Tanstack Query v5 (server state), Jotai & Zustand (client state)
24+
- **Styling:** Tailwind CSS (migrating from PandaCSS)
25+
- **State Management:** Tanstack Query v5 (server state), Jotai (client state)
2626
- **Authentication:** NextAuth.js (web), token-based auth (webview)
27-
- **UI Components:** Radix UI primitives + custom PandaCSS components
27+
- **UI Components:** Radix UI primitives + `@gitanimals/ui-tailwind`
2828
- **Package Manager:** pnpm v9.0+ with workspace configuration
2929
- **Build System:** Turborepo for orchestration
3030

31+
**Web App Architecture (FSD-inspired Hybrid):**
32+
33+
apps/web은 FSD(Feature-Sliced Design) 기반 하이브리드 아키텍처를 사용합니다.
34+
상세 가이드: [`apps/web/ARCHITECTURE.md`](apps/web/ARCHITECTURE.md)
35+
36+
```
37+
src/
38+
├── app/ # Next.js App Router (라우팅 + 조합, FSD app+pages 역할)
39+
├── widgets/ # 독립적 대규모 UI 블록 (GNB 등)
40+
├── features/ # 사용자 액션 기능 (auction, auth, feedback 등)
41+
├── entities/ # 비즈니스 엔티티 (persona, guild, user, product)
42+
├── shared/ # 범용 기반 코드 (api, config, hooks, i18n, lib, store, utils)
43+
├── components/ # [레거시] 점진적으로 shared/ui/ 또는 entities/*/ui/로 이전
44+
└── middleware.ts
45+
```
46+
47+
의존성 규칙: `app/ → widgets/ → features/ → entities/ → shared/`
48+
상위 레이어는 하위 레이어만 import 가능. 같은 레이어 슬라이스 간 import 금지.
49+
3150
## Development Commands
3251

3352
**Root-level commands (run from project root):**
@@ -68,20 +87,23 @@ pnpm --filter @gitanimals/ui-panda storybook # Start Storybook
6887

6988
## Code Patterns & Conventions
7089

71-
**Component Architecture:**
72-
- UI components in `packages/ui/panda/src/components/`
73-
- Each component has: `Component.tsx`, `Component.stories.tsx`, `index.ts`
74-
- PandaCSS styling with design tokens from `packages/ui/token`
90+
**Component Architecture (apps/web):**
91+
- FSD 레이어 구조: `shared/ → entities/ → features/ → widgets/ → app/`
92+
- 각 슬라이스는 `ui/`, `model/`, `api/` 세그먼트와 barrel `index.ts`로 구성
93+
- 라우트 전용 UI는 `app/[locale]/*/_components/`에 코로케이션
94+
- 도메인 무관 공유 UI는 `shared/ui/` 또는 `components/`(레거시)
7595

7696
**Import Patterns:**
7797
- Workspace dependencies use `workspace:*` protocol
78-
- UI components imported from `@gitanimals/ui-panda`
98+
- UI components imported from `@gitanimals/ui-tailwind`
7999
- Shared utilities from `@gitanimals/util-common`
100+
- Web app 내부는 `@/` alias 사용 (→ `src/`)
101+
- FSD 의존성 규칙 준수: `@/shared/`, `@/entities/`, `@/features/`, `@/widgets/`
80102

81103
**State Management:**
82-
- Server state: Tanstack Query v5 with `queryOptions` pattern in `src/apis/`
83-
- Client state: Jotai for atomic state, Zustand for stores
84-
- Auth state managed through NextAuth.js
104+
- Server state: Tanstack Query v5 in `entities/*/model/``features/*/model/`
105+
- Client state: Jotai atoms in `shared/store/`
106+
- Auth state managed through NextAuth.js (`shared/api/auth.ts`)
85107

86108
**Tanstack Query v5 Best Practices:**
87109
- Always use `queryOptions` factory pattern for reusable query definitions
@@ -120,7 +142,7 @@ pnpm --filter @gitanimals/ui-panda storybook # Start Storybook
120142

121143
// Usage in component
122144
import { useQuery } from '@tanstack/react-query';
123-
import { userQueryOptions } from '@/apis/user/queries';
145+
import { userQueryOptions } from '@/entities/user/model/queries';
124146

125147
function UserProfile({ userId }: { userId: string }) {
126148
const { data: user } = useQuery(userQueryOptions.getUser(userId));
@@ -139,10 +161,10 @@ pnpm --filter @gitanimals/ui-panda storybook # Start Storybook
139161
- No need for custom hooks unless adding extra logic
140162

141163
**Styling Approach:**
142-
- PandaCSS with `styled-system` generation
143-
- Shadow Panda preset for enhanced component styling
144-
- Responsive design using PandaCSS conditions (mobile/desktop)
145-
- Design tokens centralized in `packages/ui/token`
164+
- Tailwind CSS (migrating from PandaCSS)
165+
- `@gitanimals/ui-tailwind` 디자인 시스템 컴포넌트
166+
- Responsive design using Tailwind breakpoints
167+
- `cn()` utility for conditional class merging
146168

147169
## Testing & Quality
148170

@@ -155,7 +177,7 @@ pnpm --filter @gitanimals/ui-panda storybook # Start Storybook
155177

156178
- `turbo.json` - Build pipeline configuration
157179
- `pnpm-workspace.yaml` - Workspace definition
158-
- `apps/*/panda.config.ts` - PandaCSS configuration per app
180+
- `apps/web/ARCHITECTURE.md` - **FSD 아키텍처 상세 가이드 (필독)**
159181
- `packages/ui/panda/src/theme/` - Design system tokens and styles
160182

161183
## Build Pipeline Dependencies
@@ -167,7 +189,9 @@ The build system has specific dependency chains:
167189

168190
## Notes for Development
169191

170-
- Always run `panda codegen` after theme changes
171192
- UI component changes require Storybook restart
172193
- Mobile app uses Expo SDK ~53.0.17 with React Native 0.79.5
173-
- Web app uses Next.js App Router with internationalization (next-intl)
194+
- Web app uses Next.js App Router with internationalization (next-intl)
195+
- **apps/web 작업 시 반드시 FSD 의존성 규칙을 따를 것** (상세: `apps/web/ARCHITECTURE.md`)
196+
- 새 코드는 반드시 `shared/`, `entities/`, `features/`, `widgets/` 중 적절한 레이어에 배치
197+
- `components/`(레거시)에 새 파일 추가 금지 — 적절한 FSD 레이어 사용

0 commit comments

Comments
 (0)