jif2.zhang
|
fd4079c9c3
|
feat(任务): 即时同步 —— 订阅本地库变更, 跨端改动无需切页自动刷新
Docker Build and Push / build-image (push) Failing after 1m48s
现象: 多端同时打开同一项目时, 一端改完, 另一端必须切到别的页面再切回来才更新。
根因: 不是同步没到, 而是 UI 从未订阅本地库变化 ——
PowerSync 的下行推送 (PG 逻辑复制 → sync service → 客户端本地 SQLite) 本身正常,
但任务模块的读全是命令式 db().getAll() (api/task.js), 读完不再看;
lib/powersync/react.jsx 虽然导出了 useQuery/useStatus, 全项目一次都没用过;
TaskPage/ProjectView 只在 useEffect 里 load() 一次, 连 useRefreshOnVisible 都没接
(只有打卡与宏观页面在用)。「切面板能刷新」纯粹是因为组件重新挂载又 load 了一次。
实现 (docs/V0.2/离线编辑模块/即时同步方案.md, 方案 C):
- 新增 lib/powersync/useDbSignal.js: 用 db.watch() 的表级过滤 (tables) + 节流
(throttleMs) + AbortSignal, 订阅本地库变更; 跳过订阅时的首次通知, 避免与
挂载时的 load() 重复。
(初版设计是手写 count/sum/max(updatedAt) 的「信号 SQL」, 实施时发现 SDK 原生
支持 tables 过滤, 更可靠, 已改为表过滤并在文档中记录变更。)
- api/task.js 新增 TASK_TABLES / PROJECT_TABLES 常量 (表名须与客户端 schema 一致)。
- ProjectView: 订阅任务域 (Task/BoardColumn/TaskMember/TaskTag) → 重算;
TaskPage: 订阅项目域 (Project/ProjectMember) → 重算。
- 不打断操作: BoardView/ListView 上报 onDragActiveChange, 拖拽期间收到变更只记
pending, 松手后补一次刷新, 避免卡片在手指下跳位。
- 回前台兜底: 两页都接 useRefreshOnVisible (WebView 后台可能节流订阅回调)。
验证 (真实 Windows 外壳 + CDP, 服务端直接改库模拟另一端):
- 服务端改任务标题后, 页面在**无任何操作**的情况下自动更新 (三次复测均成功);
- 改回原标题后同样自动还原; 测试数据已恢复。
已知瓶颈 (不在 UI 层, 另见文档 §7.0):
- 实测端到端延迟约 13~14s, 未达 ≤1s 目标;
- CDP Network 观察客户端: 无 WebSocket, 仅 /sync/stream 长连接;
- NPM (baishe nginx-app-1, proxy_host/5.conf) 未关闭 proxy_buffering,
流式响应被 nginx 缓冲后按批下发, 与观测到的固定批次延迟吻合;
- 修复属运维配置 (proxy_buffering off 等), 需单独评估后执行。
|
2026-10-27 20:57:05 +08:00 |
|
jif2.zhang
|
32f404ac90
|
fix(任务): 修复列表与看板拖拽「能触发但放不下」—— uuid 主键被 Number() 成 NaN
Docker Build and Push / build-image (push) Successful in 1m34s
0.2.1 切本地库后 Task.id / BoardColumn.id 为 uuid 字符串, 拖拽落点却用
Number(dataset.xxxId) 取值得到 NaN:
- 看板 hitColumn 返回 NaN -> NaN 为 falsy, onDrop 永不触发; 目标列也不高亮
- 列表 colId/taskId 为 NaN -> 组内命中与换列 findIndex 恒失败, 松手无操作
(打卡侧仍走 REST 数字 id, 故未受影响)
- 新增 src/pages/task/ids.js: idStr / sameId / datasetId, 统一按字符串比对
- useColumnDrag / useRowDrag: 落点、组内命中、换列、提交判定改用 sameId
- ProjectView: moveToColumn / reorderTask / changeStatus 改用 sameId,
落点为空直接忽略, 不把坏 id 写进本地库
- api/task.js: update 拦截 "NaN"/"undefined" 列 id, 报「看板列无效」
验证: headless Edge + CDP 派发真实指针事件驱动两个 hook (uuid 数据),
修复前 4 条落点断言全挂, 修复后全部通过。
|
2026-10-27 10:06:37 +08:00 |
|
jif2.zhang
|
06e9a3e694
|
fix(任务): 编号改为 #序号展示、详情页完整编号可复制、修复详情改列报「看板列不存在」
- 列表/看板任务编号徽标改为 `#序号`(如 #18), 移除不再需要的 codePrefix 透传
- 详情页标题下新增完整任务编号胶囊 (项目编号-序号, 如 ADMIN-18), 点按复制:
Clipboard API 优先, 非安全上下文/旧 WebView 回退 execCommand, 并提示已复制
- 修复详情页「看板列」切换报错: 0.2.1 本地库列 id 为 uuid 字符串,
ActionSheet 的 key 恒为字符串, 旧代码 Number(key) 得到 NaN ->
update 校验失败抛「看板列不存在」。改为字符串比对 (currentCol/勾选标记同步)
- 详情页保存后先就地替换该行再回源刷新
|
2026-10-27 10:06:12 +08:00 |
|
jif2.zhang
|
e689e44923
|
Merge branch 'dev-0.2.1' into dev-0.2
# Conflicts:
# generated/prisma/internal/class.ts
# generated/prisma/internal/prismaNamespace.ts
# generated/prisma/internal/prismaNamespaceBrowser.ts
# generated/prisma/models/BoardColumn.ts
# generated/prisma/models/Project.ts
# generated/prisma/models/ProjectMember.ts
# generated/prisma/models/Task.ts
# generated/prisma/models/TaskMember.ts
# generated/prisma/models/TaskTag.ts
# generated/prisma/models/User.ts
# server/routes/projects.js
# server/routes/tasks.js
# src/api/task.js
|
2026-10-26 20:46:25 +08:00 |
|
jif2.zhang
|
a714013e3e
|
feat(0.2.1): M3 前端接入 —— PowerSyncProvider/登录连接/登出清库, 任务模块数据层切本地库 (projectApi/columnApi/taskApi 本地实现, 离线读写+自动上行), 任务编号徽标展示
|
2026-10-26 00:41:51 +08:00 |
|
jif2.zhang
|
f83deefa47
|
feat(V0.2): 视图切换移入项目栏 —— 紧凑段控 + 按钮收纳 (按设计稿)
Docker Build and Push / build-image (push) Successful in 1m5s
- 项目栏一行: 项目名(省略) + 列表/看板紧凑段控(vseg 26px) + 已归档/管理/+新增
- 「项目管理」文案收窄为「管理」, mini-btn 内边距收窄
- 移除原 .pv-head 大段控; 视图记忆逻辑不变 (T-VW-02/03)
|
2026-10-25 23:51:09 +08:00 |
|
jif2.zhang
|
368e99a380
|
feat(任务模块): 任务归档 T-ARC-01~08 实现
Docker Build and Push / build-image (push) Successful in 1m27s
- 数据: Project.autoArchive + Task.archived/archivedAt/archiveSource,
迁移 20261026000000_task_archive (两索引)
- 领域: server/task-domain/archive.js —— hiddenAtOf 与保留口径精确同源,
autoArchiveDue 到期判定, runAutoArchiveForProject (读时惰性) +
runAutoArchiveSweep (每小时 cron 兜底)
- 接口: POST /tasks/:id/archive|unarchive (连带子任务, 幂等);
GET /projects/:id/tasks/archived (keyword/kind/columnId/from/to 过滤,
archivedAt+id 游标分页); 项目 PUT 收 autoArchive (枚举校验);
主列表/子任务/项目 taskCount 全部排除归档
- 前端: ⋯ 菜单「归档」(确认含子任务条数); 项目栏「已归档」入口 →
ArchivedTasks 弹层 (关键词/类型/列/归档时段过滤 + 加载更多 + 恢复/删除);
项目管理「归档设置」四档 Picker
|
2026-10-25 23:09:52 +08:00 |
|
jif2.zhang
|
cee21a39d9
|
feat(V0.2): 快速添加输入框三行/失焦收起; ⋯菜单点选即收; 项目图标可设图片
Docker Build and Push / build-image (push) Successful in 1m22s
- 快速添加改 3 行 textarea, Enter 创建/Shift+Enter 换行/Esc 关闭,
焦点离开且无内容时自动收起
- 任务 ⋯ ActionSheet 点选动作后 handler.close() 收回菜单
- Project.icon (TEXT data URL, 迁移 20261025130000): 项目管理可选图片,
客户端裁为 96x96 cover JPEG (~15KB); 项目列表/最近项目/管理页图标位
显示图片, 保持原尺寸与圆角; 可恢复默认首字色块
|
2026-10-25 12:02:29 +08:00 |
|
jif2.zhang
|
74e1e7dd13
|
feat(V0.2): 标题30字+智能拆分 / 时间标记 MM-dd / 时间词前缀 (T-TK-14~16)
Docker Build and Push / build-image (push) Successful in 1m25s
- 标题上限收紧至 30 字 (服务端校验+详情编辑框); 快速添加输入框
放宽到 200 字: 超长时在 30 字内分隔符处截断为标题, 完整原文进描述
- Task.markDate (DateTime, 迁移 20261025120000): 详情页 DatePicker
选择/清除, 列表行与看板卡显示 MM-dd 小标签
- 快速添加时间词前缀: 今天/明天/后天/本周/下周/本月/下月 开头
(后跟分隔符) 自动设为时间标记并移出标题; 本周=本周日, 本月=月末
- 需求/功能/数据库设计文档同步更新 T-TK-14~16 与 Task 表字段
|
2026-10-25 11:47:44 +08:00 |
|
jif2.zhang
|
fb9e2350b3
|
feat(V0.2): 任务类型标签 —— 项目级自定义 + 任务标记 + 列表/看板展示
Docker Build and Push / build-image (push) Successful in 1m21s
- 数据: Project.taskKinds (JSON, 未配置回落默认 需求/Bug/FEATURE/优化),
Task.kind (≤20字); 迁移 20261025030000_task_kind
- 服务: 项目 PUT 支持整体替换 taskKinds (去重/上限30/至少1个);
任务 create/update 支持 kind (空串清空)
- 项目管理: 新增「任务类型」分区, chips 展示 + 弹层编辑 (删除/新增)
- 任务详情: 新增「类型」字段, 项目类型 chips 点选, 可清空
- 展示: 列表行左下与看板卡左下显示彩色小标签
(需求蓝/Bug红/FEATURE紫/优化橙, 自定义类型灰)
|
2026-10-25 02:53:25 +08:00 |
|
jif2.zhang
|
c0b55277a4
|
fix(V0.2): 列表组内排序乐观更新未重排数组, 松手后界面不动
Docker Build and Push / build-image (push) Successful in 1m0s
列表分组渲染按 tasks 数组顺序, reorderTask 此前只给任务打新
sortOrder 字段而保持原数组顺序 —— 松手后界面无任何变化, 看起来
就是组内无法排序 (数据其实已提交)。改为直接按新顺序重建数组,
不在分组内的任务 (孤儿) 追加在尾部。
|
2026-10-25 02:37:39 +08:00 |
|
jif2.zhang
|
5066007d9d
|
feat(V0.2): 克隆卡片跟手浮层 + 列表组内排序 + 把手统一移到最左
Docker Build and Push / build-image (push) Successful in 1m1s
- 浮层改为激活时克隆原卡片 (DOM clone, 淡化+投影) 挂 body 顶层,
移动直接改 transform —— 替代蓝色信息条, 所见即所拖
- 任务列表支持组内排序: 拖到本组某行上/下半显示插入指示, 松手提交
POST /projects/:id/tasks/reorder (顶层任务按展平顺序重写 sortOrder);
拖到其他分组仍为换列
- ⠿ 把手统一移到卡片最左: 打卡 / 列表任务行 / 看板卡片 (看板新增把手
即按即拖路径, 与列表同款 touchstart preventDefault 双保险)
- useColumnDrag onDrop 经 ref 桥接防陈旧闭包
|
2026-10-25 02:07:58 +08:00 |
|
jif2.zhang
|
d6ca7573f3
|
fix(V0.2): 三轮反馈 5 项 —— 回滚键盘方案 / 列表卡片拖动 / 看板防误触 / 横滑整屏 / 详情页恢复
Docker Build and Push / build-image (push) Successful in 4m9s
1. 回滚键盘遮挡统一方案 (真机测试不通过, 需求搁置): 恢复 TaskDetail/
UserPicker/CopyTaskPopup/ProjectManage 与 useKeyboardInset 到 9fea1a5^,
删除 useKeyboardInsetWatcher / .kb-safe / interactive-widget=resizes-content
2. 任务详情页样式随 1 一并恢复提交前状态 (含底部拷贝/删除按钮)
3. 列表视图换列改为卡片拖动: 新 useRowDrag (长按 400ms 行抬起, 左右
80px/列步进, 行尾徽标显示目标列, 松手落列), 移除长按 ActionSheet
—— 旧长按与复选框/行点击互相误触, 抬手合成 click 落在控件上触发状态切换
4. 看板拖动防误触: 任务区禁长按文字选择与系统菜单 (输入框除外);
pointercancel 只放弃不提交; 拖动结束 350ms 内抑制 click 误开详情;
状态点/⋯/子任务行 pointerdown 不冒泡, 不发起拖动
5. 看板横滑扩展到整屏: .page-transition 补 height:100% 打通
app-main → page-with-navbar 百分比链, board-wrap 撑满剩余高度
已验证: kb-safe/Watcher/onLongPress 残留引用清零, 逐文件 diff 审阅通过;
本机无 Node 运行时, 未跑 vite build
|
2026-10-24 23:24:31 +08:00 |
|
jif2.zhang
|
9fea1a5a3a
|
fix(V0.2): 二轮评审 6 项 —— BUILD_ID 格式 / 菜单与详情精简 / 拖动重做 / 键盘统一方案
Docker Build and Push / build-image (push) Successful in 4m5s
1. BUILD_ID 改为 yyyyMMddHHmmss (去掉中间点), 仍 UTC+8
2. 任务 ⋯ 菜单去掉顶部任务名标题
3. 任务详情去掉底部「拷贝到其他项目」「删除任务」按钮 (⋯ 菜单已有)
4+6. 键盘遮挡统一方案 (重点设计 §7.2):
- index.html 加 interactive-widget=resizes-content
- App 级 useKeyboardInsetWatcher 写 --kb-inset (visualViewport+window 双源)
- 底部弹层统一 .kb-safe 类 (安全区+20px+键盘插入量, dvh 收缩+内部滚动)
- TaskDetail/UserPicker/CopyTaskPopup/信息块弹层全部迁移, 删除 per-component hook
- 信息块 textarea 补 focus scrollIntoView 兜底
5. 拖动方案重做 (重点设计 §7.1):
- 新 useColumnDrag: Pointer Events + setPointerCapture, 长按400ms原位抬起,
elementFromPoint 高亮目标列, 边缘 rAF 自动横滚; 移除手指跟随浮层(任务名)
- 列表行长按 500ms → 「移动到列」ActionSheet (不做自由拖动)
- 移除「拖到卡片转子任务」误触路径, 统一走详情页层级区
- 删除旧 useLongPressDrag
已验证: 99 文件语法 0 错误、导入 0 缺失
|
2026-10-24 22:15:52 +08:00 |
|
jif2.zhang
|
506db0795b
|
feat(V0.2): 任务操作菜单 / 状态指示 / 移动与转子任务 / 移除扩展信息
Docker Build and Push / build-image (push) Successful in 4m13s
1. 任务 ⋯ 菜单 (列表行与看板卡片): 编辑 / 拷贝到其他项目 / 删除
(antd-mobile ActionSheet, 带任务名标题; 拷贝抽出为 CopyTaskPopup 复用)
2. 点击任务非按钮区域 = 打开编辑页 (原本即如此, ⋯ 不再误触为编辑)
3. 修复状态选择器堆成三行: 此前 .seg 只有 .pv-head 作用域样式,
详情弹层裸用导致纵向堆叠; 新增通用 .seg 分段样式, 当前项高亮点按即切
4. 移除任务的扩展信息 UI (T-TK-04~07 标注已取消, 决策 35):
ExtrasCard 组件删除, DB extras 字段保留不再使用;
项目相关长文本由项目信息块 (T-PJ-13) 承载
5. 任务移动入口: 详情页新增「看板列」ActionSheet 换列(联动裁决不变)
与「层级」区(转为子任务=选父任务 / 转为顶层), 覆盖无法拖拽的场景
6. 列表页移除「+ 子任务」入口: 添加子任务只在详情页, 或经转子任务
已验证: 99 文件语法 0 错误、导入 0 缺失、文档 149 条/决策 35 连续
|
2026-10-24 21:51:26 +08:00 |
|
jif2.zhang
|
0cdbfb434f
|
feat(V0.2): 任务模块界面调整 —— 首屏/项目管理/底部安全距离
Docker Build and Push / build-image (push) Successful in 4m8s
按 2026-10-24 评审的 5 条调整实现 (需求 T-VW-08~10 / T-PJ-11/12 / T-UI-11):
首屏 (T-VW-08/09):
- /task 改为「上=最近项目条(3 个+更多入口), 下=当前项目任务管理」
- 完整项目列表迁至 /task/list, 从「更多项目」进入; /task/:pid 保留供深链
最近项目排序 (T-VW-10):
- 卡片长按 300ms 拖动换位, 结果存设备端 prefs.recentOrder
- 顺序 = 手动排序 > 最近访问(recentIds) > 列表序, 归档项目不展示
项目管理 (T-PJ-11/12):
- 新增 ProjectManage: 成员 / 看板列 / 项目信息 三分区统一入口
- 项目信息含 改名 / 归档切换 / 删除(个人项目隐藏) / 退出(仅创建人)
- 项目页头部只留「项目管理 + 新增」, 移除散置的成员/列设置按钮
底部安全距离 (T-UI-11):
- 任务详情 / 人员选择 / 拷贝弹层 padding-bottom = 安全区 + 20px
- 小屏下弹层 maxHeight + 内部滚动, 底部按钮完整可见
已验证: 97 文件语法 0 错误、相对导入 0 缺失
|
2026-10-24 20:32:44 +08:00 |
|
jif2.zhang
|
6c9cd3fd99
|
feat(V0.2): 任务模块 —— 项目 / 列表与看板 / 列-状态绑定 / 一级子任务
Docker Build and Push / build-image (push) Failing after 3m51s
需求 142 条 (T-*), 设计见 docs/V0.2/任务模块/
数据层:
- 新增 6 张表: Project / ProjectMember / BoardColumn / Task / TaskMember / TaskTag
- 看板列是实体(可增删改排序), Task.columnId 外键 RESTRICT 防误删列丢任务
- Task.status(todo/doing/done) 与 columnId 双落库, 二者正交
领域层 server/task-domain/ (唯一口径, 前后端不重复实现):
- resolveStatus: 列决定状态(只看目标列, 无拖出回退); 状态与列不匹配时按列序取第一个绑定该状态的列自动归位, 无匹配列则不移动; 子任务完全豁免
- retention: 逐列 6 档保留窗口(永不显示/当天/3天/本周/本月/永久显示), 以 doneAt 判定
- copyTask: 跨项目深拷贝, 人员按目标项目成员过滤并回报丢弃名单
接口: /api/projects, /api/columns, /api/tasks (均校验项目成员)
前端:
- 底部 Tab 插入「任务」, 位于「打卡」之后; 默认首页仍为打卡
- 列表视图(子任务缩进+折叠) / 看板视图(长按拖拽换列、拖到卡片降为子任务)
- 列设置(列管理+状态绑定+保留选项) / 任务详情(扩展信息卡片默认收起) / 成员管理
- 视图记忆与上次项目存设备端
已验证: 95 文件语法 0 错误、相对导入 0 缺失、领域逻辑用例全部通过
|
2026-10-24 11:21:16 +08:00 |
|