尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Your AI personal stylist. Upload photos of your clothes to get instant styling feedback, build a searchable digital wardrobe, and generate complete outfits from pieces you already own — powered by Google Gemini vision.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) + TypeScript |
| Styling | Tailwind CSS v4 |
| AI / vision | Google Gemini (gemini-3.6-flash) via @google/genai |
| Database / Auth / Storage | Supabase (Postgres + Auth + Storage) |
The AI layer sits behind a provider-agnostic AIStylist interface
(src/lib/ai/), so the underlying model can be swapped without touching the
rest of the app.
flowchart LR
Browser(["User's browser"])
subgraph app["Next.js app (Vercel)"]
direction TB
Pages["Pages / SSR<br/>landing · analyze · closet · outfits · profile"]
Proxy["proxy.ts<br/>refresh session · guard routes"]
Server["Server Actions<br/>+ /api/analyze"]
AI["AIStylist interface<br/>→ GeminiStylist"]
end
Gemini["Google Gemini<br/>vision + text"]
subgraph sb["Supabase"]
direction TB
Auth["Auth"]
DB[("Postgres + RLS<br/>garments · profiles")]
Store["Storage<br/>private images"]
end
Browser -->|every request| Proxy
Browser -->|load page| Pages
Browser -->|submit form| Server
Server --> AI
AI -->|images + prompts| Gemini
Server -->|scoped by RLS| DB
Server --> Store
Proxy --> Auth
Server --> Auth
/api/analyze; wardrobe uploads and outfit
suggestions run through Server Actions.AIStylist
interface (src/lib/ai/). Swapping Gemini for another model means writing one
new class — the rest of the app is untouched — and it makes the AI layer easy to
unit-test by mocking the client.429/503 errors retry with
exponential backoff, while real errors fail fast. This is covered by tests.auth.uid()), not just in app
code — and an integration test proves user A can't read user B's data.git clone https://github.com/pranavraju24/outfitmax.git
cd outfitmax
npm install
Copy the example file and fill in your own values:
cp .env.example .env.local
| Variable | Where to find it |
|---|---|
GEMINI_API_KEY | Google AI Studio → Create API key |
NEXT_PUBLIC_SUPABASE_URL | Supabase → Project Settings → Data API |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Supabase → Project Settings → API Keys (publishable) |
SUPABASE_SECRET_KEY | Supabase → Project Settings → API Keys (secret) |
.env.localis git-ignored — your real keys never get committed.
supabase/schema.sql. This creates the garments and
profiles tables with Row-Level Security and the required grants.garments
(Storage → New bucket → uncheck "Public bucket").npm run dev
Open http://localhost:3000.
The app ships a multi-stage Dockerfile (Next.js standalone output) and a
docker-compose.yml. With your env values in .env.local:
docker compose --env-file .env.local up --build
Supabase itself runs separately (your hosted project, or npx supabase start
for a local stack).
| Command | Description |
|---|---|
npm run dev | Start the development server |
npm run build | Production build |
npm run start | Serve the production build |
npm run lint | Run ESLint |
npm run typecheck | Type-check with tsc |
npm test | Run unit tests (Vitest) |
npm run test:integration | Run RLS integration tests (needs local Supabase) |
npm test) cover the AI layer: schema-validated output,
retry/backoff on transient errors, and the swappable-provider factory. The
Gemini client is mocked, so they're fast and need no network.npm run test:integration) run against a local
Supabase (npx supabase start) and prove Row-Level Security keeps each user's
wardrobe private.src/
├── app/
│ ├── page.tsx # Landing page
│ ├── analyze/ # Styling feedback (public)
│ ├── closet/ # Wardrobe: upload, grid, actions
│ ├── outfits/ # Outfit suggestions from your closet
│ ├── login/ # Auth screens + server actions
│ ├── profile/ # Account details + log out
│ ├── api/analyze/ # Styling feedback route handler
│ └── _components/ # Shared UI (header, marquee)
├── lib/
│ ├── ai/ # Provider-agnostic AIStylist (Gemini impl)
│ ├── supabase/ # Browser / server / admin clients
│ ├── auth/ # Data access layer (session gate)
│ └── wardrobe/ # Garment types + image storage helpers
└── proxy.ts # Route protection (Next.js 16 "proxy")
supabase/schema.sql # Database schema + RLS policies
This is a personal learning project. Secrets are read from environment variables and never committed; the Supabase secret key is used only in server-side code and never reaches the browser.