Compare commits
3 Commits
fbcd734688
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 18d735cc12 | |||
| 86b45376d0 | |||
| fdba9cf9c4 |
@@ -1,18 +1,18 @@
|
|||||||
# Patbond Flutter
|
# Patbond Flutter
|
||||||
|
|
||||||
Patbond
|
Patbond 客户端,可运行在 Android、iOS、Web 和桌面平台。
|
||||||
|
|
||||||
可运行在 Android、iOS、Web 和桌面平台。
|
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
- 社区动态搜索、点赞、收藏与评论
|
- 注册登录、当前用户资料与头像、宠物头像
|
||||||
- 模拟 AI 图片/视频创作和社区发布
|
- 宠物档案、体重与疫苗记录、健康档案与照护提醒
|
||||||
- 宠物资料、疫苗记录及健康档案管理
|
- 社区:Feed 游标分页、帖子发布与详情、单层评论、点赞与收藏、关注
|
||||||
- 医院、美容和个人服务搜索、筛选与模拟预约
|
- 中文本地化(`flutter_localizations`)与统一的日期录入
|
||||||
- 使用 `shared_preferences` 持久化宠物、疫苗和帖子数据
|
- AI 创作(M4 进行中)
|
||||||
|
|
||||||
AI 创作、预约、账号和部分菜单目前仍为本地演示交互。
|
**仍为本地演示交互的部分**:AI 创作页(M4 的替换目标)、预约、以及首页的天气/位置/圈子/促销卡四张卡片。后四项是**刻意保留的 demo 占位**并已在 ADR-022 登记去向,不是遗漏——天气与位置需接外部服务,圈子实为话题(ADR-018 剪出),促销卡属 M5 服务域。
|
||||||
|
|
||||||
|
数据以服务端为唯一事实来源,`shared_preferences` 只用于本地偏好与 anonymousId,不再持久化业务数据。
|
||||||
|
|
||||||
## 运行
|
## 运行
|
||||||
|
|
||||||
@@ -28,11 +28,49 @@ Web 调试:
|
|||||||
flutter run -d chrome
|
flutter run -d chrome
|
||||||
```
|
```
|
||||||
|
|
||||||
## 验证
|
后端地址通过 `--dart-define` 注入,默认指向本机各服务端口(auth 8081 / user 8082 / pet 8083 / community 8084 / creation 8085)。
|
||||||
|
|
||||||
|
## 本地门禁
|
||||||
|
|
||||||
|
与 CI 同一套命令(`.gitea/workflows/ci.yml`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dart format --output=none --set-exit-if-changed lib test
|
dart format --output=none --set-exit-if-changed lib test
|
||||||
flutter analyze
|
flutter analyze
|
||||||
flutter test
|
flutter test
|
||||||
flutter build apk --debug
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**每人每仓启用一次** pre-commit 凭证防泄漏钩子(ADR-021):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git config core.hooksPath scripts/hooks
|
||||||
|
```
|
||||||
|
|
||||||
|
`scripts/check-secrets.sh` 是四仓同构副本,调整规则时四仓同步提交。
|
||||||
|
|
||||||
|
## 手工 E2E 脚本
|
||||||
|
|
||||||
|
仓库根目录下的 `test_e2e_*_manual.dart` 是按迭代累积的端到端烟囱脚本,需要一个在跑的后端,用 `dart run` 执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dart run test_e2e_m3_manual.dart
|
||||||
|
```
|
||||||
|
|
||||||
|
两点须知:
|
||||||
|
|
||||||
|
- 这些脚本**不被 `flutter test` 收集**,因此常规测试跑绿并不代表它们跑过;它们只在发布回归时手工执行。
|
||||||
|
- 它们**被 `flutter analyze` 覆盖**,所以文件顶部需要 `// ignore_for_file: avoid_print`。
|
||||||
|
|
||||||
|
发布回归要求跑**全部**脚本,份数以 `patbond-doc` 的 `docs/development/releases.md` 为准。
|
||||||
|
|
||||||
|
## 真机验证
|
||||||
|
|
||||||
|
部分能力桌面端不可替代(移动端后台生命周期、`platform` 枚举不含 linux 故桌面埋点会被服务端拒收、选图与压缩无桌面实现),这些项目集中登记在 `patbond-doc` 的 `docs/development/device-verification.md`,含逐项步骤与通过标准。**模拟器是被接受的路径**,不必等真机。
|
||||||
|
|
||||||
|
## 相关仓库
|
||||||
|
|
||||||
|
| 仓库 | 内容 |
|
||||||
|
| --- | --- |
|
||||||
|
| `patbond-api` | Spring Boot 多模块后端 |
|
||||||
|
| `patbond-ai` | AI 生成服务(Python),只调服务商 API |
|
||||||
|
| `patbond-doc` | 契约(`docs/api/openapi.yaml`)、架构决策(`docs/architecture/decisions.md`)、迭代报告与发布记录 |
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
# check-secrets.sh —— 凭证防泄漏检查(ADR-021,规范见 patbond-doc docs/development/git-workflow.md)
|
# check-secrets.sh —— 凭证防泄漏检查(ADR-021,规范见 patbond-doc docs/development/git-workflow.md)
|
||||||
#
|
#
|
||||||
# 规则单一来源:本地 pre-commit 与 CI 兜底跑的是同一个脚本、同一张规则表。
|
# 规则单一来源:本地 pre-commit 与 CI 兜底跑的是同一个脚本、同一张规则表。
|
||||||
# 三仓(patbond-api / patbond-flutter / patbond-doc)各存一份同构副本,改规则时三仓同步。
|
# 四仓(patbond-api / patbond-flutter / patbond-doc / patbond-ai)各存一份同构副本,
|
||||||
|
# 改规则时四仓同步提交。patbond-ai 是唯一持有 AI 服务商凭证的仓,尤其不可漏。
|
||||||
#
|
#
|
||||||
# 用法:
|
# 用法:
|
||||||
# sh scripts/check-secrets.sh --staged # pre-commit:扫暂存区内容(经 scripts/hooks/pre-commit 调用)
|
# sh scripts/check-secrets.sh --staged # pre-commit:扫暂存区内容(经 scripts/hooks/pre-commit 调用)
|
||||||
@@ -15,7 +16,18 @@ set -u
|
|||||||
mode="${1:---all}"
|
mode="${1:---all}"
|
||||||
|
|
||||||
# 允许清单:行内出现任一形态即放行(${} 注入、占位值、明显示例值)
|
# 允许清单:行内出现任一形态即放行(${} 注入、占位值、明显示例值)
|
||||||
ALLOW='\$\{[^}]*\}|\{\{[^}]*\}\}|changeme|change[-_]me|your[-_][a-zA-Z0-9_-]+|<[a-zA-Z0-9 ,_.-]+>|placeholder|example|sample|dummy|fake|redacted|\*\*\*'
|
# 注:x{3,}(xxx / xxxx…)是本项目文档描述凭证形态时的既有占位约定,
|
||||||
|
# 放行它使「讲解规则的文档」不会被规则自身拦下(如 iteration-4/08 §漏检清单)。
|
||||||
|
ALLOW='\$\{[^}]*\}|\{\{[^}]*\}\}|changeme|change[-_]me|your[-_][a-zA-Z0-9_-]+|<[a-zA-Z0-9 ,_.-]+>|placeholder|example|sample|dummy|fake|redacted|\*\*\*|x{3,}'
|
||||||
|
|
||||||
|
# 依赖注入的传参不是字面量密钥:`api_key=settings.api_key`、
|
||||||
|
# `.param("secretKey", props.getSecretKey())` 这类行里没有任何秘密,而做 DI 的
|
||||||
|
# 代码到处都是这种写法——不放行就得在每个调用点绕过一次。
|
||||||
|
# 收得很紧,避免把真凭证放进来:
|
||||||
|
# * 值必须是**未加引号**的小写起首标识符引用(真密钥要么带引号,要么不是标识符形状)
|
||||||
|
# * 只允许**恰好一个点**且随即行尾(JWT 是 a.b.c 三段,仍会被拦)
|
||||||
|
# * 连字符不在字符集内(sk-ant-… 这类前缀仍会被拦)
|
||||||
|
ALLOW_REFERENCE='[:=][[:space:]]*[a-z][a-zA-Z0-9_]*\.[a-z][a-zA-Z0-9_]*[[:space:]]*[,);]?$'
|
||||||
|
|
||||||
# 内容扫描跳过:本脚本与 hook 自身(含规则文本,非凭证)
|
# 内容扫描跳过:本脚本与 hook 自身(含规则文本,非凭证)
|
||||||
SKIP_PATHS='(^|/)scripts/(check-secrets\.sh|hooks/pre-commit)$'
|
SKIP_PATHS='(^|/)scripts/(check-secrets\.sh|hooks/pre-commit)$'
|
||||||
@@ -29,9 +41,11 @@ RULES=$(cat <<'EOF'
|
|||||||
AK-AWS - - AKIA[0-9A-Z]{16}
|
AK-AWS - - AKIA[0-9A-Z]{16}
|
||||||
AK-QCLOUD - - AKID[0-9A-Za-z]{16,}
|
AK-QCLOUD - - AKID[0-9A-Za-z]{16,}
|
||||||
AK-ALIYUN - - LTAI[0-9A-Za-z]{12,}
|
AK-ALIYUN - - LTAI[0-9A-Za-z]{12,}
|
||||||
|
AK-ANTHROPIC - - sk-ant-[A-Za-z0-9_-]{16,}
|
||||||
|
AK-OPENAI - - sk-(proj-|svcacct-)?[A-Za-z0-9]{20,}
|
||||||
MINIO-DEFAULT i - minio[-_.]?admin
|
MINIO-DEFAULT i - minio[-_.]?admin
|
||||||
PRIVATE-KEY - - ^[[:space:]]*-----BEGIN [A-Z ]*PRIVATE KEY-----[[:space:]]*$
|
PRIVATE-KEY - - ^[[:space:]]*-----BEGIN [A-Z ]*PRIVATE KEY-----[[:space:]]*$
|
||||||
KEY-ASSIGN i - (access[-_]?key(_?id)?|secret[-_]?(access[-_]?)?key)["']?[[:space:]]*[:=][[:space:]]*["']?[A-Za-z0-9+/=_-]{8,}
|
KEY-ASSIGN i - (access[-_]?key(_?id)?|secret[-_]?(access[-_]?)?key|api[-_]?(key|secret|token)|auth[-_]?token)["']?[[:space:]]*[:=][[:space:]]*["']?[A-Za-z0-9+/=_-]{8,}
|
||||||
JWT-SECRET i - (jwt[-_.]?secret|signing[-_]?key|token[-_]?secret|hmac[-_]?(key|secret))["']?[[:space:]]*[:=][[:space:]]*["']?[A-Za-z0-9+/=_-]{8,}
|
JWT-SECRET i - (jwt[-_.]?secret|signing[-_]?key|token[-_]?secret|hmac[-_]?(key|secret))["']?[[:space:]]*[:=][[:space:]]*["']?[A-Za-z0-9+/=_-]{8,}
|
||||||
DB-PASSWORD i \.(ya?ml|properties|toml|conf|ini)(\.sample|\.example)?$ (password|passwd|pwd)["']?[[:space:]]*[:=][[:space:]]*["']?[^[:space:]"'$]{6,}
|
DB-PASSWORD i \.(ya?ml|properties|toml|conf|ini)(\.sample|\.example)?$ (password|passwd|pwd)["']?[[:space:]]*[:=][[:space:]]*["']?[^[:space:]"'$]{6,}
|
||||||
EOF
|
EOF
|
||||||
@@ -85,6 +99,7 @@ for f in $files; do
|
|||||||
ci=""
|
ci=""
|
||||||
[ "$flag" = "i" ] && ci="-i"
|
[ "$flag" = "i" ] && ci="-i"
|
||||||
grep -InE $ci -e "$pat" "$tmp" 2>/dev/null | grep -viE "$ALLOW" |
|
grep -InE $ci -e "$pat" "$tmp" 2>/dev/null | grep -viE "$ALLOW" |
|
||||||
|
grep -vE "$ALLOW_REFERENCE" |
|
||||||
sed "s|^|[$id] $f:|" >>"$viol" || true
|
sed "s|^|[$id] $f:|" >>"$viol" || true
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
@@ -96,7 +111,7 @@ if [ -s "$viol" ]; then
|
|||||||
处置:
|
处置:
|
||||||
1. 若是真实凭证:先去云控制台轮换/禁用该密钥,再从提交中移除;
|
1. 若是真实凭证:先去云控制台轮换/禁用该密钥,再从提交中移除;
|
||||||
2. 若是误报:改用 ${} 注入或占位值(changeme / your-xxx / <占位>),
|
2. 若是误报:改用 ${} 注入或占位值(changeme / your-xxx / <占位>),
|
||||||
或与团队确认后调整三仓同构的 scripts/check-secrets.sh 规则表。
|
或与团队确认后调整四仓同构的 scripts/check-secrets.sh 规则表。
|
||||||
敏感信息只允许存在于被 gitignore 的文件或 .sample 占位中(git-workflow.md)。
|
敏感信息只允许存在于被 gitignore 的文件或 .sample 占位中(git-workflow.md)。
|
||||||
MSG
|
MSG
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user