WallpaperMachine
The wallpapers you love. A new home on your Mac.
사진과 상황을 알려주면 지금 코디가 그 자리에 얼마나 잘 맞는지 확인해드려요. 미래에이아이랩 MVP 샘플.
Translation pending
LifestyleTypeScript · JavaScriptGitHub @sanghohoho0813-labOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
StyleCheck AI — 상황별 코디 적합도 판정 MVP 미래에이아이랩 MVP 샘플 프로젝트 "오늘 이 옷, 괜찮을까요?" — 사진과 가는 곳을 알려주면 지금 코디가 그 자리에 얼마나 잘 맞는지, 무엇 하나를 바꾸면 좋을지 알려주는 스타일 도우미. 사진 → 상황(12종) → 조건(만나는 사람·장소·무드·계절) → 판정 → 결론(적합도·판정) → 이유(잘 맞는 점 / 바꿀 점) → 다음 행동(한 가지만 바꾼다면) → 추천대로 바꿔 입기(완료 이벤트) → 저장·공유 → 기록에서 다시 확인 완료 이벤트는 실제 상태를 바꿉니다. 모든 상태는 브라우저 localStorage에 저장되어 새로고침 후에도 유지됩니다. 처음 방문하면 오늘 기준 2·5·9일 전 샘플 기록 3건이 채워진 상태로 시작합니다.Read the full README ↗
미래에이아이랩 MVP 샘플 프로젝트 "오늘 이 옷, 괜찮을까요?" — 사진과 가는 곳을 알려주면 지금 코디가 그 자리에 얼마나 잘 맞는지, 무엇 하나를 바꾸면 좋을지 알려주는 스타일 도우미.
Next.js 15 (App Router) · React 19 · TypeScript (strict) · Tailwind CSS v4 · Vitest · Playwright
npm ci
npm run dev # http://localhost:3000
npm run check # lint + typecheck + unit tests
npm run build && npm run test:e2e # 프로덕션 빌드로 E2E (phone + desktop)
사진 → 상황 → 판정. 필수 입력은 사진 한 장과 상황 하나뿐이에요.
| 행동 | 바뀌는 상태 | 다시 확인하는 곳 |
|---|---|---|
| 코디 판정 | 기록 1건 생성 | 기록 · 마이 통계 |
| 세부 조건 선택(선택 사항) | 점수 가감 + 이유(ConditionNote) | 결과 "핵심 이유" · 자세히 보기 "고른 조건이 바꾼 점수" |
| 추천대로 바꿔 입기 / 되돌리기 | appliedAt | 결과(적용 전/후) · 기록 "바꿔 입음" 필터·카드 · 마이 통계 · 스타일 패턴 |
| 저장 | favorite | 기록 "저장한 코디" 필터 · 마이 통계 |
| 친구에게 물어보기 | 공유 링크 (사진 제외) | 다른 기기에서 같은 판정 + 링크 미리보기 이미지 |
| 기록 삭제 / 되돌리기 | 제거 · 같은 위치로 복원 | 기록 · 마이 통계 |
| 선호 스타일 | 선호 무드 | 코디 확인 "원하는 느낌" 기본값 |
| 데모 데이터 초기화 | 전체 초기화 + 샘플 기록 재생성 | 기록 · 마이 |
결과 데이터는 기기에 남는다. 로그인 없는 MVP라 기록은 localStorage(lib/storage.ts)에 두고,
구조는 supabase/schema.sql과 맞춰 두었습니다. 저장 계층은 실패를 전제로 짰습니다.
localStorage가 막힌 환경(쿠키 차단 등)에서는 탭 메모리로 계속 동작합니다.공유는 서버 없이 동작한다. 기록이 기기에만 있으니 /result/<id>만 보내면 친구 화면은 비어 있습니다.
공유 링크(lib/share.ts)는 엔진 입력(샘플 id 또는 이미지 키·상황·조건)과 숫자만 base64url로 담습니다.
받는 쪽은 같은 결정적 엔진으로 문구를 다시 만들고 숫자는 고정해 두 사람이 같은 판정을 봅니다.
사진은 링크에 들어가지 않습니다. 변조된 코드는 거부하고 안내 화면을 보여줍니다.
링크를 채팅에 붙이면 /og/result가 점수·판정·바꿀 한 가지가 담긴 미리보기 이미지를 그립니다(lib/og.tsx).
판정은 친구의 말투로, 점수보다 먼저. lib/advice.ts가 점수 구간별 판정 한 줄과 조언 한 문장을 만들어요
(예: "결혼식에 잘 맞는 코디예요." / "다만 구두만 블랙 스트레이트팁으로 바꾸면 재킷과 톤이 이어져 격식이 한 단계 올라가요.").
추천마다 action(무엇을 어떻게)과 effect(무엇이 달라지는지)를 따로 두어 문장이 자연스럽게 이어져요.
결과 화면, 공유받은 화면, 공유 메시지, 링크 미리보기가 모두 같은 문장을 써요.
스타일 패턴은 데이터가 말하는 만큼만. lib/insights.ts는 기록이 3개 이상일 때만 패턴을 보여주고,
모든 문장에 근거 숫자를 붙여요("최근 4번 중 2번, 신발·소품이 가장 아쉬웠어요", "추천 4번 중 2번을 실제로 바꿔 입었어요").
조건을 채우지 못하는 패턴은 아예 만들지 않아요.
사진을 가장 먼저 존중한다. 업로드 사진은 3:4로 자르지 않고 전체를 보여줘요. 잘라내면 조언의 대상인 신발이나 가방이 잘릴 수 있어서예요. EXIF 회전은 브라우저 디코딩에 맡기고, 투명 PNG는 흰 배경 위에 그려요. 어두운 사진·가로 사진·작은 사진은 픽셀 정보만으로 판단해 다시 찍기 팁을 줘요(옷을 인식하지는 않아요).
엔진은 정직한 데모다. lib/style-engine.ts는 규칙 기반·결정적 엔진입니다. 업로드 사진을 인식하지 않으며
화면에 "데모 분석"으로 표기합니다. 조건은 명시적 규칙으로만 점수를 움직이고, 움직인 만큼을 문장과 점수로 돌려줍니다.
예를 들어 계절이 맞지 않으면 −3/−6, 격식을 요구하는 자리인데 격식이 낮으면 −3~−5입니다.
결과 스키마가 실제 Vision/LLM 연동 때와 같아서, analyzeOutfitImage만 바꾸면 화면·저장·공유를 그대로 씁니다.
흐름은 브라우저처럼 움직인다. 코디 확인의 각 단계는 history 항목이라 휴대폰 뒤로가기가 한 단계씩 돌아갑니다.
진행 중 입력은 sessionStorage 초안으로 새로고침 뒤에도 이어집니다. 결과가 나오면 단계 기록을 걷어내고
결과로 교체하므로, 결과에서 뒤로가면 확인을 시작한 화면(홈·기록·가이드)으로 갑니다.
| 영역 | 내용 |
|---|---|
| 단위 테스트 (79) | lib/__tests__ — 모든 샘플 × 계절 × 조건 조합에서 점수 범위, "바꾸면 좋아진다", 대안 < 추천, 조건 점수 = 설명된 점수 합. 판정·조언 문장(모든 샘플·업로드 템플릿에서 한 문장으로 끝나는지), 상황별 질문, 스타일 패턴의 데이터 기준. 공유 링크 왕복·변조 거부. 저장 계층의 마이그레이션·용량 초과·차단 대응. 한국어 조사·날짜 |
| E2E (76) | e2e/ — phone(390, 터치)·desktop(1280) 프로젝트. 첫 화면 사진 → 상황 → 판정 → 바꿔 입기 → 저장 → 공유 → 기록 전체 여정, 휴대폰 결과 화면의 하단 실행 바, 상황별 질문, 사진 팁, 뒤로/앞으로/새로고침, 다시 확인하기, 깨끗한 기기에서 공유 링크·미리보기, 빈·오류 상태, 상황 미선택 시 안내가 보이는 위치, 기록의 기간별 묶음, 키보드 경로, 휴대폰에서 화면이 옆으로 넓어지지 않는지(레이아웃 뷰포트 폭) |
| CI | .github/workflows/ci.yml — lint · typecheck · unit → build · E2E (실패 시 리포트 업로드) |
| 접근성 | e2e/a11y.spec.ts — axe-core로 모든 화면과 바꿔 입은 상태를 휴대폰·데스크톱에서 WCAG 2.1 A/AA 자동 감사(serious·critical 0건 유지, 로고타입은 WCAG 1.4.3 예외라 제외). 본문 바로가기, 상황 선택의 WAI-ARIA radio 키보드 패턴(화살표·Home·End), 단계 전환 시 제목으로 포커스, aria-live 로딩·토스트, 텍스트 색 대비 4.5:1 이상(상태색 sage·gold 포함), prefers-reduced-motion(지연된 등장 애니메이션까지 즉시 표시) |
| 성능 | 샘플 사진은 next/image(AVIF/WebP, 크기별 srcset, 접힘 위만 priority)이고 불러오는 동안 사진마다의 배경색(lib/look-tints.ts)을 먼저 칠함. 기기 사진은 data URL 그대로. 클라이언트 로딩 화면의 스켈레톤이 실제 레이아웃과 같아 CLS ≈ 0 |
| 안정성 | 라우트·전역 에러 경계, 친절한 404·결과 없음·공유 링크 손상 화면, 파일 형식·용량 검증, 투명 PNG 처리 |
| 보안 | nosniff · Referrer-Policy · Permissions-Policy · HSTS, X-Powered-By 제거. 미래에이아이랩 사이트가 데모를 iframe으로 보여주므로 frame 제한은 두지 않음. 프로덕션 의존성 취약점 0 (npm audit --omit=dev) |
app/
page.tsx · check/ · result/[id]/ · history/ · mypage/ · guide/ 화면
og/result/route.ts · opengraph-image.tsx · apple-icon.tsx · manifest.ts
error.tsx · global-error.tsx · not-found.tsx
components/ UI (LookImage, OccasionGrid, SituationStep, HeroQuickStart, GuideNav, Toast, SampleBridgeCTA …)
lib/
style-engine.ts 데모 분석 엔진 (조건 규칙 applyConditions)
advice.ts 판정 한 줄 · 조언 한 문장 · 공유 메시지
insights.ts 기록 기반 스타일 패턴 (데이터 기준 충족 시에만)
storage.ts 기록 · 설정 · 흐름 초안 저장 계층
share.ts 기기 간 공유 링크
og.tsx 링크 미리보기 이미지 (서버 전용)
demo-samples.ts · occasions.ts · guides.ts · wardrobe.ts 데이터
assets/ 미리보기용 폰트 서브셋(OFL) · 사진 JPEG — scripts/subset-og-font.py 로 재생성
e2e/ · lib/__tests__/ 테스트
app/globals.css)caption 13 · meta 14 · body-sm 15 · body 17 · lead 18 · title 20 · section 26 · page 32 · display 40 · hero 56.
Tailwind 기본 크기는 꺼 두어 이 스케일만 쓸 수 있습니다.rose는 장식용입니다.sm 12 · md 20 · lg 28 · Shadow subtle · raised · overlay · ctabtn + btn-lg/md/sm/xs + btn-primary/secondary/quiet, 선택형 chip + chip-on/off화면마다 역할이 달라 레이아웃 원칙도 나눴습니다. 모두 같은 토큰·컴포넌트를 씁니다.
| 화면 | 방향 | 핵심 |
|---|---|---|
| 홈 | 비주얼 + 행동 | 첫 화면에 촬영 버튼과 실제 판정 결과 카드. 데스크톱은 코디 사진 위에 판정 카드를 겹친 구성. 샘플은 휴대폰에서 가로로 넘기는 선반, 태블릿부터 그리드. 상황은 아이콘 그리드 |
| 코디 확인 | 기능 | 한 화면에 한 가지 결정. 휴대폰은 하단 고정 버튼, 데스크톱 상황 단계는 판정할 사진을 옆에 크게 고정 |
| 결과 | 하이브리드 | 판정 → 이유 → 바꿀 한 가지 순서. 휴대폰은 탭 바 대신 저장 · 물어보기 · 주 행동이 있는 하단 실행 바(상세 화면 패턴). 바꿔 입은 뒤에는 "다시 확인하기"가 주 행동이 됨 |
| 기록 | 비주얼 | 휴대폰은 읽기 쉬운 목록, 태블릿부터 사진이 먼저 보이는 룩북 카드 |
| 가이드 · 마이 | 정보 | 텍스트 위계와 여백 중심, 장식 없음 |
상단 브랜드 바 · 푸터 · 흐름을 마친 뒤의 브릿지 CTA 세 곳에만 둡니다. 코디 확인 도중에는 노출하지 않습니다.
링크는 lib/mirae-links.ts, 문구는 components/SampleBridgeCTA.tsx의 CTA_COPY에서 바꿉니다.
public/mirae-history-nav.js는 미래AI랩 데모 공용 뒤로·앞으로 버튼입니다(공용 파일이라 lint 제외).
| 이름 | 용도 |
|---|---|
NEXT_PUBLIC_SITE_URL | 링크 미리보기의 절대 URL. Vercel에서는 VERCEL_PROJECT_PRODUCTION_URL을 자동 사용 |
PW_CHROMIUM_PATH | (선택) E2E에 이미 설치된 Chromium 사용 |