它解决什么
通讯录只有姓名和号码;日记按时间流走,搜不到人;笔记软件是自己画的任意结构,不成体系。
Ties 把「关系事实」当作数据基元:见过几次、谁约的、上次见面是什么时候——全部从已有行为推导,不新增任何记录负担。
核心判断是:记录的价值不在记录的当下,而在半年后、两年后被问到的那一刻。
四条设计原则
- 不打分——查看界面不出现任何亲密度数字,用事实与文字描述关系;主观分值已整体下线,这也是「可截图」的前提;
- 零打卡——所有统计由已有数据推导,不要求用户额外操作;
- 只庆祝、不惩罚——没有进度条、没有连续签到、没有负面提醒;
- 可截图——界面经得起给对方看,敏感信息只出现在详情页。
工程过程
- 文档治理:PRODUCT / PRD / DESIGN / ROADMAP / DECISIONS / AGENTS 各管一段,一个问题只有一份文档回答;历史稿统一归档,避免多份文档互相矛盾。
- 数据库只走 migration:增量脚本按 user_version 顺序执行,只升不降、禁止手改数据库;新库全量结构与增量脚本分离。
- 可验证优先:冒烟测试与端到端验证脚本随功能一起写,脚本内的隔离数据库与上传目录必须落在系统临时目录。
- 踩坑固化:把踩过的坑写成协作规范,例如「上传路由必须把校验异常转成 400,否则掉进默认 handler 变 500」「改 import 后必须实际调用一次函数,ESM 缺绑定静态检查抓不到」。
技术栈
| 层 | 选型 |
|---|---|
| 前端 | Vue 3 · Vite · Element Plus · Pinia · Vue Router · ECharts |
| 后端 | Node.js + Express,分层 routes / controllers / services / middleware |
| 数据库 | SQLite(Node 内置 node:sqlite),结构变更只走 migration |
| 鉴权 | JWT + bcrypt |
| 文件 | multer,magic number + 大小 + 扩展名三重校验 |
一个刻意的约束:后端零第三方运行时依赖——SQLite、图片解析、AI 通道全部用标准库或自实现;前端解码组件随项目走,不走 CDN。
目前的状态
Web 版已可日常使用,主要能力:
- 人物档案:核心字段 + 性格喜好 + 标签 + 地址,照片非强制;
- 批量导入:以手机通讯录导出的 vCard 为主路径,按 UID 去重、不覆盖已有档案;
- 速记收件箱:全局快捷键唤起,指了人直接落成见面记录,没指人进待归类;
- 搜索:姓名 · 绰号 · 标签 · 备注等,支持拼音首字母;
- 见面记录与洞察:按最近见面分桶,含标签分布、见面新鲜度、新增趋势看板;
- 称号与成就:称号按规则实时计算不落库;10 枚 SVG 勋章 + 成就墙;
- 相册:照片 / 视频,HEIC 原生支持,按内容哈希识别重复;
- AI 录入:可选接入 OpenAI 兼容通道,一段话生成档案草稿。
数据全部留在本机:一个 SQLite 文件 + 一个上传目录,没有云端。
仓库说明:本项目仓库目前设为私有(GitHub),暂未公开。