AI0506 Calendar
Technical overview打开应用
AI0506 CALENDAR · TECHNICAL OVERVIEW

这不是产品宣传页,
这是项目的结构说明。

AI0506 Calendar 是一个面向个人学习、科研、考试、项目与生活安排的私人日历系统。本文解释它的边界、数据如何流动、不同客户端如何接入,以及哪些规则必须在修改代码时保持不变。

系统类型单用户私人系统
部署形态Cloudflare Pages + D1
数据入口Web · REST · MCP
当前阶段Phase 1 · 可用
01

系统边界

它解决什么问题

用一份云端结构化数据管理事件和截止事项,并让网页、未来的 Android 客户端和 AI Agent 共享同一套 API。重点是可靠、简单、可维护,而不是构建一个面向大众的 SaaS。

  • 事件:创建、查询、修改、软删除
  • 重复系列:生成实例、跳过、修改、拆分
  • Deadline:优先级、完成/重开、提醒
  • 分类、标签、导入、导出、ICS 只读订阅
IN

个人日程、学习/科研安排、截止日期、AI 辅助管理

OUT

多用户、社交、公开分享、复杂权限、聊天、AI 自动规划

LATER

Android App、课程表、Days Matter、天气卡片

02

总体架构

前端、API、MCP 和数据库位于同一个 Cloudflare Pages 项目中。客户端不直接访问 D1,所有业务写入都经过认证和领域逻辑校验。

Webpublic/index.html
Session Cookie
Android / App后续客户端
Bearer Token
AI AgentREST API
Remote MCP / OAuth
Cloudflare Pages + Functions路由 · Middleware · Auth · Domain logic · Response envelope
Cloudflare D1 · calendar-dbSQLite · events · series · deadlines · reminders · notifications · OAuth state
关键原则客户端共享 API;API 共享数据库;REST 与 MCP 共享校验和领域逻辑;认证入口集中在 functions/_middleware.js
03

一次请求如何流动

01
客户端发起请求

浏览器携带 session cookie;App / Agent 携带 Authorization: Bearer ...;MCP 客户端使用 OAuth access token。

02
Pages Function 接收

请求进入 functions/api/*functions/mcp/index.js;REST 的 /api/* 由全局 middleware 保护。

03
认证与输入校验

校验凭据、JSON 字段、时间格式、分类存在性、提醒枚举和幂等键;失败返回统一错误信封。

04
领域逻辑 + D1

事件、系列、Deadline 和提醒逻辑在 functions/_lib/ 中复用;多步系列变更用 D1 batch() 保持原子性。

05
返回稳定 DTO

成功返回 { ok: true, data };失败返回 { ok: false, error: { code, message } }

04

认证与权限

这是私人单用户系统,但浏览器会话和 Agent/API 访问是两条概念上分离的路径。

BROWSER

Session Cookie

POST /api/auth/login 校验私人密码,签发带 HMAC 签名的长期 Cookie。Cookie 为 httpOnlySecureSameSite=Lax;密码不会进入前端。

APP / AGENT

Bearer Token

App 和 AI Agent 使用 Authorization: Bearer <API_TOKEN>。Phase 1 只有一个 token,不做 token 管理表。

MCP

OAuth 2.1 + PKCE

/mcp 使用 OAuth 授权;动态注册、授权码、token 和 scope 由 Pages Functions 处理。

密钥边界PASSWORDAPI_TOKENSESSION_SECRETICS_SUBSCRIPTION_TOKEN 只存在于环境变量,不写入静态页、Git 或日志。
05

数据模型

时间字段使用带时区偏移的 ISO 8601 字符串,按客户端提交的偏移原样存储,不在 API 层强制转 UTC。

实体职责关键关系
events普通事件与重复事件实例series_id 关联系列;deleted_at 软删除
event_series重复规则本身生成实际 events;daily / weekly / monthly / yearly
deadlines独立的单次截止事项priority、completed_at;不属于重复 Event
categories / tags分类颜色与辅助标签写入前校验分类;最多 5 个 tag_ids
reminders / notifications计划提醒与站内通知以 reminder_id 去重;历史状态保留
exceptions / operations系列跳过与幂等记录支持 except、PATCH、split 重试
IDENTITY RULES
(source, external_id)  →  import idempotency
series_id              →  recurring membership
original_start_time    →  occurrence identity
idempotency_key        →  safe retry for series operations
06

重复事件逻辑

规则和实例分开存

event_series 保存规则;每一次实际发生仍是一个 events 行。创建系列时服务端生成最多 366 个实例,并通过 D1 batch 原子写入。

系列 PATCH 会合并已存规则、重新生成实例;首版不承诺保留此前对单个 occurrence 的直接修改。

except只跳过一次,不自动创建替代事件
split按日期拆成旧系列和新系列
delete系列和实例均使用软删除
retryIdempotency-Key 防止网络重试重复写入
POST/api/event-seriesPATCH/api/event-series/:idPOST/api/event-series/:id/exceptionsPOST/api/event-series/:id/split
07

提醒与通知

配置

Event 默认提前 60 和 10 分钟;可自定义最多两个,或显式关闭。

计划

服务端写入 reminders;Deadline 根据 priority 生成计划,改期/完成/删除会取消或重建 pending 行。

派发

网页打开时轮询触发到期提醒,notifications 以 reminder_id 去重。

展示

通知中心显示 scheduled_at;系统提示是独立的可选渠道。

当前边界页面关闭后不承诺持续推送;历史未读在首次登录时只作为角标基线,不会集中重播。
08

外部接入面

RESTWeb / App / Agent

/api/events/api/deadlines/api/event-series/api/export 等;JSON 响应信封稳定。

MCPAI Agent

/mcp 暴露带 calendar_ 前缀的工具,复用 REST 的校验、优先级、软删除和重复规则。

ICSApple Calendar

只读 HTTPS 订阅不走 Cookie/Bearer,而使用高熵 URL token;只包含 Event,不包含 Deadline。

IMPORT批量同步

POST /api/events/import(source, external_id) 幂等;重复提交更新而不是重复创建。

Base URLhttps://calendar.ai0506.com/apiLocalhttp://localhost:8788/api
09

运行、部署与代码索引

LOCAL

本地开发

npm ci
npm run db:local
npm run dev
CHECK

回归验证

npm run test:deadlines
npm run test:reminders
npm run test:series-patch
npm run test:ics
DEPLOY

生产边界

静态资源由 Pages 提供,Functions 提供 API;D1 绑定为 calendar-db。本地测试不等于生产验收,部署后必须检查 live domain。

public/Web shell、calendar UI、公开静态说明页
functions/api/REST routes
functions/_lib/auth、events、series、deadlines、reminders、ICS 等共享逻辑
functions/mcp/Remote MCP tools 与 OAuth 接口
migrations/D1 schema evolution;不随意改 API/数据库合同
10

明确不做与维护约束

不做

多用户、社交、公开分享、复杂权限、聊天、AI 自动规划、页面关闭后的可靠推送。

修改时保持

小步修改;不要硬编码密钥;不要提交 .env / .dev.vars;不要绕过 middleware;不要让 REST 与 MCP 出现两套校验规则。

判断完成

先做静态检查,再做对应回归测试;涉及部署时,分别验证本地代码、D1 状态、Cloudflare 部署和正式域名。