## 테스트 설정
### 공통 - Playwright (E2E)
```javascript
// playwright.config.mjs (동일)
export default {
testDir: './tests/e2e',
timeout: 30000,
use: {
headless: true,
viewport: { width: 1920, height: 1080 },
ignoreHTTPSErrors: true,
baseURL: 'http://localhost:8080'
},
reporter: [['list'], ['html', { outputFolder: 'playwright-report' }]]
}
```
### main - Vitest
```javascript
// vitest.config.js
import vue from '@vitejs/plugin-vue' // Vue 3 플러그인
export default defineConfig({
plugins: [vue()],
test: {
environment: 'jsdom',
globals: true,
silent: true,
exclude: ['**/node_modules/**', '**/tests/e2e/**']
}
})
```
### staging - Vitest
```javascript
// vitest.config.js
import { createVuePlugin } from 'vite-plugin-vue2' // Vue 2 플러그인
export default defineConfig({
plugins: [createVuePlugin()],
test: { environment: 'jsdom', globals: true, silent: true }
})
```
## 환경변수
### main (Vite - `VITE_` 접두사)
```bash
# .env.example / .env.dist
VITE_SENTRY_ENV=production
VITE_I18N_LOCALE=ko
VITE_I18N_FALLBACK_LOCALE=en
VITE_API_BASE_URL=
VITE_WORKSPACE_BASE_URL=https://test.synapse.sh
VITE_LOGIN_REDIRECT_PATH=/auth/login
VITE_PROJECT_LIST_REDIRECT_PATH=/projects
VITE_DEV_AUTH_TOKEN=
VITE_DEV_TENANT_TOKEN=
```
접근: `import.meta.env.VITE_*`
### staging (Webpack - `VUE_APP_` 접두사)
```bash
# .env.example / .env.dist
NODE_ENV=production
VUE_APP_SENTRY_ENV=production
DEPLOYMENT_TARGET=production
VUE_APP_I18N_LOCALE=ko
VUE_APP_I18N_FALLBACK_LOCALE=en
VUE_APP_API_BASE_URL=
VUE_APP_WORKSPACE_BASE_URL=https://test.synapse.sh
VUE_APP_LOGIN_REDIRECT_PATH=/auth/login
```
접근: `process.env.VUE_APP_*`
### 환경변수 매핑
| 용도 | main (`VITE_`) | staging (`VUE_APP_`) |
|------|-------------|-------------------|
| Sentry 환경 | `VITE_SENTRY_ENV` | `VUE_APP_SENTRY_ENV` |
| i18n 로케일 | `VITE_I18N_LOCALE` | `VUE_APP_I18N_LOCALE` |
| i18n 폴백 | `VITE_I18N_FALLBACK_LOCALE` | `VUE_APP_I18N_FALLBACK_LOCALE` |
| API URL | `VITE_API_BASE_URL` | `VUE_APP_API_BASE_URL` |
| 워크스페이스 URL | `VITE_WORKSPACE_BASE_URL` | `VUE_APP_WORKSPACE_BASE_URL` |
| 로그인 리다이렉트 | `VITE_LOGIN_REDIRECT_PATH` | `VUE_APP_LOGIN_REDIRECT_PATH` |
## 기타 설정 파일
### main 전용
| 파일 | 용도 |
|------|------|
| `pnpm-workspace.yaml` | pnpm 워크스페이스 설정 (onlyBuiltDependencies) |
| `.npmrc` | `auto-install-peers=true`, `strict-peer-dependencies=false`, `shamefully-hoist=true` |
| `tailwind.config.js` | Tailwind CSS 4 커스텀 설정 |
### staging 전용
| 파일 | 용도 |
|------|------|
| `webpack.config.cjs` | Webpack 5 빌드 설정 |
| `babel.config.js` | Babel 트랜스파일 + 경로 별칭 + 프로덕션 console 제거 |
| `package-lock.json` | npm 락파일 |
| `.hintrc` | webhint 설정 (`-webkit-user-drag` 호환성 무시) |
### 공통
| 파일 | 용도 |
|------|------|
| `tsconfig.json` | TypeScript 설정 |
| `eslint.config.mjs` | ESLint 9 Flat Config |
| `.prettierrc.json` | Prettier 설정 |
| `.prettierignore` | Prettier 제외 대상 |
| `postcss.config.js` | PostCSS 플러그인 |
| `vitest.config.js` | Vitest 단위 테스트 |
| `playwright.config.mjs` | Playwright E2E 테스트 |
| `.husky/pre-commit` | lint-staged 실행 |
| `.gitattributes` | `*.wasm binary` |
| `.markdownlint.json` | Markdown 린팅 규칙 |
| `.env.example` / `.env.dist` | 환경변수 템플릿 |
## 디렉토리 구조
### main (Vue 3.x)
```
synapse-annotator/
├── index.html # Vite 엔트리 HTML
├── vite.config.js # Vite 빌드 설정
├── tailwind.config.js # Tailwind CSS 설정
├── pnpm-workspace.yaml # pnpm 워크스페이스
├── .npmrc # pnpm 설정
├── package.json
├── tsconfig.json
├── eslint.config.mjs
├── .prettierrc.json
├── postcss.config.js
├── vitest.config.js
├── playwright.config.mjs
├── src/
│ ├── main.js # 앱 엔트리포인트
│ ├── i18n.js # i18n 설정
│ ├── plugins/
│ │ ├── index.js # 플러그인 등록
│ │ ├── components.js # 글로벌 컴포넌트
│ │ └── sentry.js # Sentry 초기화
│ ├── app/
│ │ ├── app.vue # 루트 컴포넌트
│ │ ├── app-routes.js # Vue Router 4
│ │ ├── app-store.js # Vuex 4
│ │ ├── annotator/
│ │ │ ├── annotators/ # 어노테이터별 구현
│ │ │ ├── services/
│ │ │ ├── store/
│ │ │ └── routes/
│ │ ├── dashboard/
│ │ └── shared/
│ ├── assets/
│ └── locales/ # i18n JSON (ko, en)
├── tests/
│ ├── unit/
│ └── e2e/
├── wasm/ # WASM 모듈
│ ├── annotator/
│ ├── image-annotator/
│ └── wasm-utils/
└── dist/ # 빌드 출력
```
### staging (Vue 2.x)
```
synapse-annotator/
├── public/
│ └── index.html # Webpack 템플릿 HTML
├── webpack.config.cjs # Webpack 빌드 설정
├── babel.config.js # Babel 설정
├── package.json
├── package-lock.json # npm 락파일
├── tsconfig.json
├── eslint.config.mjs
├── .prettierrc.json
├── postcss.config.js
├── vitest.config.js
├── playwright.config.mjs
├── src/
│ ├── main.js # 앱 엔트리포인트
│ ├── i18n.js # i18n 설정
│ ├── vue-shim.d.ts # Vue 타입 선언
│ ├── app/
│ │ ├── app.vue # 루트 컴포넌트
│ │ ├── app-routes.js # Vue Router 3
│ │ ├── app-store.js # Vuex 3
│ │ ├── annotator/
│ │ │ ├── annotators/
│ │ │ ├── services/
│ │ │ ├── store/
│ │ │ └── routes/
│ │ ├── dashboard/
│ │ └── shared/
│ ├── assets/
│ └── locales/
├── tests/
├── wasm/
├── docker/ # Docker 설정
├── docs/
└── dist/
```
## 경로 별칭 (Path Aliases)
| Alias | 경로 | main (vite) | main (tsconfig) | staging (webpack) | staging (babel) | staging (tsconfig) |
|-------|------|:-----------:|:---------------:|:-----------------:|:---------------:|:------------------:|
| `@` | `src/` | O | O | O | O | O |
| `@app` | `src/app/` | O | O | O | O | X |
| `@assets` | `src/assets/` | O | O | O | O | X |
| `@ia` | `src/app/annotator/annotators/image-annotator/` | O | O | O | O | X |
| `@pa` | `src/app/annotator/annotators/pcd-annotator/` | O | O | O | O | X |
| `@ta` | `src/app/annotator/annotators/text-annotator/` | O | O | O | O | X |
| `@va` | `src/app/annotator/annotators/video-annotator/` | O | O | O | O | X |
| `@aa` | `src/app/annotator/annotators/audio-annotator/` | O | O | X | X | X |
| `@pta` | `src/app/annotator/annotators/prompt-annotator/` | O | O | O | O | X |
| `@services` | `src/app/annotator/services/` | O | O | X | X | X |
| `@shared` | `src/app/shared/` | O | O | X | X | X |
:::caution[중요]
CLI 프로젝트 생성 시 별칭 설정은 빌드 도구(vite/webpack)와 tsconfig에 모두 동기화해야 합니다.
:::