docs: 更新项目文档与架构说明

This commit is contained in:
AndyChen1024
2026-09-15 14:35:52 +08:00
parent 547ce92050
commit a5c6a6ddfd
5 changed files with 122 additions and 11 deletions

51
docs/architecture.md Normal file
View File

@@ -0,0 +1,51 @@
# 架构
## 分层与依赖
依赖单向无环:`App → feature/* → core/*`,`App` 额外依赖 `CoreRepository` 装配具体实现。
```
App ──► FeatureHome / FeatureCheckin / FeaturePlan / FeatureProfile / FeatureAuth
│
└──► CoreDomain(协议 + UseCase)──► CoreModel
▲
└── CoreRepository(Fake* 实现)
```
- **CoreModel**:领域模型,`Sendable` 值类型,叶子不依赖任何模块。
- **CoreDomain**:Repository 协议 + UseCase,纯 Swift(不 import SwiftUI / 数据框架)。
- **CoreRepository**:Fake 实现(当前),未来替换为 OfflineFirst(编排 CoreNetwork / CoreDatabase)。
## 数据流(MVVM 单向)
```
Screen(.task) ──► ViewModel.load() ──► UseCase ──► Repository(AsyncThrowingStream)
▲ │
└────────── uiState(@Observable)◄──── yield
```
- ViewModel:`@MainActor @Observable final class`,`private(set) var uiState`。
- UiState:`enum` 关联值(对应 Kotlin sealed interface)。
- 每次 `load()` 先 `loadTask?.cancel()` 再开新 `Task`,实现 `flatMapLatest` 语义。
## 会话 / 登录态
`SessionRepository` 持进程内登录态(Fake 用 Combine `CurrentValueSubject<Bool, Never>`),`AppContainer` 持单例注入所有 ViewModel。
- 外层 `Task` 观察 `observeIsLoggedIn()`;登录态变化 → 取消内层数据 `Task` → 重新订阅。
- **Home**:已登录 `observeHome()`(isGuest=false)/ 游客 `observeGuestHome()`(isGuest=true),无 `loggedOut` 态(游客落地页即未登录首页)。
- **checkin / plan / profile**:登录态 false → `.loggedOut`;true → `.loading` → 数据。
## Feature 一览
| Feature | UiState | 数据源(Repository)|
|---|---|---|
| FeatureHome | loading / success(HomeData, isGuest) / error | observeHome / observeGuestHome |
| FeatureCheckin | loading / success(CheckinRecord) / loggedOut / error | observeCheckin + submitCheckin |
| FeaturePlan | loading / success(PlanRecord) / loggedOut / error | observePlan(+ observePlanSubmit / savePlan)|
| FeatureProfile | loading / success(UserProfile) / loggedOut / error | observeProfile |
| FeatureAuth | 表单态(isSendingCode / countdownSeconds / isSubmitting / errorMessage)| requestSmsCode / login |
## 设计 tokens
品牌色 / 状态色 / 渐变定义在 `DesignSystem/DesignTokens.swift`(`DS.Color` / `DS.Gradient`),对齐 wechat-clock-mini / android-client 的 designsystem。

31
docs/progress.md Normal file
View File

@@ -0,0 +1,31 @@
# 工作状态
> 跨会话状态快照,变更后请更新。
## 当前状态
- ✅ 四主入口 Tab(首页 / 打卡 / 计划 / 我的)+ 登录页 + 提交计划页,全部 SwiftUI 实现。
- ✅ 数据层为 Fake 实现(进程内 mock),对齐 android-client 的简化形态。
- ✅ 登录态驱动:`SessionRepository`(Combine `CurrentValueSubject`)+ 各页 `loggedOut` 态。
- ✅ `swift build` 与模拟器 `xcodebuild` 均通过。
## 已完成
- [x] CoreModel 领域模型(Home / Checkin / Plan / Profile / Auth-Session)
- [x] CoreDomain Repository 协议 + UseCase(Home / Checkin / Plan / Profile / Session)
- [x] CoreRepository Fake 实现(含可提交的 checkin / plan、会话)
- [x] FeatureHome(落地页)/ FeatureCheckin / FeaturePlan(+提交页)/ FeatureProfile / FeatureAuth
- [x] DesignSystem 品牌 tokens;AppContainer DI + AppRootView 导航(Tab + sheet 登录 + 推入提交页)
## 下一步
1. 接入真实后端:CoreNetwork 定义 API + DTO(对应 wechat-backend `/api/v1/*`),CoreRepository 替换为 OfflineFirst。
2. CoreDatabase 落地 SwiftData schema(打卡 / 计划 / 用户)。
3. 真实图片上传(计划附件、头像)与隐私协议跳转页。
4. 单元测试(ViewModel / UseCase / Fake 仓库)。
## 遗留项(暂缓)
- 计划附件上传、头像上传仍是占位(与 android 一致)。
- `webview`(H5)能力未引入,首页为纯原生落地页。
- 未跑 `swiftlint`(本机未安装)。