全站页面接口设计
视觉与页面需求以Figma原稿为准;当前生成API只描述已实现合同。本轮重建前端,不修改后端端点或生成客户端。以下先定义需要承接的最小合同;标“拟议”的路径仅供后续实施,不是可调用API。旧页面依赖清单继续用于兼容核查。
Figma页面的服务缺口与最小合同
所有聚合响应含 snapshot_at、window_start/end、coverage、available;未知字段为null,零值必须有完成覆盖依据。公开端只返回许可范围,个人端owner只取会话。无分析样本不返回虚构比例。
| 拟议合同 | 页面/输入 | 输出与数量 | 失败/一致性 |
|---|---|---|---|
GET /api/publication/overview | 首页;window固定24h,category可选 | tracking_count/new_count/platform_count/negative_spike_count,前5上升事件 | 同一快照,不用50条热榜代替全量;不可用字段null,局部availability |
扩展 GET /api/publication/stories/{event_id} | 事件;固定revision | sentiment三类数量+sample_count、覆盖、代表观点最多6条、24h序列最多24点 | revision一致;证据撤权后重投影;48h现值不能改标签冒充24h |
GET /api/publication/search | 探索;q/type/source_keys/window/sentiment/order/cursor,limit<=40 | 类型化结果,total仅有精确查询时返回,next_cursor | cursor绑定全部过滤和snapshot;类型未开放返回明确能力状态,非空结果中混入私有数据禁止 |
| 扩展公开刊期投影 | 日报;kind/key/revision | 固定社媒趋势<=10、重点事件、入刊观点/舆情、引用id | 使用入刊快照,不能把今天数据拼进历史刊期;按许可脱敏 |
| 扩展榜单投影 | 榜单;board/run | comparable_previous_run、rank_change、新入榜标志、最多3变化摘要 | 方法/样本口径不同不可比较;长上下文须独立发布,不改映射 |
GET /api/topics/{topic_id}/overview | 监控;24h窗口 | 24小时命中桶、平台最近成功/计数/状态 | 计数基于冻结规则版本与时间;未覆盖!=0,跨owner404 |
PUT/DELETE /api/reading/follows/{event_id} | 事件关注 | 关注状态、last_seen_revision、未读进展数 | 自然键幂等;不创建新事件副本,重复PUT不重置已读位置 |
PATCH /api/reading/alerts/{evaluation_id} | 最近告警;read=true | read_at、version | 验证评估归属;重复已读幂等;全部已读使用snapshot截止,不能吞新告警 |
| 多类型收藏本机合同 | 收藏;kind/id/note/saved_at | 当前仅资讯实现;未来类型由可公开读取投影验证 | 先扩本机结构与迁移,不默认云服务;跨设备另立明确用户故事 |
首批实施可复用当前查询扩字段,不要求同时引入上述所有路径。每个服务切片必须先更新OpenAPI,再从同一后端生成客户端,最后接UI;文档中的路径不能手写到生成文件。409保留草稿并重读,401/403区分无会话/拒绝,429保留查询不自动重试写入,5xx给重试并保留可读旧数据标过期。
从页面到接口的边界
| 当前交互 | 请求/响应中必须保留 | 存储与最小服务职责 |
|---|---|---|
| 首页加载 | stories最多50、daily最新1期 | 两路读取并行、局部降级;4项全站指标目前未知,待聚合合同 |
| 探索筛选/翻页 | q/mode/by/window/category/source_key/tag/topic/order;items或cards、next_cursor、snapshot_at | 查询URL为真源;普通30/搜索40/时间线20;换条件清游标,不拉全库 |
| 公开正文 | content_id → id/revision、许可、正文可读模式、媒体、来源、关联 | 由服务端固定发布范围解释ID;禁止客户端owner参数决定可读范围 |
| 收藏 | 本机ID/日期 → 每页20项公开详情,逐项处理撤回 | 无服务器收藏写入;如有瓶颈先验证批读需求,不建同步服务 |
| 主题创建/编辑 | name/三组关键词/source_keys/editorial_profile_ids/频率/report_time/周报/通知;编辑expected_version | 新建只保存,更新比较版本;服务返回timezone,页面不是任意时区编辑器 |
| 主题运行 | topic_id + operation_id + source_keys → topic_version、各来源job_ids或skip | 受理不是采集成功;重试保留相同输入/键;不用前端定时器调度外部采集 |
| 内容/评论读取 | content_id、root_id或parent_id、cursor/limit → 可读内容、父关系、next_cursor | 每页20;父缺失有状态;身份/版本/观察分开 |
| 评论刷新 | 单内容readiness → 明确run请求 → job_id | 沿用任务受理与恢复;查看旧评论不是刷新成功 |
| 告警保存 | operation_id/expected_revision/name/topic+rule_version/metric/threshold/cooldown/target+revision/enabled;heat_increment需事件 | 规则、评估与投递分离;没有已读状态合同 |
| 私有事件修订 | event_id+预期revision+操作/对象/原因 | 复用固定成员与revision_operations,不用页面覆盖原事实 |
| 文档草稿/发布 | path、base/source/draft版本、expected_revision、operation_id、snapshot_id | 允许清单分读/写/发布;源文件和快照已有独立流程,不复用业务content库 |
现有调用合同
每页的字段裁剪是展示模型,不应手写一份与后端脱节的新API类型。以下类型的完整定义在生成类型 ,约束/默认值/错误见对应后端。${param0}等是生成客户端模板路径,正式HTTP路径参数语义以其params类型为准。
首页与探索
| 函数 | 方法 / 路径 | 输入 → 输出 | 合同源 |
|---|---|---|---|
listPublicItems | GET /api/publication/items | listPublicItemsParams → PublicItemsPage | 生成函数 · 后端 |
getPublicHotStories | GET /api/publication/hot | getPublicHotStoriesParams → PublicStoriesPage | 生成函数 · 后端 |
getPublicTopicDirectory | GET /api/publication/topics | 无业务入参 → PublicTopicDirectoryView | 生成函数 · 后端 |
getPublicTopicPage | GET /api/publication/topics/{slug} | getPublicTopicPageParams → PublicTopicPageView | 生成函数 · 后端 |
getPublicReadingTimeline | GET /api/publication/timeline | getPublicReadingTimelineParams → PublicTimelinePage | 生成函数 · 后端 |
getPublicStory | GET /api/publication/stories/{event_id} | getPublicStoryParams → PublicStoryView | 生成函数 · 后端 |
getPublicStoryDevelopments | GET /api/publication/stories/{event_id}/developments | getPublicStoryDevelopmentsParams → PublicDevelopmentsPage | 生成函数 · 后端 |
getPublicFactReports | GET /api/publication/facts/{fact_id}/reports | getPublicFactReportsParams → PublicFactReportsPage | 生成函数 · 后端 |
getSitePublicationItem | GET /api/publication/items/{content_id}/site | getSitePublicationItemParams → PublicItemDetailView | 生成函数 · 后端 |
刊物与榜单
| 函数 | 方法 / 路径 | 输入 → 输出 | 合同源 |
|---|---|---|---|
listPublicEditionCatalogue | GET /api/publication/catalogue/editions | listPublicEditionCatalogueParams → PublicEditionCatalogueView | 生成函数 · 后端 |
getPublicEdition | GET /api/publication/editions/{kind}/{key} | getPublicEditionParams → PublicEditionView | 生成函数 · 后端 |
getPublicEditionNavigation | GET /api/publication/catalogue/editions/{kind}/navigation/{key} | getPublicEditionNavigationParams → PublicEditionNavigationView | 生成函数 · 后端 |
getPublicDailyCalendar | GET /api/publication/catalogue/editions/daily/months/{month} | getPublicDailyCalendarParams → PublicDailyCalendarView | 生成函数 · 后端 |
getLeaderboardBoard | GET /api/leaderboard/boards/{board} | getLeaderboardBoardParams → BoardView | 生成函数 · 后端 |
getLeaderboardModel | GET /api/leaderboard/models/{slug} | getLeaderboardModelParams → ModelDetailView | 生成函数 · 后端 |
listLeaderboardSources | GET /api/leaderboard/sources | 无业务入参 → SourcesView | 生成函数 · 后端 |
getLeaderboardSource | GET /api/leaderboard/sources/{source_key} | getLeaderboardSourceParams → SourceDetailView | 生成函数 · 后端 |
getLeaderboardRules | GET /api/leaderboard/rules | 无业务入参 → RulesView | 生成函数 · 后端 |
身份与主题
| 函数 | 方法 / 路径 | 输入 → 输出 | 合同源 |
|---|---|---|---|
getLoginOptions | GET /api/identity/options | 无业务入参 → LoginOptionsView | 生成函数 · 后端 |
createIdentitySession | POST /api/identity/sessions | IdentityPasswordLoginInput → IdentitySessionView | 生成函数 · 后端 |
sendEmailLoginCode | POST /api/identity/email/challenges | EmailCodeInput → EmailChallengeView | 生成函数 · 后端 |
verifyEmailLoginCode | POST /api/identity/email/sessions | VerifyEmailCodeInput → IdentitySessionView | 生成函数 · 后端 |
startGithubLogin | POST /api/identity/github/authorize | GithubAuthorizationInput → GithubAuthorizationView | 生成函数 · 后端 |
listMonitorTopics | GET /api/topics | listMonitorTopicsParams → PageViewMonitorTopicView_ | 生成函数 · 后端 |
getMonitorTopic | GET /api/topics/{topic_id} | getMonitorTopicParams → MonitorTopicView | 生成函数 · 后端 |
createMonitorTopic | POST /api/topics | MonitorTopicCreateInput → MonitorTopicView | 生成函数 · 后端 |
updateMonitorTopic | PATCH /api/topics/{topic_id} | updateMonitorTopicParams, MonitorTopicUpdateInput → MonitorTopicView | 生成函数 · 后端 |
previewMonitorTopic | POST /api/topics/preview | MonitorTopicPreviewInput → MonitorTopicPreviewView | 生成函数 · 后端 |
previewMonitorTopicSamples | POST /api/topics/sample-preview | ContentSamplePreviewInput → ContentSamplePreviewView | 生成函数 · 后端 |
runMonitorTopic | POST /api/topics/{topic_id}/runs | runMonitorTopicParams, MonitorTopicRunInput → MonitorTopicRunView | 生成函数 · 后端 |
pauseMonitorTopic | POST /api/topics/{topic_id}/pause | pauseMonitorTopicParams → MonitorTopicView | 生成函数 · 后端 |
resumeMonitorTopic | POST /api/topics/{topic_id}/resume | resumeMonitorTopicParams → MonitorTopicView | 生成函数 · 后端 |
archiveMonitorTopic | POST /api/topics/{topic_id}/archive | archiveMonitorTopicParams → MonitorTopicView | 生成函数 · 后端 |
cloneMonitorTopic | POST /api/topics/{topic_id}/clone | cloneMonitorTopicParams → MonitorTopicView | 生成函数 · 后端 |
结果、评论、来源和恢复
| 函数 | 方法 / 路径 | 输入 → 输出 | 合同源 |
|---|---|---|---|
listContentRecords | GET /api/contents | listContentRecordsParams → PageViewContentRecordSummaryView_ | 生成函数 · 后端 |
getContentRecord | GET /api/contents/{content_id} | getContentRecordParams → ContentRecordDetailView | 生成函数 · 后端 |
listContentComments | GET /api/contents/{content_id}/comments | listContentCommentsParams → PageViewContentCommentView_ | 生成函数 · 后端 |
getContentCommentRunReadiness | GET /api/contents/{content_id}/comment-run-readiness | getContentCommentRunReadinessParams → CommentRunReadinessView | 生成函数 · 后端 |
runContentComments | POST /api/contents/{content_id}/comment-runs | runContentCommentsParams, CommentManualRunInput → JobAcceptedView | 生成函数 · 后端 |
listSourceCapabilities | GET /api/source-capabilities | 无业务入参 → PageViewSourcePlatformView_ | 生成函数 · 后端 |
updateSourceConnection | PUT /api/source-connections/{source_key} | updateSourceConnectionParams, SourceConnectionUpdateInput → SourceConnectionView | 生成函数 · 后端 |
connectBilibiliChrome | POST /api/source-connections/bilibili/chrome | 无业务入参 → SourcePresetApplyView | 生成函数 · 后端 |
listCollectionJobs | GET /api/jobs | listCollectionJobsParams → PageViewJobHistoryItemView_ | 生成函数 · 后端 |
getCollectionJob | GET /api/jobs/{job_id} | getCollectionJobParams → JobStatusView | 生成函数 · 后端 |
cancelCollectionJob | POST /api/jobs/{job_id}/cancel | cancelCollectionJobParams → JobStatusView | 生成函数 · 后端 |
retryCollectionJob | POST /api/jobs/{job_id}/retry | retryCollectionJobParams → JobStatusView | 生成函数 · 后端 |
listCollectionCoverage | GET /api/collection-coverage | listCollectionCoverageParams → PageViewCollectionCoverageView_ | 生成函数 · 后端 |
getCollectionCoverage | GET /api/collection-coverage/{window_id} | getCollectionCoverageParams → CollectionCoverageView | 生成函数 · 后端 |
getCollectionCoverageMetrics | GET /api/collection-coverage/metrics | getCollectionCoverageMetricsParams → CollectionCoverageMetricsView | 生成函数 · 后端 |
告警、报告与文档
| 函数 | 方法 / 路径 | 输入 → 输出 | 合同源 |
|---|---|---|---|
listAlerts | GET /api/alerts | 无业务入参 → AlertRuleView[] | 生成函数 · 后端 |
createAlert | POST /api/alerts | AlertRuleInput → AlertRuleView | 生成函数 · 后端 |
updateAlert | PUT /api/alerts/{rule_id} | updateAlertParams, AlertRuleInput → AlertRuleView | 生成函数 · 后端 |
listAlertHistory | GET /api/alerts/{rule_id}/history | listAlertHistoryParams → AlertEvaluationView[] | 生成函数 · 后端 |
listReports | GET /api/reports | listReportsParams → PageViewReportSummaryView_ | 生成函数 · 后端 |
getReport | GET /api/reports/{report_id} | getReportParams → ReportDetailView | 生成函数 · 后端 |
listReportEditions | GET /api/editions | listReportEditionsParams → EditionSummaryView[] | 生成函数 · 后端 |
requestReportEdition | POST /api/editions | EditionRequestInput → EditionDetailView | 生成函数 · 后端 |
getReportEdition | GET /api/editions/{edition_id} | getReportEditionParams → EditionDetailView | 生成函数 · 后端 |
correctReportEdition | POST /api/editions/{edition_id}/corrections | correctReportEditionParams, EditionCorrectionInput → EditionDetailView | 生成函数 · 后端 |
listWorkspaceDocuments | GET /api/workspace/documents | listWorkspaceDocumentsParams → WorkspaceCatalogView | 生成函数 · 后端 |
searchWorkspaceDocuments | GET /api/workspace/documents/search | searchWorkspaceDocumentsParams → WorkspaceSearchView | 生成函数 · 后端 |
getWorkspaceDocument | GET /api/workspace/documents/document | getWorkspaceDocumentParams → WorkspaceDocumentView | 生成函数 · 后端 |
getWorkspaceDocumentDraft | GET /api/workspace/documents/draft | getWorkspaceDocumentDraftParams → WorkspaceDraftView | 生成函数 · 后端 |
saveWorkspaceDocumentDraft | PUT /api/workspace/documents/draft | WorkspaceSaveInput → WorkspaceDraftView | 生成函数 · 后端 |
publishWorkspaceDocument | POST /api/workspace/documents/publish | WorkspacePublishInput → WorkspaceOperationView | 生成函数 · 后端 |
getWorkspaceDocumentOperation | GET /api/workspace/documents/operations/{operation_id} | getWorkspaceDocumentOperationParams → WorkspaceOperationView | 生成函数 · 后端 |
核心写入的字段和校验
| 操作 | 必填/关键字段 | 页面校验与服务器判断 | 成功/失败恢复 |
|---|---|---|---|
| 创建主题 | name、match_any/match_all/exclude;来源与频率/报告配置按现有默认 | 词条使用KeywordInput;名字和规则限制沿用schema;来源必须实际准入 | 返回MonitorTopicView再跳详情。当前创建合同没有operation_id,不承诺自动幂等;响应丢失先重读列表核对,不能盲目重发 |
| 修改主题 | 创建字段+expected_version | 服务比较当前版本;主题owner从会话取得 | 返回新current_version;409保留草稿并提示重读,不静默覆盖 |
| 立即运行 | operation_id(UUID)、source_keys;topic_id路径参数 | 主题状态/来源版本/预算/准入以服务器为准 | 返回每个来源job_ids或skip;同一次操作复用原键;刷新后的完整批次回执目前没有独立读取合同,列为缺口 |
| 保存告警 | operation_id、expected_revision、topic_id/topic_rule_version、metric、threshold、cooldown_seconds、target_id/target_revision | metric为negative_count或heat_increment;前者计数阈值应为整数,后者关联事件;具体范围由已有合同校验 | 返回AlertRuleView;冲突重读规则/主题/目标;不要借保存动作重复发送通知 |
| 反馈 | operation_id、content;email/page_url/screenshot可选 | 当前UI正文2–5000字符、邮箱≤200、页面URL≤500、截图≤8MiB且类型受限;服务器仍必须验证 | 返回编号;失败留输入和原操作号;不自动转发到外部应用 |
| 取消/恢复Job | job_id与现有控制输入 | 服务器判断状态、manual_retry_allowed、租约和冻结来源条件 | 成功后重读原任务;取消只能阻止后续步骤,不等于撤销已发外部请求 |
账户密码和验证码、运营令牌均不属于页面持久字段;只通过既有认证合同传递,不写URL、日志、导出和本机长期存储。
错误、授权与重试
统一使用ApiRequestError的HTTP状态和code分支,message仅为显示文案。各接口实际错误集以路由定义为准,不给每个端点机械添加相同状态码。
| 情况 | 页面行为 |
|---|---|
| 401/会话失效 | 清除当前私有视图,安全站内回跳登录;不靠缓存继续展示敏感详情 |
| 403/独立管理权限不足 | 显示无权限或所需配置,普通登录不等于运营权限 |
| 404/资源不存在或不可读 | 不暴露另一owner的标题;公开撤回不能回退到旧正文 |
| 409/版本或操作冲突 | 保留用户输入,重读服务版本;同键异参不当成成功 |
| 422/输入不合规则 | 关联具体表单字段;页面校验不能代替服务校验 |
| 429/限流或冷却 | 展示实际等待/停止原因,不循环自动重试写入 |
| 503/数据库、来源或服务不可用 | 与无记录区分;独立区块单独失败,已有合法数据标记过期 |
| 网络断开、超时、请求取消 | 读取允许重试,旧响应不能覆盖新筛选;写入可能已提交,按原合同查结果,不假定“没发出” |
私有读取不进入公开缓存。公开读也必须复核许可/修订。所有生成请求经过现有request.ts,业务不直接fetch/Axios;仅调整页面字段使用时不改变网络层或创建第二套SDK。
避免重复建设
全站统计、情感、关注和告警已读按上方原稿需求承接;优先扩充现有读取投影,不为每个控件新建服务。不新增通用操作账本、独立运行批次/来源批次状态机;静态说明不建CRUD。本机备注不需要云写入,跨设备同步需独立用户故事。
增量必须附页面、控件、输入输出、统计口径、现有接口不足、最小存储与可复跑验收。后端合同变更后生成客户端,不手改生成物;真实来源与送达另行验收。