Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 105 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,128 +1,135 @@
# SkinLab
<p align="center">
<img src="./assets/readme/hero.svg" width="100%" alt="SkinLab standardizes a skin photo, analyzes it, and compares repeated check-ins over a 28-day tracking cycle">
</p>

AI-powered skin analysis and skincare recommendation iOS app.
**SkinLab** 是一款 iOS 17+ 的皮肤记录与护肤效果追踪应用。它把一次 AI 照片分析变成可重复的基线:标准化拍摄、记录产品与生活方式、按周期复拍,再用可靠性与趋势模型解释变化。

## Overview
> **隐私与医疗边界:** AI 分析不是离线完成。点击分析后,压缩后的面部照片会以 base64 JPEG 发送到 OpenRouter 的 chat-completions API,当前模型为 `google/gemini-3-flash-preview`。结果只供护肤记录参考,不构成医疗诊断;异常皮肤问题应咨询专业医护人员。

SkinLab helps users understand their skin health through AI-powered analysis and track skincare effectiveness over a 28-day verification cycle. The app focuses on data-driven insights that users want to share.
## 从照片到证据

**Core Philosophy**: Make skincare effects visible ("让护肤效果看得见")
```text
标准化拍照
→ 质量 / 可靠性检查
→ OpenRouter + Gemini vision 分析
→ SwiftData 保存结果与基线
→ 复拍 + 产品 / 生活方式记录
→ 趋势、异常、季节性与相关性提示
```

**Target Users**: 18-35 year olds focused on skincare
仓库中的真实功能模块:

**Differentiation**:
- Effect verification engine with 28-day tracking cycles
- Skin twin matching for personalized recommendations
- Anti-ad commitment - evidence-based suggestions only
| 模块 | 当前源码 |
|---|---|
| Analysis | 相机/相册、图片优化、OpenRouter 请求、皮肤与区域分数、routine generation |
| Tracking | 28 天 session、check-in、可靠性、time series、异常/季节性/forecast、产品归因 |
| Products | 本地产品/成分数据、OCR、风险规则与 AI insight |
| Engagement | 连续记录、streak freeze、achievement、提醒与庆祝动画 |
| Community | consent level、匿名 profile、skin twin matching、反馈与推荐 engine |
| Privacy | 本地存储开关、照片保留/删除、数据导出与全量删除入口 |

## Features (Completed)
这些是源码能力,不代表 App Store 已发布或临床验证。

### fn-2: Engagement (Daily Streaks & Achievement Badges)
- Daily streak tracking for check-ins with longest streak display
- Achievement badges and dashboard for milestones
- Milestone celebration animations (respects reduced motion)
- Streak freeze mechanic (1 per 30 days)
- Local notifications for streak reminders and at-risk warnings
## 快速开始

### fn-3: Photo Standardization & Lifestyle Correlation
- Day 0 baseline creation to start tracking sessions from analysis
- Standardized photo capture guidance with real-time feedback
- Photo quality and reliability scoring at capture time
- Lifestyle inputs are optional and only saved when explicitly set
- Lifestyle correlation insights based on real score deltas
要求:

## Tech Stack
- macOS + Xcode **15.2**(CI 固定版本)
- iOS **17.0+** simulator 或设备
- OpenRouter API key

| Component | Technology |
|-----------|------------|
| Platform | iOS 17+ |
| Language | Swift 5.9+ |
| UI Framework | SwiftUI |
| Architecture | MVVM + Clean Architecture |
| Storage | SwiftData |
| AI | Gemini 3.0 Flash Vision API |
| Image Processing | Vision Framework |
```bash
git clone <repository-url>
cd SkinLab
open SkinLab.xcodeproj
```

## Getting Started
在 Xcode 中选择 `SkinLab` scheme 与 iOS 17 simulator。开发运行时,在 **Product → Scheme → Edit Scheme → Run → Arguments → Environment Variables** 添加:

### Requirements
```text
OPENROUTER_API_KEY=<your-key>
```

- Xcode 15.0+
- iOS 17.0+ deployment target
- Swift 5.9+
- Gemini API key (see `Secrets.xcconfig.template`)
然后 Build & Run。`GeminiService` 会先读取进程环境变量,再读取 Info.plist 中由 build setting 展开的 `OPENROUTER_API_KEY`。

### Setup
仓库保留了 `Secrets.xcconfig.template`,但当前 `project.pbxproj` 没有把 `Secrets.xcconfig` 设为 base configuration;**仅复制模板不会自动注入 key**。若需要 archive,应在 Xcode build settings/CI secret 中显式提供该值,且不要提交 key。

1. Clone and open the project:
```bash
git clone <repository-url>
cd SkinLab
open SkinLab.xcodeproj
```
命令行构建:

2. Configure secrets:
- Copy `Secrets.xcconfig.template` to `Secrets.xcconfig`
- Set your API key in the new file (see template for key name)
- Do NOT commit `Secrets.xcconfig` to version control
```bash
xcodebuild build \
-project SkinLab.xcodeproj \
-scheme SkinLab \
-destination 'platform=iOS Simulator,name=iPhone 15' \
CODE_SIGNING_ALLOWED=NO \
OPENROUTER_API_KEY='<your-key>'
```

3. Build and run on simulator or device:
```bash
xcodebuild -scheme SkinLab -destination 'platform=iOS Simulator,name=iPhone 15'
```
## 第一次使用

### Running Tests
1. 允许相机或相册权限。
2. 按拍摄引导保持光线、角度与清晰度,创建一次分析。
3. 在分析结果中查看分区与问题维度;不要把分数视为医学结论。
4. 从分析结果建立 tracking baseline,并只填写真实使用的产品/生活方式信息。
5. 后续 check-in 尽量复用相同拍摄条件,再查看可靠性与趋势,而不是比较任意两张照片。
6. 在 Profile → Privacy Center 检查 consent、照片保留、导出和删除选项。

```bash
xcodebuild test -scheme SkinLab -destination 'platform=iOS Simulator,name=iPhone 15'
```
### 重要隐私事实

## Project Structure
- SwiftData 保存分析、追踪、产品与 profile records。
- 原图是否在设备侧保留由 Privacy Center 选项控制。
- **AI 请求仍会把压缩图发送给 OpenRouter**;“本地优先”不等于 vision inference 完全离线。
- 社区匹配使用 consent level 与匿名 profile 模型,但使用前仍应审查具体数据流与部署配置。

```
SkinLab/ # App source code
├── App/ # App entry point and configuration
├── Core/
├── Network/ # API services (GeminiService)
│ └── Utils/ # Extensions and utilities
## 工程结构

```text
SkinLab/
├── App/ 应用入口、恢复视图与主导航
── Core/ config、network、camera、OCR、cache、errors
├── Features/
│ ├── Analysis/ # AI skin analysis feature
│ ├── Tracking/ # 28-day effect tracking
│ ├── Engagement/ # Streaks and achievements
│ ├── Community/ # Skin twin and sharing
│ ├── Products/ # Product recommendations
│ ├── Profile/ # User profile management
│ ├── Celebration/ # Achievement celebrations
│ └── Sharing/ # Social sharing services
├── Services/ # Shared business logic services
├── UI/
│ ├── Components/ # Reusable UI components
│ └── Theme/ # Design system and styling
└── Resources/ # Assets and data files

SkinLabTests/ # XCTest target for unit tests
.flow/ # Flow-Next specs and tasks
│ ├── Analysis/ 拍照、AI 分析、结果与 routine
│ ├── Tracking/ session、check-in、趋势与报告
│ ├── Products/ 成分与产品
│ ├── Community/ consent、matching、feedback
│ ├── Engagement/ streak 与 achievements
│ ├── Profile/ 用户资料与 Privacy Center
│ └── Scenario/ 场景化护肤建议
├── Services/ analytics / funnel events
└── UI/ theme 与共享组件
```

架构为 SwiftUI + MVVM/Clean Architecture,持久化使用 SwiftData,图片预处理使用 UIKit/Vision 相关能力。

## 测试与质量

```bash
xcodebuild test \
-project SkinLab.xcodeproj \
-scheme SkinLab \
-destination 'platform=iOS Simulator,name=iPhone 15' \
CODE_SIGNING_ALLOWED=NO \
OPENROUTER_API_KEY='CI_PLACEHOLDER_KEY'
```

## Planning Artifacts
仓库还提供:

The `.flow/` directory contains project planning and task tracking:
- Epic specifications in `.flow/specs/`
- Task breakdowns in `.flow/tasks/`
- See [.flow/usage.md](.flow/usage.md) for workflow details
```bash
make help
make lint
make format-check
make test
make test-ui
make quality-quick
```

Key planning documents:
- `fn-1`: Competitor analysis and improvement roadmap
- `fn-2`: Engagement features (streaks, badges)
- `fn-3`: Photo standardization and lifestyle correlation
- `fn-4`: Code quality and test coverage
测试覆盖 Analysis、Tracking、Community、Products、Engagement、Network、Profile、Scenario、Weather 与 UI flows。可用 simulator 名称随本机 Xcode runtime 变化;必要时先运行 `xcrun simctl list devices available`。

## Contributing
## 进一步阅读

See [CLAUDE.md](CLAUDE.md) for development guidelines and AI agent instructions.
- [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) — 工程架构
- [`docs/TESTING.md`](./docs/TESTING.md) — 测试策略
- [`SkinLab/SKIN_TWIN_MATCHING_SYSTEM_DESIGN.md`](./SkinLab/SKIN_TWIN_MATCHING_SYSTEM_DESIGN.md) — matching 设计
- [`DATA_COLLECTION_README.md`](./DATA_COLLECTION_README.md) — 成分/产品数据处理

Key conventions:
- Use Flow-Next (`.flow/bin/flowctl`) for task tracking
- Follow MVVM + Clean Architecture patterns
- Write unit tests for core services
- Keep views under 600 lines
仓库当前没有根 License 文件;分发与商用前请先补充明确授权。
44 changes: 44 additions & 0 deletions assets/readme/hero.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading