From e92a7a51fa86b76d5cbc80621736c0fd843e584c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E5=8F=A3=E6=B5=AA=E4=BA=BA?= Date: Sun, 18 Oct 2026 17:59:20 +0800 Subject: [PATCH] docs: organize project guides and consolidate historical records --- README.md | 4 +- README.zh-CN.md | 4 +- RELEASE_NOTES.md | 197 ++++++++++++++++++ docs/README.md | 22 ++ docs/deployment/GITEA_CD.md | 388 ------------------------------------ docs/releases/v0.1.11.md | 7 - docs/releases/v0.1.12.md | 5 - docs/releases/v0.1.13.md | 3 - docs/releases/v0.1.14.md | 5 - docs/releases/v0.1.15.md | 9 - docs/releases/v0.1.16.md | 12 -- docs/releases/v0.1.17.md | 11 - docs/releases/v0.1.18.md | 6 - docs/releases/v0.1.5.md | 31 --- docs/releases/v0.1.6.md | 29 --- docs/releases/v0.1.7.md | 24 --- docs/releases/v0.1.8.md | 13 -- docs/releases/v0.1.9.md | 19 -- 18 files changed, 225 insertions(+), 564 deletions(-) create mode 100644 RELEASE_NOTES.md create mode 100644 docs/README.md delete mode 100644 docs/deployment/GITEA_CD.md delete mode 100644 docs/releases/v0.1.11.md delete mode 100644 docs/releases/v0.1.12.md delete mode 100644 docs/releases/v0.1.13.md delete mode 100644 docs/releases/v0.1.14.md delete mode 100644 docs/releases/v0.1.15.md delete mode 100644 docs/releases/v0.1.16.md delete mode 100644 docs/releases/v0.1.17.md delete mode 100644 docs/releases/v0.1.18.md delete mode 100644 docs/releases/v0.1.5.md delete mode 100644 docs/releases/v0.1.6.md delete mode 100644 docs/releases/v0.1.7.md delete mode 100644 docs/releases/v0.1.8.md delete mode 100644 docs/releases/v0.1.9.md diff --git a/README.md b/README.md index 960464e..d63778d 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ docker compose up -d Open `http://127.0.0.1:6005` and sign in with the account you created. The browser uses an HttpOnly session cookie; it does not require an API token. Remembered sessions last 30 days. Change the password or sign out in Settings. `FRAME_FLOW_TOKEN` authenticates external API clients and is separate from the KoKonna API key. -The published interface defaults to loopback. For LAN access, explicitly set `WEB_BIND` to your NAS LAN address and choose an available `WEB_PORT`. See [Synology deployment](docs/NAS.md), [build mirrors and caching](docs/BUILDING.md), and [Gitea deployment/rollback](docs/deployment/GITEA_CD.md). No firewall, router or reverse-proxy settings are changed automatically. +The published interface defaults to loopback. For LAN access, explicitly set `WEB_BIND` to your NAS LAN address and choose an available `WEB_PORT`. See [Synology deployment](docs/NAS.md), [build mirrors and caching](docs/BUILDING.md). No firewall, router or reverse-proxy settings are changed automatically. For a local mock demo, use Python 3.14: @@ -95,3 +95,5 @@ Tests mock cloud/device calls. CI also verifies an isolated Docker build, readin Cloud synchronization does not prove the physical pixels refreshed. KoKonna cloud uploads activate immediately, so upload-only uses local staging. Native slideshow membership editing is unavailable; avoid running native and Frame Flow playback simultaneously. Smart cropping is a saliency heuristic, not guaranteed face detection. The service uses one worker and is not designed for multiple replicas. Browser OAuth, AI daily-art scheduling, additional calendar recurrence features and more device drivers remain roadmap items. Related projects: [PIGWay Raspberry Pi Agent](https://tea.pigway.com/way/pigway-raspberry-pi-agent) · [PIGWay Device Console](https://tea.pigway.com/way/pigway-device-console) · [PIGWay Yahboom Cooling HAT](https://tea.pigway.com/way/pigway-yahboom-cooling-hat) + +[Documentation](docs/README.md) diff --git a/README.zh-CN.md b/README.zh-CN.md index 61beeb3..cd40bf1 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -26,7 +26,7 @@ docker compose up -d 打开 `http://127.0.0.1:6005`,使用刚创建的账号登录。网页使用 HttpOnly 会话 Cookie,无需输入 API Token;勾选记住登录后会话有效期为 30 天,可在设置中修改密码或退出。`FRAME_FLOW_TOKEN` 用于外部 API 客户端鉴权,与 KoKonna API Key 分开。 -默认端口只绑定本机回环地址。需要局域网访问时,显式将 `WEB_BIND` 设置为 NAS 的局域网地址,并通过 `WEB_PORT` 选择空闲端口。参见[群晖部署](docs/NAS.md)、[构建镜像源与缓存](docs/BUILDING.md)和 [Gitea 部署与回滚](docs/deployment/GITEA_CD.md)。不会自动修改防火墙、路由器或反向代理。 +默认端口只绑定本机回环地址。需要局域网访问时,显式将 `WEB_BIND` 设置为 NAS 的局域网地址,并通过 `WEB_PORT` 选择空闲端口。参见[群晖部署](docs/NAS.md)、[构建镜像源与缓存](docs/BUILDING.md)。不会自动修改防火墙、路由器或反向代理。 使用 Python 3.14 运行本地 Mock 演示: @@ -97,3 +97,5 @@ KoKonna 是支持的设备集成。本项目与 KoKonna 无隶属关系,也不 云端同步不等于已确认物理屏幕刷新。KoKonna 云端上传会立即切换,因此“仅上传”使用本地暂存。官方接口不支持编辑原生轮播成员,应避免原生轮播与 Frame Flow 播放同时运行。smart 裁切采用显著性启发式,不保证识别人脸。当前服务使用单 Worker,不面向多副本部署。浏览器 OAuth、AI 每日艺术调度、更多日历重复规则及设备驱动仍属于后续计划。 相关项目:[PIGWay Raspberry Pi Agent](https://tea.pigway.com/way/pigway-raspberry-pi-agent) · [PIGWay Device Console](https://tea.pigway.com/way/pigway-device-console) · [PIGWay Yahboom Cooling HAT](https://tea.pigway.com/way/pigway-yahboom-cooling-hat) + +[文档目录](docs/README.md) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md new file mode 100644 index 0000000..9f0a228 --- /dev/null +++ b/RELEASE_NOTES.md @@ -0,0 +1,197 @@ +# 版本记录 + +以下为已有版本记录,不代表当前生产运行状态。当前安装与开发说明见项目首页。 + +## v0.1.19 + +- 修正 v0.1.18 的群晖照片方向筛选:Photos 返回的 resolution 已按显示方向转正,不能再按 EXIF 交换宽高。横向来源排除竖图,竖向来源保留竖图。 +- 保留下载后、裁剪前对实际图片的 EXIF 方向校验,防止预览或元数据不一致导致错误裁剪。 +- 使用共享与个人空间的合成数据覆盖 EXIF 5–8,验证已转正尺寸不会重复旋转。 +- 不修改 NAS 原图,不自动重新生成或发送已有图库照片;发行制品保留 LICENSE、NOTICE,私有配置和验证回执留在仓库外。 + +## v0.1.18 + +- Synology Photos 列表显式请求照片方向信息;按 EXIF 旋转后的宽高筛选横向、竖向和自动方向,避免存储像素为横向的竖拍照片误入横图来源。 +- 渲染前复核实际取得图片的 EXIF 方向;若元数据或缓存预览与来源方向不符,则跳过该候选。显式选择方向不符的照片时返回明确错误。 +- 保持既有水印和铺满布局,不修改 NAS 原照片、来源设置或现有图库;修复不自动重新生成、上传或切换已显示图片。 +- 源码及镜像保留 LICENSE、NOTICE;公开验证只使用合成照片和通用示例,私有部署参数与回执保存在仓库之外。 + +## v0.1.17 + +- 总览预览改用原图,避免放大低分辨率缩略图。 +- 云端图库缩略图升级为最大 860×860,等比缩放、JPEG 质量 88;原位替换旧缓存,仍只保留一档。点击放大继续读取原图。 +- 照片源新增最小短边、最小长边参数,同时检查源照片和实际取得的预览尺寸,默认 0 不限制。 +- 本地图库显示 NAS 原照片完整路径并支持换行,保留原文件名大小写和后缀;历史四张图片已按照片 ID 核实并补齐来源。 +- 自动化新增“目标相框”列;历史记录的状态、结果、调用方及操作按钮垂直居中。 +- 左上角统一显示 PIGWay Frame Flow,移除图标和重复品牌前缀。 +- 设置与鉴权保持左右并排、卡片等高,鉴权内部单列。图片预览弹窗保留原有布局。 + +不修改 NAS 原照片,不主动切换真实画框。清理仅针对项目临时构建物及过期镜像,保留持久数据和近期回滚资源。 + +## v0.1.16 + +统一 PIGWay 品牌写法,优化图库、自动化、历史记录、设置、连接中心和拼图页面布局。 + +- 图库直接点击图片查看,移除重复的查看按钮;缩略图底框为正方形,卡片宽度适配单行操作按钮。 +- 全站共用更宽的内容区域,宽屏图库可一行显示三张卡片;搜索、排序、来源和任务筛选合并排列。 +- 自动化与历史记录状态改为仅保留颜色的文字,优化列宽与操作对齐。 +- 设置与鉴权信息保持左右并排,鉴权卡片内部信息改为单列;相关设置控件紧凑排列。 +- 连接中心和自动拼图短字段合并排列,按钮按内容宽度显示,空结果提示不再占据额外空间。 +- 窄屏自动换行,保留图片预览、长文本和表格所需空间。 + +本轮界面检查覆盖 11 个主页面、本地图库及弹窗,中英文、明暗主题和四种屏幕宽度共 289 项布局检查通过;隔离环境拼图流程 8 项检查通过。生产部署后的界面复查使用隔离数据,没有执行真实画框写入。 + +## v0.1.15 + +自动照片、拼版、模板及数据模板任务在上传失败后,持久保存同一张暂存图片,并在下一次计划之前安排最多 5 次额外重试。间隔按 1、2、4、8、16 权重递增,随剩余窗口缩放,计划时间集中在窗口前半段,为上传与设备同步留出时间。重试不移动原定计划,也不复用旧操作 ID;每次独立记录操作及事件。成功后取消剩余重试,重启后沿用已有计数与截止时间;停用任务不再追加重试,删除任务取消其重试计划。 + +若额外重试均失败,下一次计划仍先上传同一张图;若这一次仍失败,只删除该任务未入库、未星标的生成缓存,再按照片源生成并上传新图。NAS 原照片、用户上传文件和成功图库图片不由此流程删除。新图仍失败时,进入它自己的下一轮恢复窗口。 + +上传结果未知不再阻塞后续独立上传。每次重试前先只读核对设备及云图库,精确确认已成功的上传不再重传;需继续尝试时关闭旧尝试并保留错误和核对审计。删除、恢复及自动清理仍保留各自的保护条件。重试窗口到期后不再启动额外上传,待同步尝试经核对结束后交给原计划执行。 + +任务生成图片先保存在缓存,确认任务成功后才进入本地图库;失败不会产生看似成功的本地图库记录。额外重试仍归属原任务的云端保留规则,任务列表显示最近尝试结果。 + +## v0.1.14 + +底部文字仅显示日期、已命名人物(使用 & 连接)、文件夹主题及地点,不显示原始文件名。原始文件名仍用于图库和诊断记录。 + +上传传输区分明确的 DNS/连接建立失败与已建立连接中断:前者尚未发送 HTTP 写入,最多重试三次,失败后结束该次操作,不进入阻塞后续写入的 UNKNOWN;读超时或连接中断等不确定结果继续保留核对保护,不盲目重放上传。既有未知操作通过只读设备/图库核验后使用原有 acknowledge 流程关闭,保留原始错误和审计记录。 + +## v0.1.13 + +照片底部同时显示所有已识别且已命名的人物,人物之间使用 ` & `;日期、人物、主题、地点及文件名之间继续使用 ` · `。例如 `2026-10-18 · Alice & Bob · Family · one.jpg`。人物仍来自 Photos 实际相册归属,未命名人物不显示;历史生成图片不自动重绘。 + +## v0.1.12 + +修复临时展示到期或手动恢复后,“上一张图片”仍指向当前图片,导致已确认删除仍被恢复保护拦截的问题。只有设备已确认同步到受管理的当前图片、且没有基础恢复目标、临时展示或待确认写入时,才清除这条自身引用;不同图片的有效恢复引用继续受保护。既有残留引用在读取设备状态或删除校验时自动修正,不需要强制删除图片或重置数据库。 + +有效恢复引用仍拒绝删除,并通过结构化原因显示中英文提示。保留当前图片删除确认,不主动删除照片或切换画框。 + +## v0.1.11 + +照片底部单行按“日期 · 已命名人物 · 主题 · 地点 · 文件名”排列,空项省略,人物之间也使用 ` · `。主题、日期和地点沿用最近的日期文件夹解析;没有结构化日期目录时仍保留文件名。人物来自 Synology Photos 已命名人物相册的实际图片归属,按账号会话和空间缓存 15 分钟,不显示未命名人物编号。人物查询失败时保留图片及其他描述。 + +新建照片源默认开启底部文字,既有来源保留明确设置。横向来源继续同时约束选图和生成画布,不拉伸图片。更新来源表单说明与浏览描述顺序。 + +使用既有 Ubuntu Server 发布流程,备份配置、数据库与 Compose,从提交源码构建并核验部署哈希;失败恢复旧 Compose。发布过程不主动切换真实画框,不重绘历史图库图片。 + +## v0.1.9 + +照片来源通过 Synology Photos API 按账号权限读取,共享/个人空间、人物 any/all 筛选和有界 XL 预览缓存可用。生产拒绝文件系统照片来源及 /photos 挂载;本地上传、生成图片和 Server 本地图库继续保留。NAS 原图下载接口曾被拒绝,本版不宣称支持原图下载。 + +自动化新增 1~10080 分钟的真实间隔,跨整点与跨天不按 Cron 字段重置,既有 Cron 任务保持原样。显示时长明确为到期恢复期限。统一来源快捷创建任务编辑器,改善登录及来源表单响应式布局、设备显示名与历史记录中英文;诊断详情保留原始标识。 + +## 生产部署 + +生产已迁至 Ubuntu Server,由 systemd 管理 Docker;业务、Docker 数据和恢复资料位于 T7,并有 UUID 与挂载依赖保护。NAS 旧 Frame 专属资源已清理且独立复核 PASS。CI 保留隔离验证,移除 NAS 自动生产部署任务,不再向 NAS 发布。 + +正式发布使用 scripts/server-release.py:仅在既有 Ubuntu Server 环境运行,从已提交源码包构建,校验依赖锁、源码哈希、T7 UUID、容器安全约束和真实写入设置;备份 SQLite、配置及 Compose 后切换镜像,失败恢复旧 Compose,不自动回写旧数据库。它不执行上传、显示、删除或恢复图片等设备操作。成功后记录正式提交号、保存源码包及审计回执,删除本次暂存目录;白名单内的 Frame 旧迁移输入归档到本次 recovery,清除无恢复引用的临时镜像别名,共享 Console 资料不动。旧镜像及历史恢复资料保留供回滚,不执行全局 prune。 + +脚本要求由 git archive 生成的源码放在 /migration-inbox 的独立子目录;目录内同时提供 RELEASE_COMMIT、RELEASE_HASHES.json 和原始 source.tar.gz。哈希清单涵盖源码与源码包,不含自身。执行 sudo python3 <暂存目录>/scripts/server-release.py;成功后读取 /apps/pigway-frame-flow/release-verification.json 并独立检查线上接口。 + +## 验收范围 + +完整后端测试、静态检查与桌面/平板/手机的中英文浏览器回归纳入发布检查。线上历史补丁已核验,真实写入保持开启;本轮正式发布不重复真实设备写入测试。隔离浏览器验证与真实设备写入证据由维护者私下保管。 + +局域网 HTTPS、独立加密备份及恢复演练仍是后续工作;T7 recovery 不属于独立备份。没有执行 USB 断连、服务器重启或压力测试。 + +## PIGWay Frame Flow v0.1.8 + +增加 NAS 本地图库反选、放大总览图片,并统一图片查看器与界面表达。 + +- 反选只切换当前页可见图片的勾选状态;隐藏勾选项的批量操作范围明确提示。 +- 总览当前图片预览增大,点击或键盘打开与图库相同的查看器,读取原图并支持适应屏幕、原始尺寸和 Esc 关闭。 +- 修正图库排序、播放顺序、型号信息来源、云端确认状态等标签,补齐天气与连接状态翻译。 +- 区分本地与云端删除影响,解释星标保留规则,避免对未知来源作无依据判断。 +- 修正数据源空态、路径与凭据说明;同步 README 和操作文档中的共享 Photos 登录机制与入口。 + +验证:305 项布局检查、8 组星标与反选检查、12 组总览查看器检查、45 项图片加载检查及新增中英文文案检查通过。全套后端与静态检查由本次发布流水线再次验证。检查不涉及真实照片删除、设备写入或收费 AI 调用。 + +Improve NAS gallery selection, dashboard image viewing and UI wording. Invert selection affects visible items on the current page. Dashboard previews open the same full-image viewer as the gallery. Storage destinations, deletion scope, server-side stars, cloud confirmation and shared Photos credentials are clarified in both languages. + +## PIGWay Frame Flow v0.1.7 + +## 简体中文 + +修复首次打开图库时内容区空白、必须等待云端图片列表返回才出现控件的问题。 + +- 目的地标签、搜索、排序、刷新和上传按钮立即初始化,图片列表独立请求。 +- 仅在工具栏提示正在读取列表;未知数量时不生成图片卡片,不提前显示“图库为空”。实际图片仍在自己的区域内独立加载。 +- 启动使用轻量设备身份目录,完整设备状态在后台更新,避免厂商状态请求阻塞首屏。 +- 慢请求期间可以切换到 NAS 图库;过期响应不会覆盖当前页面。 +- 列表失败时保留控件并在工具栏显示错误,仍可刷新或切换目的地。 +- 保留等待期间输入的搜索词和排序选择;本地任务筛选请求在同一次导航内复用。 + +### 验证 + +本地 508 项 Python 测试、Ruff、格式检查、mypy 和 JavaScript 语法检查通过。 +新增首次未缓存列表的控件就绪、输入保留、慢云端切换和列表失败回归。 +不增加图库列表的服务端缓存,不修改厂商请求重试、照片、生成内容或设备写入策略。 + +## English + +Fix the blank gallery on its first uncached visit. Destination tabs and gallery controls initialize before metadata requests complete. +Slow or failed cloud listing does not prevent switching to NAS storage. Search and sort choices survive list arrival, and stale responses cannot replace the active destination. +Only a small toolbar status indicates metadata loading; real images keep independent loading indicators. + +## PIGWay Frame Flow v0.1.6 + +## 简体中文 + +- 图库使用具体目的地标签:`KoKonna 云端图库` 与 ` 本地图库`,NAS 名称通过 `FRAME_FLOW_STORAGE_NAME` 配置。 +- Settings API 增加目的地元数据,标签仅展示连接已配置、明确支持保存且存在适配器的目的地;全局写入保护保持独立。 +- 后续网盘须实现读取/保存适配器并完成连接后才能加入标签栏,显示具体服务商/实例名称。当前只读照片来源不会作为保存目的地展示。 +- 长标签在手机上换行,避免整页横向溢出;中英文保持相同目的地身份。 +- Compose 和自动部署透传 NAS 展示名称;分支 CI 完整验证后发布标签,避免相同提交的标签推送重复占用构建队列。 + +### 验证 + +本地 507 项 Python 测试、Ruff、格式检查、mypy、JavaScript 语法检查通过。 +图库目的地标签与能力过滤 18 项浏览器检查通过;覆盖 320–1440 像素、中英文、明暗主题和长 NAS 名称。 +本次不增加任何网盘写入功能,不改变画框写入策略。 + +### 升级 + +Compose 设置 `FRAME_FLOW_STORAGE_NAME`;Actions 设置同名仓库 Variable。 +名称只描述实例,不作为路径或授权凭据。未设置时回退为 NAS。 +默认访问端口仍为 6005,容器内部端口仍为 18787。 +NAS 源码包与 SHA256 附件不含运行配置、密钥、数据库或私人照片,需自行构建镜像。 + +## English + +Gallery tabs identify the concrete destination: KoKonna cloud gallery and the configured NAS name plus Local gallery. +Destination metadata includes connection and upload capabilities; only implemented writable adapters are shown. +Existing read-only cloud photo sources are not presented as save destinations. Long labels wrap on mobile. +Set FRAME_FLOW_STORAGE_NAME in Compose or the Actions repository Variables. No cloud-drive write support or device write policy is changed. + +## PIGWay Frame Flow v0.1.5 + +## 简体中文 + +- 图片仅在真实图片区域内居中显示加载动画,无页面骨架、虚构图片卡片或人为展示延时;请求及解码完成后立即显示,失败时显示局部提示。 +- 图库搜索、排序、卡片操作及写入保护先于图片请求初始化,复用真实列表元数据;本地任务筛选异步填充,不阻塞其他控件。 +- 手动拼版改为并行加载,各图独立完成或失败;固定区域容器保留坐标和拖动交互,加载前后位置一致。 +- 修复手机底栏文字裁切、窄屏页头拥挤和横屏导航可达性,支持底部安全区域,补齐表单标签和当前导航无障碍状态。 +- 默认对外访问端口改为 **6005**。本地启动、Compose、测试地址及文档同步;容器内部仍监听 18787。 + +### 验证 + +本地 505 项 Python 测试、Ruff、格式检查、mypy、JavaScript 语法和差异检查通过。 +浏览器回归:布局 305 项、图片加载 45 项、图库加载顺序 14 项、手动拼版 31 项通过。 +先行 UI 部署的生产静态文件哈希、health/ready 和拦截测试数据下的浏览器交互已验证; +不代表真实 AI 生成、画框写入、手机实机或软键盘测试。 + +### 升级说明 + +已有安装须更新私有环境配置中的 `WEB_PORT=6005`,并重建服务后生效。 +自动部署的 `PROD_WEB_PORT` 必须与现有实例的映射一致;仅修改该变量不能迁移端口。 +NAS 附件是源码部署包,需自行构建 Docker 镜像,不含密钥、运行配置、数据库或私人照片。 + +## English + +Image loading indicators stay inside real image regions, without page skeletons or artificial delays. +Gallery controls initialize before image requests. Manual collage images load independently in parallel, +with stable regions and working coordinate/drag controls. Mobile navigation, safe-area spacing and form +accessibility are improved. The default published port is now **6005**, mapped to container port 18787. +Existing installations must update their private port configuration and recreate the service. +NAS source package and SHA256 checksum are included; this is not a prebuilt Docker image. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..0cd8d21 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,22 @@ +# 文档目录 + +安装、连接及日常使用从[中文首页](../README.zh-CN.md)或[英文首页](../README.md)开始。本目录收录仍适用的功能、配置与开发说明;版本变化见[版本记录](../RELEASE_NOTES.md)。 + +- [自动拼图](AUTOMATIC_COLLAGE.md) +- [构建、缓存与 CI](BUILDING.md) +- [可选连接与扩展](EXTENSIONS.md) +- [厂商请求失败与未知写入处理](KOKONNA_RECOVERY.md) +- [Docker 与群晖安装](NAS.md) +- [照片来源配置](PHOTO_SOURCES.md) +- [照片来源与共享连接](PHOTO_SOURCE_CONNECTIONS.md) +- [公开源码与隐私边界](PUBLICATION.md) +- [真实画框测试步骤](REAL_DEVICE_TEST.md) +- [厂商接口研究概览](RESEARCH.md) +- [Synology Photos API 与来源迁移](SYNOLOGY_PHOTOS_API.md) +- [Ticktar 外部集成契约](integrations/TICKTAR.md) +- [厂商账号能力研究](research/KOKONNA_ACCOUNT_CAPABILITIES.md) +- [厂商内容订阅研究](research/KOKONNA_CONTENT_SUBSCRIPTIONS.md) +- [厂商本地控制研究](research/KOKONNA_LOCAL_CONTROL.md) +- [开发与贡献](../CONTRIBUTING.md) +- [安全问题反馈](../SECURITY.md) +- [第三方声明](../NOTICE.md) diff --git a/docs/deployment/GITEA_CD.md b/docs/deployment/GITEA_CD.md deleted file mode 100644 index c0f0181..0000000 --- a/docs/deployment/GITEA_CD.md +++ /dev/null @@ -1,388 +0,0 @@ -# Gitea Actions production CD v1 (historical) - -> This NAS production deployment procedure is retired. Current Gitea Actions -> only runs isolated verification; production uses the maintainer-specific -> Ubuntu workflow in `scripts/server-release.py`. For a new installation use -> the Docker Compose instructions in README.md. Filesystem/NFS photo sources -> are disabled; use Synology Photos API or WebDAV. The configuration below is -> retained for historical reference and must not be used for new deployments. - -## Audit and adoption boundary - -Production `docker-compose.yml` is unchanged: AMD64 image, UID/GID 10333, -`unless-stopped`, read-only rootfs, `/tmp` tmpfs, dropped capabilities, limited -logs, `/data` and `/config` bind mounts, default private bridge, and configurable -host bind/port. SQLite/images/generated/cache live under `/data`; accounts, -vendor sessions and configuration live under `/config`. Neither is disposable. -The optional photos mount is read-only and has supplementary group access. - -Historical repository receipts mention `/volume1/docker/pigway-frame-flow/data`, -`/volume1/docker/pigway-frame-flow/config`, `/volume1/photo`, port 18787, and -container/project `pigway-frame-flow`. These are **confirmation candidates**, not -script defaults. The deploy action accepts only explicitly configured paths -that match the existing running container on the Runner's Docker daemon. -It rejects different projects, ports, unknown mounts, host/custom networking, -missing photos confirmation, or different user/restart policy. The deploy action does not create NAS host directories or migrate/adopt an unrelated -container. First-time directory creation is limited to the manual bootstrap below. - -CI uses `ffci-*` projects, per-run image tags and named volumes, no host ports. -Its cleanup does not refer to any production resource. Production uses fixed -configured names and existing bind mounts, with `create_host_path: false`. - -## Gitea configuration - -Repository Settings → Actions configuration (private paths/addresses use Secrets): - -| Variable or Secret | Value to explicitly confirm | -| --- | --- | -| `PROD_DEPLOY_ENABLED` | Initially `false`; change to `true` only after plan acceptance | -| `PROD_PROJECT` | Existing Compose project label; candidate `pigway-frame-flow` | -| `PROD_CONTAINER` | Existing container name; candidate `pigway-frame-flow` | -| `PROD_IMAGE_REPO` | Fixed local image repository; suggested `pigway-frame-flow` | -| `PROD_DATA_DIR` (Secret) | Existing absolute NAS host data path; no default | -| `PROD_CONFIG_DIR` (Secret) | Existing absolute NAS host config path; no default | -| `PROD_PHOTOS_DIR` (Secret) | Existing read-only photos source if present; otherwise empty | -| `PROD_WEB_BIND` (Secret) | Exact existing Docker HostIp (`0.0.0.0` or NAS LAN IP etc.) | -| `PROD_WEB_PORT` | Exact existing mapped port | -| `FRAME_FLOW_STORAGE_NAME` | Optional NAS display name for the local gallery; defaults to NAS | -| `PROD_STATE_VOLUME` | Dedicated new deployment journal volume, e.g. `pigway-frame-flow-cd-state` | -| `PROD_MOCK` | Explicit `true`/`false`, consistent with intended production mode | -| `PROD_WRITE_ENABLED` | Explicit `true`/`false`; preserve owner's existing write policy | - -The state volume must be separate from application/CI storage. An existing -volume without the matching `frameflow.deploy.project` label is rejected. -Supplementary groups are read from the existing container; no host ACL changes. -Keep existing `DEBIAN_MIRROR`, `DEBIAN_SECURITY_MIRROR`, `CI_PIP_INDEX_URL`, and -`CI_PIP_FALLBACK_INDEX_URL` settings from Verify; CI/production builds share the -Dockerfile, pinned base, lockfile, and BuildKit caches. - -Repository Settings → Actions → Secrets: - -`PRODUCTION_ENV`: multiline **unquoted** `KEY=value` entries, without shell -expansion. At least: - -```dotenv -FRAME_FLOW_TOKEN= -KOKONNA_API_KEY= -``` - -Optional additional runtime secret variables can be included. No key values are -committed, passed to image builds, or printed. Nonsecret mock/write flags use -Variables. Other existing runtime environment values are retained. The script -sets commit/build time and internal data/config paths explicitly. Dollar signs -in secret values are escaped before Compose interpolation. Snapshots containing -old runtime secrets are stored only in a private journal file (0600, directory -0700) on the dedicated Docker volume; Docker administrators can access it. -Never upload that journal or a full Docker inspect as a public CI artifact. - -## First safe trial - -1. On NAS, inspect only the necessary fields (use existing Docker/sudo access): - ```sh - docker inspect pigway-frame-flow --format '{{index .Config.Labels "com.docker.compose.project"}}' - docker inspect pigway-frame-flow --format '{{json .Mounts}}' - docker inspect pigway-frame-flow --format '{{json .HostConfig.PortBindings}} {{.HostConfig.NetworkMode}}' - ``` - Confirm the Variables/Secrets against these actual values, including photos. -2. Configure the Secret privately. Keep `PROD_DEPLOY_ENABLED=false`. -3. Manually run **Verify Frame Flow** on `main`, `deploy_action=plan`. - Verify must pass first. Plan checks resource identity, paths/port, required - Secret keys, current `/ready`, smoke endpoints and commit. It performs no - build, stop, restart, tagging, lock creation, volume creation, or data writes. - If no production Variables exist, it reports configuration missing and does - nothing; that is an unconfigured plan, not production acceptance. -4. Review `PLAN ONLY` output and arrange a maintenance window for the first real - deploy/restart. Set `PROD_DEPLOY_ENABLED=true`, manually run `deploy_action=deploy`. -5. After `DEPLOY VERIFIED`, subsequent pushes to `main` run Verify → deploy. - Pushes to other branches and pull requests never deploy. A manual run defaults - to plan, even when automatic deployment is enabled. - -The deploy action supports updates to an existing healthy deployment. For first-time -creation use the explicit manual bootstrap flow below. No real production deployment or rollback drill has -been performed during implementation; those are first-run acceptance steps. - -## Deployment transaction and rollback - -1. Verify job must succeed completely, including isolated Docker tests/cleanup. -2. Deploy job checks out the same revision and prepares tools. An atomic - `docker create` reservation named `-deploy-lock` serializes - production changes on the daemon. Job `concurrency` is also declared, but - correctness does not depend on Gitea implementing it. A competing deploy - fails safely instead of changing production. No other job may remove a lock - whose owner label differs from its own. -3. Re-read the current baseline under the lock; confirm ready/smoke. Record exact - image ID, runtime Compose/environment, version/commit. Pin the old image with - an immutable rollback tag so normal dangling-image cleanup cannot remove it. -4. Refuse a stale checked-out `main` revision that no longer equals remote main. - Build an immutable `release--` tag locally, without a registry - then point `latest` at the candidate; CI image tags are never changed. -5. Persist a `prepared` journal with old/new runtime configs. Create an additive - SQLite online backup under `/data/deploy-backups/.db`. No data/config - directory or file is removed, replaced or recursively chowned. -6. `compose up -d --no-build --pull never` replaces only the configured service. - Check `/ready`, the unchanged nine-endpoint read-only smoke test, and exact - `/api/v1/version` commit. Only all checks passing produce `DEPLOY VERIFIED`. -7. Any activation/verification failure runs `up` again with the saved exact old - image ID and old runtime environment/mounts, then repeats ready/smoke/commit - verification. A failed deploy remains a failed workflow even if rollback - succeeds. If rollback fails, the journal/lock are retained, failure is explicit, - and redacted scoped diagnostics are emitted. -8. An `always()` step uses the recorded owner to recover an interrupted prepared - transaction and release only its own lock. Abrupt host loss or termination of - the entire runner can prevent both handlers: inspect the journal/lock before - manually recovering; never automatically force-unlock an unknown owner. - -Rollback is an **image/config rollback**, not an automatic database rewind. -User data accumulated during deployment remains. The SQLite backup is for -operator-reviewed recovery; destructive or backward-incompatible future schema -changes must not be auto-deployed without a separate migration/backup plan. -Baseline artifacts and additive backups are retained for the operator; there is -no automated pruning of production rollback history or data. - -After enabling CD, use its workflow/script as the production lifecycle owner. -The old NAS checkout's Compose/.env files are not rewritten remotely by CD and -may describe an older deployment. Do not concurrently recreate production from -that old checkout. The repository's standalone Compose remains usable for an -independent deployment; the private journal records the CD runtime configuration. - -## Actual commit and manual rollback - -```sh -curl -fsS http://NAS_LAN_IP:PORT/api/v1/version -# Check `commit`, `version`, and `build_time` against successful deployment output. -docker inspect PRODUCTION_CONTAINER --format '{{.Image}}' -``` - -For a manual rollback: keep CD enabled and run **Verify Frame Flow** on `main` -with `deploy_action=rollback`. After Verify passes, the script locks production, -loads the last journal's `previous` image/config and verifies recovery. This is -last-baseline rollback, not an arbitrary image selector. Never use `down -v`, -volume pruning, or delete data/config to roll back. - -If a failed run retained a lock, inspect only its owner label: - -```sh -docker inspect PRODUCTION_CONTAINER-deploy-lock --format '{{index .Config.Labels "frameflow.deploy.owner"}}' -``` - -With the documented Variables configured in a trusted Docker-enabled shell: - -```sh -FRAME_FLOW_DEPLOY_OWNER= CD_ACTION=recover python scripts/production-deploy.py -``` - -`recover` retries that owner's journaled rollback and retains the lock again if -recovery fails. If the very first attempt stopped before a journal was written, -confirm that the original image is still running and healthy before an operator -removes the stale lock. Do not delete a live lock or any persistence volume. - -## First-time production bootstrap (explicit manual action) - -The confirmed NAS residue is a `created`, never-started container with dead -`/workspace/way/...` bind paths. It is not an adoption/rollback baseline. -No migration from those paths is performed. Production Compose remains independently usable. - -Set the ordinary repository Actions Variables below; set paths and addresses as Secrets (see docs/PUBLICATION.md): - -```text -PROD_DEPLOY_ENABLED=true -PROD_PROJECT=pigway-frame-flow -PROD_CONTAINER=pigway-frame-flow -PROD_IMAGE_REPO=pigway-frame-flow -PROD_DATA_DIR=/volume1/docker/pigway-frame-flow/data -PROD_CONFIG_DIR=/volume1/docker/pigway-frame-flow/config -PROD_WEB_BIND=192.0.2.10 -PROD_WEB_PORT=6005 -PROD_STATE_VOLUME=pigway-frame-flow-cd-state -PROD_MOCK=true -PROD_WRITE_ENABLED=false -``` - -Leave `PROD_PHOTOS_DIR` unset/empty. Existing mirror Variables still apply. -Enabling CD does not enable real frame writes. Before the first successful bootstrap, -ordinary main pushes report `production not bootstrapped / bootstrap required`. -They cannot create production. `bootstrap` additionally requires the Actions event -`workflow_dispatch`; the default action remains `plan`. Every action is gated by -successful complete Verify on main. - -Create repository Actions **Secret** `PRODUCTION_ENV` as multiline bare `KEY=value`: - -```dotenv -FRAME_FLOW_TOKEN=replace-with-a-long-random-private-token -KOKONNA_API_KEY= -``` - -Do not add shell quotes, `export`, interpolation or spaces around `=`. An existing -KoKonna key may be supplied but first bootstrap forcibly uses Mock with writes off. -Optional application secrets/settings may be added in the same format; bootstrap -always overrides Mock/write flags, data/config paths, timezone and build identity. -This token remains useful for API/smoke checks even if Web UI uses account login. -Do not paste the real Secret into logs or repository files. - -### Safety and cleanup - -Bootstrap builds the verified main revision first, then acquires the same atomic -Docker daemon deployment lock used by deploy. Host path checks run in a short-lived, -network-disabled helper with **read-only** NAS root mounted, not CI workspace paths. -Synology does not automatically create missing bind sources with `-v`. A temporary -network-disabled helper mounts the explicitly configured existing parent directories -and creates only their data/config leaves, owned `10333:10333`, mode `0750`. It never -mounts NAS root writable, recursively changes parent permissions, or deletes contents. -Parents must already exist; missing parents fail closed. Nonempty directories, symlinks -(including ancestor symlinks), overlapping paths and unknown journal resources fail closed. - -A same-name residue can be removed **without force** only after checking all of: -Compose project/service labels; `Status=created`; `Running=false`; -`StartedAt=0001-01-01T00:00:00Z`; exactly two bind mounts `/data` and `/config`; -and both old host sources absent. A running, previously started, unknown or data-bearing -container is refused. An existing default network must be owned by this Compose -project and contain no endpoints other than the validated residue. - -The production service uses `create_host_path=false`, the explicit NAS LAN bind, -non-root UID, `unless-stopped`, normal bridge network and existing resource/security -limits. Acceptance runs ready, all read-only smoke endpoints, version/commit, -preflight mount/port/project/user/restart checks, one restart, repeated checks, -Docker health and exact built-image ID before `BOOTSTRAP VERIFIED`. - -On failure after transaction preparation, cleanup removes only this transaction's -owner-labelled new container and its newly created, empty, project-labelled network. -The previously validated never-started residue has no rollback value and is not recreated. -**Data/config files, images/build cache and the private CD journal volume are retained.** -No `down -v`, volume prune or removal of unrelated/CI resources is used. -Cleanup failure retains the lock so the always recovery step can retry using the journal. -Only an explicitly dispatched bootstrap may retry a failed first-install journal, and -only when its project/container/mounts/port match, its volume ownership matches, and -target directories remain empty or absent. Prepared/success/foreign journals are refused. -On a new transaction, the prior journal is archived as `deploy..json` inside -the private state volume before replacing the active journal; generated data is never -automatically emptied and journals are never deleted. -Abrupt host/runner loss still requires operator review of the lock/journal. -The journal is private (0700/0600) and may contain prior/candidate secrets; never export it -as an Actions artifact. First bootstrap has no prior healthy version to roll back to. - -### First run and acceptance - -1. In Gitea repository **Actions → Verify Frame Flow → Run workflow**, choose branch - `main`, action **plan**. This is read-only and reports bootstrap required for the - absent/created instance; it is not a bootstrap safety acceptance. Detailed host - residue/directory checks happen under the lock in bootstrap. -2. Run the same workflow on `main` with action **bootstrap**. Verify runs in full first. - No NAS bootstrap is executed merely by committing this implementation. -3. Require `BOOTSTRAP VERIFIED` in the deploy log. In Container Manager confirm - container `pigway-frame-flow` is running/healthy, user 10333, restart unless-stopped, - exact `/volume1/docker/pigway-frame-flow/{data,config}` mounts and - `192.0.2.10:6005` binding (not loopback). -4. Open `http://192.0.2.10:6005/api/v1/version`; its `commit` must equal the full - workflow checkout commit. Check `/ready` returns HTTP 200. The immutable image tag - is `pigway-frame-flow:latest`; compare its image ID in - Container Manager with the running container. -5. Keep `PROD_DEPLOY_ENABLED=true`. Subsequent main pushes Verify then deploy using - this same runtime and journal mechanism. The first update records bootstrap as - its rollback baseline. Repeating bootstrap against this instance is refused. - Enable real-device read-only access and write access only through separate explicit - operator decisions; no automatic change is made by bootstrap. - -Docker tests are mocked locally. The first manual NAS Runner bootstrap, including -real host mounts and restart, remains the required live acceptance. - -## Actions download transport - -Verify and deploy reference official GitHub Actions directly, pinned to immutable -commits rather than moving tags: - -| Action | Official upstream commit | -| --- | --- | -| actions/checkout v4 | 11d5960a326750d5838078e36cf38b85af677262 | -| actions/setup-python v5 | a26af69be951a213d495a4c3e4e4022e16d87065 | - -The workflow uses explicit `https://github.com/actions/...` URLs so Gitea's -configured default Actions host cannot redirect downloads to the project owner's -server. Forks download Actions through their own Runner/network; no public action -mirror is served by this project. The former Tea auxiliary repository is private -and is no longer required by current workflows. - -Keep the Runner's action cache and Python toolcache persistent. For Gitea Runner -versions supporting `cache.offline_mode`, use a private Runner configuration: - -```yaml -runner: - file: /data/.runner -cache: - offline_mode: true -``` - -In the Runner's own Compose service (not the application), set `HOME=/data` and -`CONFIG_FILE=/data/config.yaml`, with `/data` already persisted. Before recreating -an idle Runner, back up its configuration and copy the existing action cache from -`/root/.cache/act` to `/data/.cache/act`. Preserve registration, labels, image, -mounts and networks; do not interrupt active jobs or recreate other services. -Verify cached actions against the pinned upstream commit and tree before reuse. -This is administrator configuration, not a public workflow dependency. - -Offline reuse avoids refreshing cached actions from GitHub on each job. Moving -tags/branches may remain at the cached version; this workflow deliberately pins -immutable SHAs. A new action URL or commit requires an initial download or verified -administrator prewarming; an old mirror subtree is not automatically equivalent -to an upstream Git repository. Do not prune Runner caches between jobs. Python -toolcache misses still download Python from its upstream release source. Network -failures remain failures, never reasons to skip validation or silently fall back -to the owner's Tea server. - -Administrators needing a mainland-specific download route can configure their -own Runner/network cache privately. Such settings must not introduce public -workflow references to a personal mirror. This change does not modify NAS VPN, -proxy, firewall or other applications. All validation and deploy gates remain. - -### Synology Photos dependencies - -For a production photo source using Synology Photos person filtering, configure -`SYNOLOGY_PHOTOS_URL` and `SYNOLOGY_PHOTOS_CERT_SHA256` as Gitea Secrets. The -certificate fingerprint must match the configured HTTPS endpoint. Keep the Photos -session in the persistent `/config` directory; never put session credentials in -Variables or repository files. - -`PROD_PHOTOS_DIR` must identify the actual NAS photo directory mounted read-only -at `/photos`. Adoption requires that mount to exist on the current container; -changing this Variable alone does not create a new mount. Existing supplementary -permission groups are preserved by deployment. - -Restoring SQLite and session files does not restore these runtime dependencies. -Production smoke checks now reject an enabled people-filtered source if its -Photos configuration or stored connection is missing. These checks do not prove -session validity or scan the complete catalog: after restoring a source, also -verify its read-only `/api/v1/photo-sources/{id}/images?limit=1` endpoint before -running an automation task. - -### Advisory-service network resilience - -CI dependency installation uses the domestic `CI_PIP_INDEX_URL` first and the -`CI_PIP_FALLBACK_INDEX_URL` sequentially on failure. These package indexes do not -replace PyPI's vulnerability JSON API. - -`python scripts/ci-audit.py` retains the pinned `requirements.lock`, PyPI advisory -service and `--no-deps --disable-pip` checks. It uses a 60-second socket timeout, -at most three attempts, and 5/10-second backoff only for network failures. Known -vulnerabilities, malformed/incomplete reports and skipped dependencies fail -immediately. Every attempt has a five-minute process limit. A timeout or failed -final attempt still blocks deployment. - -The advisory HTTP cache is reused within the job (including retries) and follows -the audit client's normal HTTP freshness rules. It is not a permanent offline -snapshot or a cross-job cache. Raw network exceptions are omitted because proxy -URLs may contain credentials. Logs identify the advisory host and whether the -complete audit succeeded. - -### Production image retention - -Production uses `pigway-frame-flow:latest`. Builds first create a unique release -image, then tag it as latest before activation. The old image is pinned during -an update so a failed deployment can restore it. Only after the new version -passes verification are old release/rollback images and duplicate tags removed. -After successful deployment, only the current production image remains; there -is no retained historical image for manual rollback. Rebuild a historical -revision before manually reverting a successful deployment. - -Images referenced by other containers (including stopped containers), images -with unrelated tags, and CI resources remain protected. Cleanup never prunes -volumes, data, or shared build cache. Cleanup failure is a warning and does not -roll back a verified deployment. Failed deployments do not run cleanup. diff --git a/docs/releases/v0.1.11.md b/docs/releases/v0.1.11.md deleted file mode 100644 index 117261a..0000000 --- a/docs/releases/v0.1.11.md +++ /dev/null @@ -1,7 +0,0 @@ -# v0.1.11 - -照片底部单行按“日期 · 已命名人物 · 主题 · 地点 · 文件名”排列,空项省略,人物之间也使用 ` · `。主题、日期和地点沿用最近的日期文件夹解析;没有结构化日期目录时仍保留文件名。人物来自 Synology Photos 已命名人物相册的实际图片归属,按账号会话和空间缓存 15 分钟,不显示未命名人物编号。人物查询失败时保留图片及其他描述。 - -新建照片源默认开启底部文字,既有来源保留明确设置。横向来源继续同时约束选图和生成画布,不拉伸图片。更新来源表单说明与浏览描述顺序。 - -使用既有 Ubuntu Server 发布流程,备份配置、数据库与 Compose,从提交源码构建并核验部署哈希;失败恢复旧 Compose。发布过程不主动切换真实画框,不重绘历史图库图片。 diff --git a/docs/releases/v0.1.12.md b/docs/releases/v0.1.12.md deleted file mode 100644 index 96aec59..0000000 --- a/docs/releases/v0.1.12.md +++ /dev/null @@ -1,5 +0,0 @@ -# v0.1.12 - -修复临时展示到期或手动恢复后,“上一张图片”仍指向当前图片,导致已确认删除仍被恢复保护拦截的问题。只有设备已确认同步到受管理的当前图片、且没有基础恢复目标、临时展示或待确认写入时,才清除这条自身引用;不同图片的有效恢复引用继续受保护。既有残留引用在读取设备状态或删除校验时自动修正,不需要强制删除图片或重置数据库。 - -有效恢复引用仍拒绝删除,并通过结构化原因显示中英文提示。保留当前图片删除确认,不主动删除照片或切换画框。 diff --git a/docs/releases/v0.1.13.md b/docs/releases/v0.1.13.md deleted file mode 100644 index 20783b0..0000000 --- a/docs/releases/v0.1.13.md +++ /dev/null @@ -1,3 +0,0 @@ -# v0.1.13 - -照片底部同时显示所有已识别且已命名的人物,人物之间使用 ` & `;日期、人物、主题、地点及文件名之间继续使用 ` · `。例如 `2026-10-18 · Alice & Bob · Family · one.jpg`。人物仍来自 Photos 实际相册归属,未命名人物不显示;历史生成图片不自动重绘。 diff --git a/docs/releases/v0.1.14.md b/docs/releases/v0.1.14.md deleted file mode 100644 index 1cbc385..0000000 --- a/docs/releases/v0.1.14.md +++ /dev/null @@ -1,5 +0,0 @@ -# v0.1.14 - -底部文字仅显示日期、已命名人物(使用 & 连接)、文件夹主题及地点,不显示原始文件名。原始文件名仍用于图库和诊断记录。 - -上传传输区分明确的 DNS/连接建立失败与已建立连接中断:前者尚未发送 HTTP 写入,最多重试三次,失败后结束该次操作,不进入阻塞后续写入的 UNKNOWN;读超时或连接中断等不确定结果继续保留核对保护,不盲目重放上传。既有未知操作通过只读设备/图库核验后使用原有 acknowledge 流程关闭,保留原始错误和审计记录。 diff --git a/docs/releases/v0.1.15.md b/docs/releases/v0.1.15.md deleted file mode 100644 index 5189cb2..0000000 --- a/docs/releases/v0.1.15.md +++ /dev/null @@ -1,9 +0,0 @@ -# v0.1.15 - -自动照片、拼版、模板及数据模板任务在上传失败后,持久保存同一张暂存图片,并在下一次计划之前安排最多 5 次额外重试。间隔按 1、2、4、8、16 权重递增,随剩余窗口缩放,计划时间集中在窗口前半段,为上传与设备同步留出时间。重试不移动原定计划,也不复用旧操作 ID;每次独立记录操作及事件。成功后取消剩余重试,重启后沿用已有计数与截止时间;停用任务不再追加重试,删除任务取消其重试计划。 - -若额外重试均失败,下一次计划仍先上传同一张图;若这一次仍失败,只删除该任务未入库、未星标的生成缓存,再按照片源生成并上传新图。NAS 原照片、用户上传文件和成功图库图片不由此流程删除。新图仍失败时,进入它自己的下一轮恢复窗口。 - -上传结果未知不再阻塞后续独立上传。每次重试前先只读核对设备及云图库,精确确认已成功的上传不再重传;需继续尝试时关闭旧尝试并保留错误和核对审计。删除、恢复及自动清理仍保留各自的保护条件。重试窗口到期后不再启动额外上传,待同步尝试经核对结束后交给原计划执行。 - -任务生成图片先保存在缓存,确认任务成功后才进入本地图库;失败不会产生看似成功的本地图库记录。额外重试仍归属原任务的云端保留规则,任务列表显示最近尝试结果。 diff --git a/docs/releases/v0.1.16.md b/docs/releases/v0.1.16.md deleted file mode 100644 index d128f14..0000000 --- a/docs/releases/v0.1.16.md +++ /dev/null @@ -1,12 +0,0 @@ -# v0.1.16 - -统一 PIGWay 品牌写法,优化图库、自动化、历史记录、设置、连接中心和拼图页面布局。 - -- 图库直接点击图片查看,移除重复的查看按钮;缩略图底框为正方形,卡片宽度适配单行操作按钮。 -- 全站共用更宽的内容区域,宽屏图库可一行显示三张卡片;搜索、排序、来源和任务筛选合并排列。 -- 自动化与历史记录状态改为仅保留颜色的文字,优化列宽与操作对齐。 -- 设置与鉴权信息保持左右并排,鉴权卡片内部信息改为单列;相关设置控件紧凑排列。 -- 连接中心和自动拼图短字段合并排列,按钮按内容宽度显示,空结果提示不再占据额外空间。 -- 窄屏自动换行,保留图片预览、长文本和表格所需空间。 - -本轮界面检查覆盖 11 个主页面、本地图库及弹窗,中英文、明暗主题和四种屏幕宽度共 289 项布局检查通过;隔离环境拼图流程 8 项检查通过。生产部署后的界面复查使用隔离数据,没有执行真实画框写入。 diff --git a/docs/releases/v0.1.17.md b/docs/releases/v0.1.17.md deleted file mode 100644 index d69697c..0000000 --- a/docs/releases/v0.1.17.md +++ /dev/null @@ -1,11 +0,0 @@ -# v0.1.17 - -- 总览预览改用原图,避免放大低分辨率缩略图。 -- 云端图库缩略图升级为最大 860×860,等比缩放、JPEG 质量 88;原位替换旧缓存,仍只保留一档。点击放大继续读取原图。 -- 照片源新增最小短边、最小长边参数,同时检查源照片和实际取得的预览尺寸,默认 0 不限制。 -- 本地图库显示 NAS 原照片完整路径并支持换行,保留原文件名大小写和后缀;历史四张图片已按照片 ID 核实并补齐来源。 -- 自动化新增“目标相框”列;历史记录的状态、结果、调用方及操作按钮垂直居中。 -- 左上角统一显示 PIGWay Frame Flow,移除图标和重复品牌前缀。 -- 设置与鉴权保持左右并排、卡片等高,鉴权内部单列。图片预览弹窗保留原有布局。 - -不修改 NAS 原照片,不主动切换真实画框。清理仅针对项目临时构建物及过期镜像,保留持久数据和近期回滚资源。 diff --git a/docs/releases/v0.1.18.md b/docs/releases/v0.1.18.md deleted file mode 100644 index ab9f361..0000000 --- a/docs/releases/v0.1.18.md +++ /dev/null @@ -1,6 +0,0 @@ -# v0.1.18 - -- Synology Photos 列表显式请求照片方向信息;按 EXIF 旋转后的宽高筛选横向、竖向和自动方向,避免存储像素为横向的竖拍照片误入横图来源。 -- 渲染前复核实际取得图片的 EXIF 方向;若元数据或缓存预览与来源方向不符,则跳过该候选。显式选择方向不符的照片时返回明确错误。 -- 保持既有水印和铺满布局,不修改 NAS 原照片、来源设置或现有图库;修复不自动重新生成、上传或切换已显示图片。 -- 源码及镜像保留 LICENSE、NOTICE;公开验证只使用合成照片和通用示例,私有部署参数与回执保存在仓库之外。 diff --git a/docs/releases/v0.1.5.md b/docs/releases/v0.1.5.md deleted file mode 100644 index a6850cb..0000000 --- a/docs/releases/v0.1.5.md +++ /dev/null @@ -1,31 +0,0 @@ -# PIGWay Frame Flow v0.1.5 - -## 简体中文 - -- 图片仅在真实图片区域内居中显示加载动画,无页面骨架、虚构图片卡片或人为展示延时;请求及解码完成后立即显示,失败时显示局部提示。 -- 图库搜索、排序、卡片操作及写入保护先于图片请求初始化,复用真实列表元数据;本地任务筛选异步填充,不阻塞其他控件。 -- 手动拼版改为并行加载,各图独立完成或失败;固定区域容器保留坐标和拖动交互,加载前后位置一致。 -- 修复手机底栏文字裁切、窄屏页头拥挤和横屏导航可达性,支持底部安全区域,补齐表单标签和当前导航无障碍状态。 -- 默认对外访问端口改为 **6005**。本地启动、Compose、测试地址及文档同步;容器内部仍监听 18787。 - -### 验证 - -本地 505 项 Python 测试、Ruff、格式检查、mypy、JavaScript 语法和差异检查通过。 -浏览器回归:布局 305 项、图片加载 45 项、图库加载顺序 14 项、手动拼版 31 项通过。 -先行 UI 部署的生产静态文件哈希、health/ready 和拦截测试数据下的浏览器交互已验证; -不代表真实 AI 生成、画框写入、手机实机或软键盘测试。 - -### 升级说明 - -已有安装须更新私有环境配置中的 `WEB_PORT=6005`,并重建服务后生效。 -自动部署的 `PROD_WEB_PORT` 必须与现有实例的映射一致;仅修改该变量不能迁移端口。 -NAS 附件是源码部署包,需自行构建 Docker 镜像,不含密钥、运行配置、数据库或私人照片。 - -## English - -Image loading indicators stay inside real image regions, without page skeletons or artificial delays. -Gallery controls initialize before image requests. Manual collage images load independently in parallel, -with stable regions and working coordinate/drag controls. Mobile navigation, safe-area spacing and form -accessibility are improved. The default published port is now **6005**, mapped to container port 18787. -Existing installations must update their private port configuration and recreate the service. -NAS source package and SHA256 checksum are included; this is not a prebuilt Docker image. diff --git a/docs/releases/v0.1.6.md b/docs/releases/v0.1.6.md deleted file mode 100644 index 9e2e147..0000000 --- a/docs/releases/v0.1.6.md +++ /dev/null @@ -1,29 +0,0 @@ -# PIGWay Frame Flow v0.1.6 - -## 简体中文 - -- 图库使用具体目的地标签:`KoKonna 云端图库` 与 ` 本地图库`,NAS 名称通过 `FRAME_FLOW_STORAGE_NAME` 配置。 -- Settings API 增加目的地元数据,标签仅展示连接已配置、明确支持保存且存在适配器的目的地;全局写入保护保持独立。 -- 后续网盘须实现读取/保存适配器并完成连接后才能加入标签栏,显示具体服务商/实例名称。当前只读照片来源不会作为保存目的地展示。 -- 长标签在手机上换行,避免整页横向溢出;中英文保持相同目的地身份。 -- Compose 和自动部署透传 NAS 展示名称;分支 CI 完整验证后发布标签,避免相同提交的标签推送重复占用构建队列。 - -### 验证 - -本地 507 项 Python 测试、Ruff、格式检查、mypy、JavaScript 语法检查通过。 -图库目的地标签与能力过滤 18 项浏览器检查通过;覆盖 320–1440 像素、中英文、明暗主题和长 NAS 名称。 -本次不增加任何网盘写入功能,不改变画框写入策略。 - -### 升级 - -Compose 设置 `FRAME_FLOW_STORAGE_NAME`;Actions 设置同名仓库 Variable。 -名称只描述实例,不作为路径或授权凭据。未设置时回退为 NAS。 -默认访问端口仍为 6005,容器内部端口仍为 18787。 -NAS 源码包与 SHA256 附件不含运行配置、密钥、数据库或私人照片,需自行构建镜像。 - -## English - -Gallery tabs identify the concrete destination: KoKonna cloud gallery and the configured NAS name plus Local gallery. -Destination metadata includes connection and upload capabilities; only implemented writable adapters are shown. -Existing read-only cloud photo sources are not presented as save destinations. Long labels wrap on mobile. -Set FRAME_FLOW_STORAGE_NAME in Compose or the Actions repository Variables. No cloud-drive write support or device write policy is changed. diff --git a/docs/releases/v0.1.7.md b/docs/releases/v0.1.7.md deleted file mode 100644 index 0c09bfd..0000000 --- a/docs/releases/v0.1.7.md +++ /dev/null @@ -1,24 +0,0 @@ -# PIGWay Frame Flow v0.1.7 - -## 简体中文 - -修复首次打开图库时内容区空白、必须等待云端图片列表返回才出现控件的问题。 - -- 目的地标签、搜索、排序、刷新和上传按钮立即初始化,图片列表独立请求。 -- 仅在工具栏提示正在读取列表;未知数量时不生成图片卡片,不提前显示“图库为空”。实际图片仍在自己的区域内独立加载。 -- 启动使用轻量设备身份目录,完整设备状态在后台更新,避免厂商状态请求阻塞首屏。 -- 慢请求期间可以切换到 NAS 图库;过期响应不会覆盖当前页面。 -- 列表失败时保留控件并在工具栏显示错误,仍可刷新或切换目的地。 -- 保留等待期间输入的搜索词和排序选择;本地任务筛选请求在同一次导航内复用。 - -### 验证 - -本地 508 项 Python 测试、Ruff、格式检查、mypy 和 JavaScript 语法检查通过。 -新增首次未缓存列表的控件就绪、输入保留、慢云端切换和列表失败回归。 -不增加图库列表的服务端缓存,不修改厂商请求重试、照片、生成内容或设备写入策略。 - -## English - -Fix the blank gallery on its first uncached visit. Destination tabs and gallery controls initialize before metadata requests complete. -Slow or failed cloud listing does not prevent switching to NAS storage. Search and sort choices survive list arrival, and stale responses cannot replace the active destination. -Only a small toolbar status indicates metadata loading; real images keep independent loading indicators. diff --git a/docs/releases/v0.1.8.md b/docs/releases/v0.1.8.md deleted file mode 100644 index e066944..0000000 --- a/docs/releases/v0.1.8.md +++ /dev/null @@ -1,13 +0,0 @@ -# PIGWay Frame Flow v0.1.8 - -增加 NAS 本地图库反选、放大总览图片,并统一图片查看器与界面表达。 - -- 反选只切换当前页可见图片的勾选状态;隐藏勾选项的批量操作范围明确提示。 -- 总览当前图片预览增大,点击或键盘打开与图库相同的查看器,读取原图并支持适应屏幕、原始尺寸和 Esc 关闭。 -- 修正图库排序、播放顺序、型号信息来源、云端确认状态等标签,补齐天气与连接状态翻译。 -- 区分本地与云端删除影响,解释星标保留规则,避免对未知来源作无依据判断。 -- 修正数据源空态、路径与凭据说明;同步 README 和操作文档中的共享 Photos 登录机制与入口。 - -验证:305 项布局检查、8 组星标与反选检查、12 组总览查看器检查、45 项图片加载检查及新增中英文文案检查通过。全套后端与静态检查由本次发布流水线再次验证。检查不涉及真实照片删除、设备写入或收费 AI 调用。 - -Improve NAS gallery selection, dashboard image viewing and UI wording. Invert selection affects visible items on the current page. Dashboard previews open the same full-image viewer as the gallery. Storage destinations, deletion scope, server-side stars, cloud confirmation and shared Photos credentials are clarified in both languages. diff --git a/docs/releases/v0.1.9.md b/docs/releases/v0.1.9.md deleted file mode 100644 index 0c3cb90..0000000 --- a/docs/releases/v0.1.9.md +++ /dev/null @@ -1,19 +0,0 @@ -# v0.1.9 - -照片来源通过 Synology Photos API 按账号权限读取,共享/个人空间、人物 any/all 筛选和有界 XL 预览缓存可用。生产拒绝文件系统照片来源及 /photos 挂载;本地上传、生成图片和 Server 本地图库继续保留。NAS 原图下载接口曾被拒绝,本版不宣称支持原图下载。 - -自动化新增 1~10080 分钟的真实间隔,跨整点与跨天不按 Cron 字段重置,既有 Cron 任务保持原样。显示时长明确为到期恢复期限。统一来源快捷创建任务编辑器,改善登录及来源表单响应式布局、设备显示名与历史记录中英文;诊断详情保留原始标识。 - -## 生产部署 - -生产已迁至 Ubuntu Server,由 systemd 管理 Docker;业务、Docker 数据和恢复资料位于 T7,并有 UUID 与挂载依赖保护。NAS 旧 Frame 专属资源已清理且独立复核 PASS。CI 保留隔离验证,移除 NAS 自动生产部署任务,不再向 NAS 发布。 - -正式发布使用 scripts/server-release.py:仅在既有 Ubuntu Server 环境运行,从已提交源码包构建,校验依赖锁、源码哈希、T7 UUID、容器安全约束和真实写入设置;备份 SQLite、配置及 Compose 后切换镜像,失败恢复旧 Compose,不自动回写旧数据库。它不执行上传、显示、删除或恢复图片等设备操作。成功后记录正式提交号、保存源码包及审计回执,删除本次暂存目录;白名单内的 Frame 旧迁移输入归档到本次 recovery,清除无恢复引用的临时镜像别名,共享 Console 资料不动。旧镜像及历史恢复资料保留供回滚,不执行全局 prune。 - -脚本要求由 git archive 生成的源码放在 /migration-inbox 的独立子目录;目录内同时提供 RELEASE_COMMIT、RELEASE_HASHES.json 和原始 source.tar.gz。哈希清单涵盖源码与源码包,不含自身。执行 sudo python3 <暂存目录>/scripts/server-release.py;成功后读取 /apps/pigway-frame-flow/release-verification.json 并独立检查线上接口。 - -## 验收范围 - -完整后端测试、静态检查与桌面/平板/手机的中英文浏览器回归纳入发布检查。线上历史补丁已核验,真实写入保持开启;本轮正式发布不重复真实设备写入测试。隔离浏览器验证与真实设备写入证据由维护者私下保管。 - -局域网 HTTPS、独立加密备份及恢复演练仍是后续工作;T7 recovery 不属于独立备份。没有执行 USB 断连、服务器重启或压力测试。