内容

<div align="center">
<h1>我的生活记忆</h1>
<p>我的生活记忆是一个私人的空间记忆系统,用于记录地点、笔记、照片和路线。用户信任的AI客户端可以通过用户控制的只读MCP访问权限来研究该档案。</p>
<p><a href="https://kakizzzzz.github.io/My-life-memory/"><strong>在线演示</strong></a></p>
</div>
---
## 截图
以下六个视图展示了应用程序的核心流程:使用星星标记地点、保存文本和照片的记忆、记录行程,以及回顾出现的模式和瞬间。
<table>
<tr>
<td width="33%" align="center" valign="top">
<img src="docs/screenshots/star-color-customization.webp" alt="主地图上的星星颜色自定义" width="160"><br><br>
<strong>星星颜色</strong><br>
<sub>在地图上标记记忆地点,并给每个星星赋予独特的视觉身份。</sub>
</td>
<td width="33%" align="center" valign="top">
<img src="docs/screenshots/memory-note-editor.webp" alt="带有照片和富文本的记忆笔记编辑器" width="160"><br><br>
<strong>记忆笔记</strong><br>
<sub>将地点与富文本、照片、颜色、大小和下划线相结合。</sub>
</td>
<td width="33%" align="center" valign="top">
<img src="docs/screenshots/route-tracking.webp" alt="保存的路线,显示距离和时长" width="160"><br><br>
<strong>路线跟踪</strong><br>
<sub>记录实际移动,回顾距离、时长和路线形状。</sub>
</td>
</tr>
<tr>
<td width="33%" align="center" valign="top">
<img src="docs/screenshots/trip-statistics.webp" alt="旅行统计和地点排名" width="160"><br><br>
<strong>旅行统计</strong><br>
<sub>将星星和路线转化为地点数量、排名和旅行模式。</sub>
</td>
<td width="33%" align="center" valign="top">
<img src="docs/screenshots/records-timeline.webp" alt="保存的记忆记录时间线" width="160"><br><br>
<strong>我的记录</strong><br>
<sub>以日期时间线查看保存的笔记,支持月视图和年视图。</sub>
</td>
<td width="33%" align="center" valign="top">
<img src="docs/screenshots/memory-reader.webp" alt="保存的记忆阅读器,显示写作、摄影和原始日期" width="160"><br><br>
<strong>记忆阅读器</strong><br>
<sub>通过写作、摄影和原始日期回顾保存的地点。</sub>
</td>
</tr>
</table>
## 功能
- **地图标记地点。** 从真实的GPS坐标开始,选择地图样式,创建、移动、重新着色、排序或在外部地图应用程序中打开星星。
- **将照片转化为地点。** 导入一张地理标记的照片,在其原始坐标处创建一个星星,并自动链接照片笔记。
- **保存地点笔记本。** 每个星星都包含多个日期笔记,支持样式文本、私人照片、相机拍摄和专注的阅读和编辑视图。
- **记录实际移动。** 一个自适应的GPS记录器处理常见的旅行速度、暂停和恢复、弱信号间隙、草稿、距离、时长和路线形状。
- **回顾档案。** 通过时间线、日历、日期筛选器、文本或坐标搜索、地点排名、路线统计和点状世界地图查找记忆。
- **控制数据。** 私人账户独立同步,支持图片库、日期范围导出、主题、权限、密码更改和永久账户删除。
## 通过MCP的AI记忆研究
我的生活记忆通过用户生成的只读MCP令牌将私人档案扩展到兼容的AI客户端。该服务仅研究经过身份验证的用户的地点、日期、笔记和路线;在单独的所有权检查后,具有视觉能力的客户端可以请求与支持的笔记链接的限定一组选定照片。它不能创建、编辑或删除记忆。
研究结合空间、时间、笔记和路线证据,包括支持的用户相对地点,如家、工作或学习。不支持的问题不会返回无关记录,而模糊问题则要求用户确认隐私筛选的线索或中立的备用方案。后台不运行任何模型、嵌入服务或矢量数据库。请参阅 [记忆API和MCP参考](#记忆API和MCP参考) 以获取接口和连接步骤。
## OpenAI构建周
我的生活记忆在OpenAI构建周之前就已经存在,其核心地图、地点星星、记忆笔记、路线记录、基础接口、规范的用户范围存储、同步基础、账户生命周期和核心隐私控制已经到位。
在官方提交期间,我继续领导产品方向、功能决策、测试和验收。我独立完成了所有视觉设计、UI/UX和交互设计。在我的指导下,项目扩展了服务器拥有的媒体保留、日期范围导出、本地时区处理、富文本和媒体可靠性改进,以及具有严格模糊性和隐私边界的基于证据的只读MCP研究层。
Codex处理了实现、重构、调试、测试、文档和部署验证。GPT-5.6支持产品和架构审查、隐私和交互分析、测试计划和竞赛演示准备。GPT-5.6并未内置到Web应用程序中;兼容的AI客户端可以通过项目的用户控制的只读MCP连接。
## 技术栈
- React 19 + TypeScript
- Vite 6
- Tailwind CSS 4
- Leaflet + React Leaflet + MapLibre GL JS
- Motion用于小型UI过渡
- Supabase Auth、Postgres、行级安全和私人存储
- Supabase Edge Functions用于邀请注册、记忆API、MCP令牌管理、云MCP、账户删除和计划媒体保留
- 用于AI客户端的本地模型上下文协议(MCP)服务器
- GitHub Pages用于静态托管
## 地图数据和图块服务
- 浅色和深色样式使用OpenFreeMap矢量地图,通过Leaflet兼容层使用MapLibre GL JS渲染。
- OpenFreeMap样式使用OpenMapTiles模式和OpenStreetMap数据。所需的源和许可链接保持可见。
- 航空样式使用公共VersaTiles卫星样式,它将公开可用的卫星图像与更高分辨率的公共正射照片相结合,在有覆盖的区域。
- VersaTiles不需要账户或API密钥。其官方图像源链接和OpenStreetMap归属保持可见。
- 开放图像分辨率因地区而异。没有公共正射照片覆盖的区域无法匹配专有的Google、Apple或商业图像,应用程序不使用未许可的原始图块URL来模仿它们。
- 必要的源和许可链接在地图角保持可见。
- Apache License 2.0适用于此仓库的源代码,不适用于第三方地图数据、图像、托管服务、字体或依赖项。
- 在更改提供商、删除归属或部署大量流量之前,请参阅 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) 和 [NOTICE](NOTICE)。
## 数据和存储
- Supabase Auth拥有密码和会话;规范的Postgres表存储星星、笔记、路线、设置、隐私同意和有界的七天历史,位于用户范围的RLS下。
- 每个云编辑都是一个实体突变,由`dataset_revision`保护。一个IndexedDB出站队列保留了排队和正在进行的作业,跨崩溃、重试和临时网络损失,不存储完整的存档在localStorage中。
- `life-media`是一个私人存储桶。行保存路径和元数据,而不是公共URL,签名显示URL保持临时。
- 富文本HTML在存储和加载后进行清理。页面和存储的图像元素使用无引用策略;旧HTTP(S)图像保持可读以兼容,应迁移到私人存储,而不是静默删除。
- 删除笔记、星星或路线在七天内可逆。Supabase Cron和身份验证的`media-retention`函数在物理删除过期行、历史和私人文件之前重新检查引用。
## 记忆API和MCP参考
我的生活记忆提供了一个专注的、只读的MCP工具服务器,通过本地stdio和云Streamable HTTP。它设计用于个人记忆研究,而不是作为通用MCP平台;云传输使用用户生成的承载令牌,不声明MCP OAuth发现或每个可选的MCP功能。
我的生活记忆通过Supabase Edge Function `memory-api`公开用户范围的记忆API。API读取`memory_stars`、`memory_notes`和`memory_tracks`,具有明确的用户范围和分页;动作特定的加载避免无关表,并将日期范围推入数据库查询。范围摘要使用服务专有的`summarize_normalized_memory_range`聚合。API不读取或重写`app_states`。服务角色凭证永远不会到达前端或MCP客户端。
公共MCP接口公开了九个只读工具:
- `research_memory_context`
- `get_memory_images`
- `search_memories`
- `list_locations`
- `get_location_memory`
- `get_day_memory`
- `get_routes`
- `summarize_memory_range`
- `export_memory_report`
八个面向文本的工具调用同名的记忆API读取操作。公共MCP工具`get_memory_images`使用内部身份验证的`get_note_media`操作来验证图像引用,然后返回标准的MCP图像内容。`get_note_media`不是公共MCP工具。
`research_memory_context`是自然语言问题的首选操作。它构建结构化查询计划,应用明确的公共地点和日期约束,仅从第一人称证据中解析用户相对锚点,然后匹配请求的事件、目标或附近的路线。模糊锚点不按时间顺序选择,最新保存的记忆永远不会作为用户的当前位置呈现。置信度带是启发式检索标签,而不是校准概率。
每个研究响应都使用一种严格的状态:`supported`、`ambiguous`、`not-found`或`candidate-review`。只有`supported`才能包含证据段落、记录、坐标、路线或图像笔记ID。其他状态在物理上省略这些答案路径,并提供确切的指令,要求客户端中继或遵循而不添加猜测。模糊候选项仅在身份验证的服务内排名。当澄清有用时,公共响应可能会标识具有隐私筛选的短标题、明确名称、通用软提示或序数回退以及短期不透明令牌的选项;它从不暴露笔记正文、日期、坐标、分数、路线、图像或内部ID。
## 本地开发
先决条件:建议使用Node.js 20或更新版本。
```sh
npm install
cp .env.example .env.local
npm run dev
```
打开 [http://localhost:3000/](http://localhost:3000/)。
`.env.local` 需要:
```bash
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-publishable-or-anon-key
```
## 后端设置
完整的生产运行手册在 [`docs/backend-setup.md`](docs/backend-setup.md) 中维护。它涵盖了规范的v2迁移和校验和门、Edge Function部署、Vault和Supabase Cron配置、媒体保留、RLS验证、备份、回滚和同账户恢复。
不要将规范的前端部署到v1数据库,跳过迁移,或使用 `supabase db push` 作为文档发布顺序的替代。对于现有的生产项目,请在运行任何SQL之前检查迁移账本和验证查询。
## 部署
对于 GitHub Pages:
1. 将生产环境 Supabase 环境变量添加到构建环境中。
- `VITE_SUPABASE_URL`
- `VITE_SUPABASE_ANON_KEY`
2. 运行:
```sh
npm run build
```
3. 将 `dist/` 发布到 Pages 分支或使用 `.github/workflows/deploy-pages.yml`。后端发布使用官方 Supabase GitHub 集成,仅连接到此仓库。仓库根目录是 Supabase 工作目录,`main` 是生产分支,因此提交的迁移和 Edge Functions 在不存储 GitHub Actions 中的账户范围 Supabase 访问令牌的情况下部署。保护 `main`,在合并前审查后端更改,并将 GitHub App 安装限制在此仓库中。
4. 部署后,打开 Pages URL 并测试:
- 注册和登录
- 在同一设备上切换账户,并确认每个账户仅看到其自己的数据
- 上传头像
- 添加笔记图片
- 从具有 GPS 元数据的照片中创建星标
- 搜索笔记文本,并在搜索结果页面打开结果
- 从配置文件中更改密码
- 导出可读的 HTML 报告
- 使用登录用户的 bearer 令牌调用 `memory-api`
- 在设置中生成 MCP 令牌,并从移动/HTTP MCP 客户端列出云 MCP 只读工具
- 启动本地 MCP 服务器并列出只读工具
- 在另一个设备/浏览器上重新加载
- 删除图片并确认它消失
- 切换所有地图样式并确认属性链接仍然可见并打开正确的提供商/许可页面
### 生产备份策略
数据库备份和存储备份是分开的。Supabase 数据库备份不包含私有的 `life-media` 对象,因此生产恢复计划必须涵盖这两个来源。
- 在开放注册之前,请选择具有托管数据库备份的 Supabase 计划或加密的现场 `supabase db dump` 调度。
- 使用仅在受信任的操作员环境中运行的服务角色进程独立导出 `life-media`。保留对象路径,以便规范的图像元数据仍然可恢复。
- 永远不要提交转储、存储导出、数据库 URL、服务角色密钥或备份通行短语。不要将未加密的用户数据备份上传为此公共仓库的工件。
- 在将备份描述为可用的之前,请测试恢复到单独的 Supabase 项目。记录最后成功的数据库备份、存储备份和恢复演练,不在仓库中。
## 安全说明
- 不要提交 `.env.local`、服务角色密钥、数据库密码或原始 SQL 连接字符串。
- 前端必须仅使用 Supabase 可发布/匿名密钥。
- `service_role` 仅属于受信任的 Edge Function/服务器环境,绝不能包含在前端中。
- 注册由 Supabase Edge Function `register-with-invite` 控制;现有账户正常登录,不需要邀请码。
- 注册需要两个匹配的密码,每个密码至少八个字符,并明确接受当前的隐私声明。唯一的账户声明序列化并发请求,然后再进行 Auth 创建。现有的不完整的 Auth 用户必须证明原始密码,绝不会被管理员密码重置接管。
- 注册回滚只能删除由该确切请求_nonce 创建的 Auth 用户,而该用户仍被标记为待处理。它会先重新检查配置文件、设置和隐私同意,因此无法删除已完成的并发注册。
- 账户删除仅由经过身份验证的 `delete-account` Edge Function 执行,执行前需验证当前密码。该函数将存储清理范围限定为经过身份验证的用户 UUID, Auth 删除后再次扫描,并依赖实时配置文件存储策略以关闭最后上传的竞速。
- 面向浏览器的 Edge Functions 拒绝 `ALLOWED_ORIGINS` 之外的来源。云 `mcp` 端点允许不带 Origin 头的请求和原生客户端 `Origin: null`,但任何具体的浏览器源必须被列入白名单;每个请求仍然由每个用户 bearer 令牌控制。速率限制键通过 SHA-256 哈希并在 Postgres 中原子计数,直到迁移可用之前使用内存备用方案。
- `memory-api` Edge Function 必须在读取规范化行之前验证真实用户 bearer 令牌或具有解析的 `user_id` 的私有内部 MCP 调用。 可选写入是用户范围的实体突变,绝不会重写旧存档。
- 云 MCP 令牌是每个用户独有的。应用程序显示完整的令牌一次,每个用户在 `public.mcp_tokens` 中仅存储一个活动哈希,可以从设置中删除活动令牌。
- 本地 MCP 服务器登录为一个普通用户或使用一个用户访问令牌;它不使用服务角色凭证。
- MCP 是只读的,并在成功令牌身份验证后更新 `mcp_tokens.last_used_at`。直接内存 API 写/删除操作默认情况下在生产环境中禁用,需要正常的用户身份验证、`ENABLE_MEMORY_API_WRITES=true` 和显式的确认字段。
- 富文本 HTML 在客户端和内存 API 写路径中进行清理。存储的笔记仅允许 `p`、`br`、`span`、`u`、`figure` 和 `img`,以及一个小的安全样式/元数据允许列表。
- 笔记编辑器默认粘贴纯文本。粘贴的图片通过上传路径,外部 HTML 不直接插入到 contentEditable 编辑器中。
- 文档级引用者策略和两个 HTML 清理器强制笔记图片使用 `no-referrer`。遗留的 HTTP(S) 图片 URL 为兼容性而保留,因此操作员应将它们迁移到私有存储;静默阻止它们将删除用户可见的内容,需要单独的迁移 UX。
- 统计 iframe 预览在沙盒中运行,不允许同源。未来的生产工作应本地化外部 D3/topojson/world-atlas 资产。
- 邀请码必须仅作为 `INVITE_CODE` 存储在 Supabase 函数秘密中。
- 部署后,禁用公共 Supabase 电子邮件注册,以便注册不能绕过 Edge 函数。
- RLS 确保用户只能读取自己的配置文件、规范化行和历史记录。身份验证写入使用用户范围的突变 RPC;普通客户端根本无法访问 v1 `app_states` 存档。存储策略继续将媒体对象限定为身份验证用户的 UUID 文件夹。
- 私有图片使用短寿命签名 URL 渲染;签名 URL 不存储在规范化元数据中。
- 突变清理在云保存前剥离类似密码的字段。生产构建不允许在未配置 Supabase 的情况下进行本地帐户/密码回退。
- Supabase Auth 密码无法被应用程序查看。应用程序支持更改密码,但不支持显示保存的密码。
- 合成帐户电子邮件无法接收 Supabase 重置邮件。安全自助恢复码流程尚未实施;请勿添加安全问题或管理员密码重置快捷方式作为替代。
- 显式媒体删除由身份验证用户 UUID 文件夹限定范围,例如 `authUserId/notes/noteId/imageId.jpg`。以前引用的媒体进入七天的数据库队列。仅所有者 Supabase Cron 作业释放过期规范化行,并调用单独身份验证的 `media-retention` Edge Function,该函数在删除存储对象之前重新检查引用。函数 URL 和 bearer 机密从加密的 Supabase Vault 条目中读取;客户端维护和手动 GitHub 工作流仍然是回退,而不是唯一的清理执行器。
- 旧数据 URL 图片仅作为兼容性回退保留,并在登录或网络恢复后自动迁移到私有存储。
- 如果使用 GitHub Pages 作为实时演示,请在构建前在 GitHub Actions 机密中配置 Supabase 环境变量。
## 有用的脚本
```sh
npm run dev
npm run mcp:memory
npm run typecheck
npm run lint
npm run lint:edge
npm test
npm run test:e2e
npm run build
```
## 许可证
My Life Memory 源代码根据 Apache License 2.0 许可。参见 [LICENSE](LICENSE)。
第三方地图数据、图像、托管服务、字体和依赖项不通过 Apache 2.0 重新许可。参见 [NOTICE](NOTICE) 和 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
连接信息
猜你喜欢
暂无推荐服务器