# 웹 앱 (React)

메모를 쓰고 태그를 본다. Vite + React 19 + TanStack Query (:5280). 클라이언트 공통 규칙은 `docs/clients.md`, 이 파일이 이 앱에서는 우선한다.

## 구조

```
index.html               # 진입 HTML
src/
├── main.tsx             # 진입점: QueryClientProvider 하나 · style.css
├── App.tsx              # 메모 화면: 목록(태그 칩) · 추가 · 삭제. useQuery · useMutation
└── style.css            # 색 토큰(라이트/다크) · 화면 스타일
vite.config.ts           # 개발 서버 :5280 · /api 프록시
package.json · tsconfig.json
Dockerfile               # 이미지: dist 를 nginx 가 내주고 /api 는 API_URL(실행할 때, 기본 http://gateway:8003)로 (clients/nginx.conf.template)
```

## 명령

```bash
pnpm dev · build · typecheck · lint · format   # vite (:5280) · vite build · tsc -p . (TS 7) · oxlint · oxfmt
docker build --build-context workspace=../../.. .   # 이미지 (이 폴더에서)
```

## 규칙

- 서버: notes 하나. `createClient<notes.paths>({ name: 'notes' })` (같은 출처). vite 프록시가 `/api` 를 `API_URL`(기본 gateway :8003)로 넘기고, gateway 가 notes 로 보낸다.
- 화면은 `useQuery(api.query(경로))`, 만들기 · 지우기는 `useMutation` 뒤 `invalidateQueries({ queryKey: api.query('/api/notes').queryKey })`.
- 태그는 notes 가 저장할 때 붙여 돌려준다(tags 서버를 부르지 않는다). 화면은 DESIGN.md 의 Tag 칩으로만 보여 준다.
- `react` · `react-dom` 버전은 카탈로그가 정한다(정확히 같은 버전, `docs/clients.md`). 이 앱에서 따로 올리지 않는다.