프로젝트 문서 체계 정비
This commit is contained in:
349
docs/spec.md
349
docs/spec.md
@@ -1,45 +1,38 @@
|
||||
# 기술 명세
|
||||
|
||||
## 1. 프로젝트 개요
|
||||
- 프로젝트명: `UNIARE - Union Arena Deck Builder` (표시명 UNIARE, 내부 API 식별자 일부는 `uadeck` 레거시 유지)
|
||||
- 형태: 정적 HTML/CSS/JavaScript 프론트 + Docker API 백엔드
|
||||
- 패키지 의존성 (프론트): `tailwindcss`, `@tailwindcss/cli`
|
||||
- 패키지 의존성 (API): `express`, `better-sqlite3`, `bcryptjs`, `jsonwebtoken`, `cors`
|
||||
- 빌드 산출 스타일: `style/output.css`
|
||||
## 프로젝트 개요
|
||||
|
||||
## 2. 화면 구조
|
||||
- 서비스명: `UNIARE - Union Arena Deck Builder`
|
||||
- 현재 버전: `v4.0.1`
|
||||
- 프론트: 정적 HTML, CSS, JavaScript
|
||||
- 백엔드: Express, SQLite(`better-sqlite3`)
|
||||
- 운영: Docker Compose 기반 Nginx + API
|
||||
- 지원 언어: 한국어, 일본어, 영어
|
||||
- 표시 브랜드는 `UNIARE`이며 `UaDeckApi`, `uadeck_token`, `uadeck.db` 등 내부 레거시 식별자는 호환을 위해 유지한다.
|
||||
|
||||
### `/index.html`
|
||||
- 시리즈 선택 랜딩 페이지다.
|
||||
- `i18n/translations.<lang>.json`을 직접 fetch하여 시리즈명과 소개 문구를 렌더링한다.
|
||||
- 사용자가 시리즈를 선택하면 `cardList.html?series=<key>&seriesName=<name>&lang=<lang>`로 이동한다.
|
||||
## 화면 기능
|
||||
|
||||
### `/cardList.html`
|
||||
- 특정 시리즈의 카드 목록을 보여주고 덱을 편집한다.
|
||||
- 쿼리스트링의 `series` 값을 기준으로 `./datas/${seriesKey}.js`를 동적 import 한다.
|
||||
- 필터 기능:
|
||||
- 검색어
|
||||
- 색상(`All`, `Red`, `Blue`, `Green`, `Yellow`, `Purple`)
|
||||
- 시리즈 하위 그룹
|
||||
- 타입(`Basic`, `AP`, `Parallel`)
|
||||
- 트리거(`All`, `Special`, `Color`, `Final`)
|
||||
- 카드 수량 증감, 키 카드 지정, 초기화, 상세 오버레이, 결과 페이지 이동을 담당한다.
|
||||
| 경로 | 기능 |
|
||||
|---|---|
|
||||
| `/` | 시리즈 선택, 언어 전환, 인증 헤더 |
|
||||
| `/cardList.html?series=<key>` | 카드 검색·필터, 수량 조절, 키 카드 지정, 덱 편집 |
|
||||
| `/cardList.html?d=<shareCode>` | API 공유 덱 불러오기 및 편집 |
|
||||
| `/result.html` | 덱 미리보기, PNG 다운로드, 덱 저장 |
|
||||
| `/login.html` | 로그인 |
|
||||
| `/signup.html` | 회원가입 |
|
||||
| `/profile.html` | 이메일·사용자명·아바타·비밀번호·덱 공개 기본값 관리 |
|
||||
| `/deckHistory.html` | 내 덱 검색·필터·이름 변경·공개 설정·삭제·불러오기 |
|
||||
| `/preset.html` | 공개 사용자 덱 검색·필터·즐겨찾기·불러오기 |
|
||||
| `/admin.html` | 회원과 덱 관리 |
|
||||
| `/d/<shareCode>` | Nginx에서 `cardList.html?d=<shareCode>`로 연결 |
|
||||
|
||||
### `/result.html`
|
||||
- 선택한 카드 목록을 미리보기하고 이미지로 저장한다.
|
||||
- 스타일 모드:
|
||||
- `type1`: 키 카드 강조형
|
||||
- `type2`: 클래식 5열형
|
||||
- `html-to-image` CDN을 사용해 덱 이미지를 PNG로 저장한다.
|
||||
## 카드 데이터
|
||||
|
||||
## 3. 데이터 구조
|
||||
- 데이터 위치: `datas/*.js`
|
||||
- 실제 시리즈 데이터: `ua01`~`ua54` 중 현재 존재하는 파일과 `uapr.js`
|
||||
- 샘플 데이터: `ua99 sample.js`, `ua99 sample mini.js`
|
||||
- 모듈 형식: `export const cardList = [...]`
|
||||
|
||||
### 카드 데이터 파일
|
||||
- 위치: `datas/*.js`
|
||||
- 파일 수: 현재 `52개`
|
||||
- 각 파일은 `export const cardList = [...]` 형태를 사용한다.
|
||||
|
||||
### 카드 객체 스키마
|
||||
```js
|
||||
{
|
||||
imgSrc: '/ua24/UA24BT_SHY-1-001.png',
|
||||
@@ -50,209 +43,143 @@
|
||||
parallel: false,
|
||||
rarity: 'C',
|
||||
trigger: null,
|
||||
maxCount: 4,
|
||||
}
|
||||
```
|
||||
|
||||
### 필드 의미
|
||||
- `imgSrc`: 원본 상대 식별자. 실제 렌더링 시 `images/${seriesKey}/${fileName}` 형태로 재구성한다.
|
||||
- `Number`: 카드 번호. 동일 카드 판본 묶음과 필터 기준으로 사용한다.
|
||||
- `count`: 현재 덱에 담긴 수량.
|
||||
- `key`: 키 카드 여부.
|
||||
- `color`: 카드 색상 또는 일부 특수 분류 값.
|
||||
- `parallel`: 패러렐 여부.
|
||||
- `rarity`: 희귀도 표기.
|
||||
- `trigger`: `null`, `COLOR`, `FINAL`, `SPECIAL` 등 트리거 정보.
|
||||
- `maxCount`: 일부 카드만 선택적으로 사용하며 기본값은 `4`로 동작한다.
|
||||
- `Number`가 같은 판본은 동일 카드 수량 그룹으로 처리한다.
|
||||
- `parallel`은 패러렐 판본 구분에 사용한다.
|
||||
- `trigger`는 `null`, `COLOR`, `FINAL`, `SPECIAL` 값을 사용한다.
|
||||
- `maxCount`가 없으면 기본 최대 수량은 4장이다.
|
||||
|
||||
## 4. 이미지 규칙
|
||||
- 기본 위치: `images/<seriesKey>/`
|
||||
- 저장 정책: `images/**`는 `Git LFS` 대상으로 관리한다.
|
||||
- 렌더링 규칙:
|
||||
- 카드 목록 화면: `images/${seriesKey}/${fileName}`
|
||||
- 결과 화면: `/images/${seriesKey}/${fileName}`
|
||||
## 이미지
|
||||
|
||||
- 카드 이미지: `images/<seriesKey>/<fileName>`
|
||||
- 폴백 이미지: `/images/uapr/comingsoon.png`
|
||||
- 현재 용량 현황:
|
||||
- `images/` 약 `1.7G`
|
||||
- 이미지 파일 약 `9,370개`
|
||||
- 브랜드 자산: `images/assets/`
|
||||
- `images/**`는 Git LFS로 관리한다.
|
||||
- 아바타와 덱 미리보기는 API 데이터 디렉터리에 저장하며 Git에 포함하지 않는다.
|
||||
- 덱 저장 미리보기는 1200px 기준 PNG로 정규화한다.
|
||||
|
||||
## 5. 다국어
|
||||
- 지원 언어: `ko`, `ja`, `en`
|
||||
- 번역 파일:
|
||||
- `i18n/translations.ko.json`
|
||||
- `i18n/translations.ja.json`
|
||||
- `i18n/translations.en.json`
|
||||
- `index.html`은 번역 JSON을 직접 읽는다.
|
||||
- 공통 텍스트 치환은 `i18n/i18n.js`의 `data-i18n` 기반 로직을 사용한다.
|
||||
## 브라우저 상태
|
||||
|
||||
## 6. 상태 저장
|
||||
- `localStorage.lang`: 현재 언어
|
||||
- `localStorage.selectedCards`: 편집 중인 덱 (임시, `encodeURIComponent` JSON)
|
||||
- `localStorage.selectedSeries`: 현재 시리즈 키
|
||||
- `localStorage.uadeck_token` / `uadeck_user`: 로그인 세션
|
||||
- 덱 공유·영구 저장: API + DB (`GET /api/v1/decks/:shareCode`)
|
||||
| 키 | 용도 |
|
||||
|---|---|
|
||||
| `lang` | 선택 언어 |
|
||||
| `selectedCards` | 편집 중인 덱 |
|
||||
| `selectedSeries` | 현재 시리즈 |
|
||||
| `uadeck_token` | JWT |
|
||||
| `uadeck_user` | 로그인 사용자 캐시 |
|
||||
| 덱 즐겨찾기 키 | 공유 코드 기반 로컬 즐겨찾기 |
|
||||
|
||||
## 7. 스타일 및 자산
|
||||
- Tailwind 유틸리티 클래스와 페이지별 인라인 스타일을 혼용한다.
|
||||
- 공통 스타일 파일:
|
||||
- `style/output.css`
|
||||
- `style/style.css`
|
||||
- `style/navigation.css`
|
||||
## 인증 및 권한
|
||||
|
||||
## 8. 알려진 제약
|
||||
- `cardList.html`과 `result.html`의 스크립트가 페이지 내부에 크게 포함되어 있어 모듈 분리 전까지는 변경 영향 범위가 넓다.
|
||||
- `script/navigation.js`의 일부 이동 대상 페이지는 현재 저장소에 존재하지 않는다.
|
||||
- 이미지가 Git 일반 객체로 계속 누적되면 저장소 히스토리 크기가 지속 증가한다.
|
||||
- 비밀번호는 bcrypt 비용 12로 해시한다.
|
||||
- JWT 기본 만료는 7일이며 `JWT_EXPIRES`로 변경할 수 있다.
|
||||
- `user`는 자신의 프로필과 덱만 수정·삭제할 수 있다.
|
||||
- `admin`은 회원 상태·역할·비밀번호와 전체 덱을 관리할 수 있다.
|
||||
- 관리자는 자신의 관리자 역할을 해제하거나 자신의 계정을 비활성화할 수 없다.
|
||||
- 비공개 덱은 소유자와 관리자만 조회할 수 있다.
|
||||
|
||||
---
|
||||
## 덱 저장 정책
|
||||
|
||||
## 9. v4.0.0 계획 — 회원·덱 API·공유
|
||||
- 공유 코드는 저장 시 생성되는 8자 코드다.
|
||||
- 회원 덱은 만료 없이 저장하며 공개 여부를 선택할 수 있다.
|
||||
- 비회원 덱은 공개 상태로 저장되고 30일 뒤 만료된다.
|
||||
- DB의 `cards_json`에는 `{number, count, key}`만 저장한다.
|
||||
- API 응답 시 `datas/<series>.js`에서 이미지·색상·희귀도·트리거 정보를 합성한다.
|
||||
- 공개 덱 목록은 `share_type='user'`, `is_public=1`, 미만료 조건을 사용한다.
|
||||
- `preset` 타입과 관리자 프리셋 API는 레거시 호환용으로 코드에 남아 있으며 현재 공개 덱 화면에서는 사용하지 않는다.
|
||||
|
||||
> 상태: **v4.0.0 1차 구현 완료** (2026-06-19)
|
||||
## 데이터베이스
|
||||
|
||||
### 9.1 아키텍처 개요
|
||||
- 프론트: 기존 정적 HTML/JS 유지. 헤더에 프로필·인증 UI 추가.
|
||||
- 백엔드: Docker 컨테이너 API 서버 (NAS 배포).
|
||||
- 카드 DB: `datas/*.js` + `images/` 정적 유지 (변경 없음).
|
||||
- 사용자·덱 데이터: API + SQLite(또는 PostgreSQL) DB.
|
||||
- 외부 연동(옆 프로젝트): `GET /api/v1/decks/:shareCode` 단일 계약.
|
||||
### `users`
|
||||
|
||||
### 9.2 덱 공유 방식 (확정)
|
||||
| 컬럼 | 설명 |
|
||||
|---|---|
|
||||
| `id` | 기본 키 |
|
||||
| `email`, `username` | 고유 로그인·표시 식별자 |
|
||||
| `password_hash` | bcrypt 해시 |
|
||||
| `display_name` | 레거시 표시명, 현재 `username`과 함께 갱신 |
|
||||
| `avatar_url` | 아바타 API 경로 |
|
||||
| `role` | `user` 또는 `admin` |
|
||||
| `is_active` | 계정 활성 상태 |
|
||||
| `default_deck_public` | 덱 저장 기본 공개 여부 |
|
||||
| `skip_deck_public_prompt` | 저장 시 공개 확인 생략 여부 |
|
||||
| `created_at`, `updated_at` | 생성·수정 시각 |
|
||||
|
||||
기존 `?cards=<JSON>` URL 방식은 **폐기**한다. 공유는 공유 코드 + API만 사용한다.
|
||||
### `decks`
|
||||
|
||||
| 종류 | `share_type` | 코드 생성 | URL 예시 | 설명 |
|
||||
|---|---|---|---|---|
|
||||
| 개인 덱 | `user` | nanoid 8자 (저장마다 고유) | `/d/x7Kp9m2Q` | 같은 카드 구성이라도 저장자마다 URL이 다름 |
|
||||
| 메타 덱·프리셋 | `preset` | 내용 해시 8자 (동일 구성 = 동일 URL) | `/d/a7f3b2c1` | 관리자 등록 공식 템플릿, 중복 저장 없음 |
|
||||
| 컬럼 | 설명 |
|
||||
|---|---|
|
||||
| `share_code` | 고유 공유 코드 |
|
||||
| `share_type` | `user` 또는 레거시 `preset` |
|
||||
| `content_hash` | 레거시 프리셋 중복 판별 |
|
||||
| `user_id` | 소유 회원, 비회원은 `null` |
|
||||
| `series`, `series_name` | 시리즈 키와 표시명 |
|
||||
| `name` | 덱 이름 |
|
||||
| `cards_json` | 최소 카드 구성 JSON |
|
||||
| `is_public` | 공개 여부 |
|
||||
| `view_count` | 상세 조회 횟수 |
|
||||
| `expires_at` | 비회원 공유 만료 시각 |
|
||||
| `preview_image` | 저장된 미리보기 파일 정보 |
|
||||
| `created_at`, `updated_at` | 생성·수정 시각 |
|
||||
|
||||
브라우저 진입:
|
||||
- `/d/:shareCode` → `cardList.html?d=:shareCode` 리다이렉트 또는 동일 페이지에서 API 로드
|
||||
- `cardList.html`은 `?d=` 파라미터가 있으면 API에서 덱 복원
|
||||
## API
|
||||
|
||||
### 9.3 DB 저장 vs API 응답
|
||||
### 공통
|
||||
|
||||
**DB에 저장하는 최소 덱 본문 (`cards_json`):**
|
||||
```json
|
||||
[
|
||||
{ "number": "UA36BT/MCR-1-052", "count": 4, "key": true },
|
||||
{ "number": "EX14BT/MCR-2-011", "count": 2, "key": false }
|
||||
]
|
||||
```
|
||||
| Method | Path | 권한 | 기능 |
|
||||
|---|---|---|---|
|
||||
| GET | `/api/v1/health` | 공개 | API 상태와 버전 |
|
||||
|
||||
**API 응답 시 서버가 `datas/<series>.js`를 lookup하여 풀 카드 정보를 합성한다.**
|
||||
### 인증
|
||||
|
||||
```json
|
||||
{
|
||||
"v": 1,
|
||||
"shareCode": "x7Kp9m2Q",
|
||||
"shareType": "user",
|
||||
"series": "ua36",
|
||||
"seriesName": "마크로스",
|
||||
"name": "블루 aggro",
|
||||
"totalCards": 50,
|
||||
"cards": [
|
||||
{
|
||||
"number": "UA36BT/MCR-1-052",
|
||||
"count": 4,
|
||||
"key": true,
|
||||
"imgSrc": "/ua36/UA36BT_MCR-1-052.png",
|
||||
"color": "Blue",
|
||||
"rarity": "SR",
|
||||
"trigger": null,
|
||||
"parallel": false
|
||||
}
|
||||
],
|
||||
"author": {
|
||||
"id": 12,
|
||||
"displayName": "닉네임",
|
||||
"avatarUrl": "/uploads/avatars/12.png"
|
||||
},
|
||||
"createdAt": "2026-06-19T12:00:00Z",
|
||||
"updatedAt": "2026-06-19T14:30:00Z",
|
||||
"viewCount": 42,
|
||||
"isPublic": true
|
||||
}
|
||||
```
|
||||
| Method | Path | 권한 | 기능 |
|
||||
|---|---|---|---|
|
||||
| POST | `/api/v1/auth/register` | 공개 | 회원가입 |
|
||||
| POST | `/api/v1/auth/login` | 공개 | 로그인과 JWT 발급 |
|
||||
| GET | `/api/v1/auth/me` | 회원 | 내 정보 |
|
||||
| PUT | `/api/v1/auth/me` | 회원 | 프로필·덱 저장 설정 변경 |
|
||||
| POST | `/api/v1/auth/me/password` | 회원 | 비밀번호 변경 |
|
||||
| GET | `/api/v1/auth/avatar/:userId` | 공개 | PNG 아바타 |
|
||||
|
||||
비회원 임시 공유: `author`는 `null`, `expiresAt` 필드로 만료 관리.
|
||||
### 덱
|
||||
|
||||
### 9.4 DB 스키마 (초안)
|
||||
| Method | Path | 권한 | 기능 |
|
||||
|---|---|---|---|
|
||||
| GET | `/api/v1/decks/presets` | 공개 | 공개 사용자 덱 목록 |
|
||||
| GET | `/api/v1/decks/:shareCode/preview` | 공개 | 덱 미리보기 PNG |
|
||||
| GET | `/api/v1/decks/:shareCode` | 조건부 | 공개 덱 또는 소유 덱 상세 |
|
||||
| GET | `/api/v1/decks` | 회원 | 내 덱 목록 |
|
||||
| POST | `/api/v1/decks` | 공개 | 회원 또는 비회원 덱 저장 |
|
||||
| PUT | `/api/v1/decks/:shareCode` | 소유자·관리자 | 덱 수정 |
|
||||
| DELETE | `/api/v1/decks/:shareCode` | 소유자·관리자 | 덱 삭제 |
|
||||
|
||||
#### `users`
|
||||
| 컬럼 | 타입 | 설명 |
|
||||
### 관리자
|
||||
|
||||
| Method | Path | 기능 |
|
||||
|---|---|---|
|
||||
| `id` | INTEGER PK | |
|
||||
| `email` | TEXT UNIQUE | 로그인 ID |
|
||||
| `username` | TEXT UNIQUE | 표시용 닉네임 |
|
||||
| `password_hash` | TEXT | bcrypt |
|
||||
| `display_name` | TEXT | 프로필 이름 |
|
||||
| `avatar_url` | TEXT | 프로필 썸네일 |
|
||||
| `default_deck_public` | INTEGER | 덱 저장 기본 공개 여부 (1=공개, 0=비공개) |
|
||||
| `skip_deck_public_prompt` | INTEGER | 저장 시 공개 확인 생략 (1=생략) |
|
||||
| `role` | TEXT | `user` \| `admin` |
|
||||
| `is_active` | INTEGER | 0=비활성, 1=활성 |
|
||||
| `created_at` | TEXT | 가입일 |
|
||||
| `updated_at` | TEXT | |
|
||||
|
||||
#### `decks`
|
||||
| 컬럼 | 타입 | 설명 |
|
||||
|---|---|---|
|
||||
| `id` | INTEGER PK | |
|
||||
| `share_code` | TEXT UNIQUE | URL에 쓰이는 8자 코드 |
|
||||
| `share_type` | TEXT | `user` \| `preset` |
|
||||
| `content_hash` | TEXT | preset 타입용. user 타입은 null 가능 |
|
||||
| `user_id` | INTEGER FK | null=비회원 임시 공유 |
|
||||
| `series` | TEXT | 예: `ua36` |
|
||||
| `name` | TEXT | 덱 이름 |
|
||||
| `cards_json` | TEXT | `[{number,count,key}]` JSON |
|
||||
| `is_public` | INTEGER | 0=비공개, 1=공개 |
|
||||
| `view_count` | INTEGER | 조회수 |
|
||||
| `expires_at` | TEXT | null=만료 없음 |
|
||||
| `created_at` | TEXT | 생성일 |
|
||||
| `updated_at` | TEXT | 최종 수정일 |
|
||||
|
||||
덱 1건 용량 추정: 카드 50장 × 약 60바이트 ≈ 3KB. 수만 건이어도 DB 부담은 경미하다.
|
||||
|
||||
### 9.5 API 엔드포인트 (초안)
|
||||
|
||||
#### 인증
|
||||
| Method | Path | 설명 |
|
||||
|---|---|---|
|
||||
| POST | `/api/v1/auth/register` | 회원가입 |
|
||||
| POST | `/api/v1/auth/login` | 로그인 → JWT |
|
||||
| GET | `/api/v1/auth/me` | 내 정보 |
|
||||
| PUT | `/api/v1/auth/me` | 프로필 수정 (이메일, 사용자명, 아바타, `defaultDeckPublic`, `skipDeckPublicPrompt`) |
|
||||
| POST | `/api/v1/auth/me/password` | 비밀번호 변경 |
|
||||
| GET | `/api/v1/auth/avatar/:userId` | 프로필 이미지 (PNG) |
|
||||
|
||||
#### 덱
|
||||
| Method | Path | 설명 |
|
||||
|---|---|---|
|
||||
| GET | `/api/v1/decks/:shareCode` | 덱 조회 (외부 연동 공식 계약) |
|
||||
| GET | `/api/v1/decks` | 내 덱 목록 (인증 필요) |
|
||||
| POST | `/api/v1/decks` | 덱 저장·공유 코드 발급 |
|
||||
| PUT | `/api/v1/decks/:shareCode` | 덱 수정 (소유자만) |
|
||||
| DELETE | `/api/v1/decks/:shareCode` | 덱 삭제 (소유자만) |
|
||||
|
||||
#### 관리자
|
||||
| Method | Path | 설명 |
|
||||
|---|---|---|
|
||||
| GET | `/api/v1/admin/users` | 회원 목록 |
|
||||
| GET | `/api/v1/admin/users` | 회원 목록·검색 |
|
||||
| GET | `/api/v1/admin/users/:id` | 회원 상세 |
|
||||
| PUT | `/api/v1/admin/users/:id` | 회원 정보·역할·활성 수정 |
|
||||
| PUT | `/api/v1/admin/users/:id` | 회원 정보·역할·활성 상태 변경 |
|
||||
| POST | `/api/v1/admin/users/:id/reset-password` | 비밀번호 초기화 |
|
||||
| POST | `/api/v1/admin/decks/preset` | 메타 덱(프리셋) 등록 |
|
||||
| GET | `/api/v1/admin/decks` | 전체 덱 목록 |
|
||||
| DELETE | `/api/v1/admin/decks/:shareCode` | 덱 삭제 |
|
||||
| POST | `/api/v1/admin/decks/preset` | 레거시 프리셋 생성 |
|
||||
|
||||
### 9.6 프론트 변경 (예정)
|
||||
- `script/auth-header.js`: 헤더 프로필 드롭다운 (로그인/회원가입, 내 덱 관리)
|
||||
- `login.html`, `signup.html`, `deckHistory.html`, `admin.html` 신규
|
||||
- `cardList.html`: `?cards=` 제거, `?d=` API 로드로 전환
|
||||
- `localStorage.selectedCards`: 편집 중 임시 저장만 (공유와 분리)
|
||||
## 스타일
|
||||
|
||||
### 9.7 배포
|
||||
- `docker-compose.yml`: API만 (기존 웹서버 사용 시)
|
||||
- `docker-compose.prod.yml`: Nginx + API 풀스택 (NAS 권장)
|
||||
- `docs/deploy.md`: NAS 배포 상세 가이드
|
||||
- `docs/api-integration.md`: 옆 프로젝트 연동 가이드
|
||||
- `integrations/uadeck-deck-client.js`: 연동용 JS 클라이언트
|
||||
- `nginx/default.conf`: `/api/`, `/d/` 라우팅
|
||||
- 현재는 Tailwind 유틸리티, 공통 CSS, 페이지 전용 CSS, 일부 인라인 스타일을 혼용한다.
|
||||
- 이번 단계에서는 기존 CSS를 Tailwind로 일괄 전환하지 않는다.
|
||||
- `style/output.css`는 `style/input.css`에서 생성하는 빌드 산출물이다.
|
||||
- 헤더 로고 크기는 `style/brand.css`만 기준으로 사용한다.
|
||||
- 기본 글꼴은 Pretendard 계열을 우선 사용한다.
|
||||
|
||||
## 알려진 제약
|
||||
|
||||
- `cardList.html`, `result.html`의 인라인 스크립트가 커서 변경 영향 범위가 넓다.
|
||||
- `admin.html`은 3개 언어 번역 적용이 완료되지 않았다.
|
||||
- 즐겨찾기는 브라우저별 로컬 상태라 계정 간 동기화되지 않는다.
|
||||
- Homepage 전용 `GET /api/homepage` 엔드포인트는 아직 구현되지 않았다.
|
||||
- 현재 Compose의 컨테이너명(`uniare-api`, `uniare-web`)과 데이터 볼륨명(`uniare-data`)은 고정값이며 환경 변수화되지 않았다.
|
||||
|
||||
Reference in New Issue
Block a user