API-INFO-003 P0 | 新增 ReadingEvent 表 【status:todo】 #107

Closed
opened 2026-06-07 11:03:38 +08:00 by wangdl · 2 comments
Owner

目标

保存所有原始阅读事件,支持去重、审计、重放。

关键字段

userId, eventId, clientSessionId, readingTargetType, materialId,
knowledgeBaseId?, eventType, position (JSON),
rawActiveSecondsDelta, countedActiveSecondsDelta,
clientTimestamp, clientTimezoneOffsetMinutes?, serverReceivedAt,
sequence, platform, appVersion,
status (pending|processed|failed|ignored),
errorCode?, warningCodes?

索引

  • unique(userId, eventId)
  • index(userId, clientSessionId)
  • index(userId, readingTargetType, materialId, clientTimestamp)
  • index(status, createdAt)

详见设计文档 API-INFO-000。

## 目标 保存所有原始阅读事件,支持去重、审计、重放。 ### 关键字段 ```text userId, eventId, clientSessionId, readingTargetType, materialId, knowledgeBaseId?, eventType, position (JSON), rawActiveSecondsDelta, countedActiveSecondsDelta, clientTimestamp, clientTimezoneOffsetMinutes?, serverReceivedAt, sequence, platform, appVersion, status (pending|processed|failed|ignored), errorCode?, warningCodes? ``` ### 索引 - unique(userId, eventId) - index(userId, clientSessionId) - index(userId, readingTargetType, materialId, clientTimestamp) - index(status, createdAt) 详见设计文档 API-INFO-000。
wangdl added this to the M8:学习信息收集与基础分析闭环 milestone 2026-06-07 11:03:38 +08:00
wangdl changed title from API-INFO-002 P0 | 新增 ReadingEvent 数据表 to API-INFO-003 P0 | 新增 ReadingEvent 表 2026-06-07 11:22:13 +08:00
wangdl changed title from API-INFO-003 P0 | 新增 ReadingEvent 表 to API-INFO-003 P0 | 新增 ReadingEvent 表 【status:todo】 2026-06-07 19:04:10 +08:00
Author
Owner

审查结论:当前 API 项目学习信息收集体系基本为全新建设。可复用:JWT Guard、LearningSession 基础表/CRUD、DailyLearningActivity 基础表、ActivityController 部分接口、LearningRecord schema。其余 ReadingEvent/TemporaryMaterial/Progress/批量上报/Processor/聚合/查询接口/错误码/去重/权限/测试/文档均不存在或仅部分存在。

本 Issue: 表不存在。全新建设。

标签: audit:reviewed audit:api-info status:todo work:new-table

## 审查结论:当前 API 项目学习信息收集体系基本为全新建设。可复用:JWT Guard、LearningSession 基础表/CRUD、DailyLearningActivity 基础表、ActivityController 部分接口、LearningRecord schema。其余 ReadingEvent/TemporaryMaterial/Progress/批量上报/Processor/聚合/查询接口/错误码/去重/权限/测试/文档均不存在或仅部分存在。 **本 Issue**: 表不存在。全新建设。 **标签**: audit:reviewed audit:api-info status:todo work:new-table
Author
Owner

完成报告

交付

1. Prisma Schemaprisma/schema.prisma 新增 ReadingEvent 模型:

model ReadingEvent {
  id                        String    @id @default(cuid())
  userId                    String
  eventId                   String
  clientSessionId           String
  readingTargetType         String    @db.VarChar(32)
  materialId                String
  knowledgeBaseId           String?
  eventType                 String    @db.VarChar(32)
  position                  Json?
  activeSecondsDelta        Int       @default(0)
  clientTimestampMs         BigInt
  clientTimezoneOffsetMinutes Int?
  sequence                  Int
  platform                  String?   @db.VarChar(16)
  appVersion                String?   @db.VarChar(32)
  status                    String    @default("pending") @db.VarChar(32)
  errorCode                 String?   @db.VarChar(32)
  warningCodes              Json?
  serverReceivedAt          DateTime  @default(now())
  processedAt               DateTime?
  createdAt                 DateTime  @default(now())

  user User @relation(fields: [userId], references: [id])

  @@unique([userId, eventId])
  @@index([userId, clientSessionId])
  @@index([userId, readingTargetType, materialId, clientTimestampMs])
  @@index([status, createdAt])
  @@index([userId, createdAt])
}

关键字段

  • eventId + userId unique(幂等去重)
  • position JSON(camelCase ReadingPosition)
  • status enum(pending/processed/failed/duplicate/ignored)
  • serverReceivedAt(服务端接收时间)

索引

  • @@unique([userId, eventId]) — 幂等键
  • @@index([userId, clientSessionId]) — session 查询
  • @@index([userId, readingTargetType, materialId, clientTimestampMs]) — 资料时间线
  • @@index([status, createdAt]) — 状态扫描

2. NestJS Modulesrc/modules/reading-event/:

reading-event.module.ts  — PrismaModule 注入
reading-event.service.ts — bulkUpsert() + findBySession()
## 完成报告 ### 交付 **1. Prisma Schema** — `prisma/schema.prisma` 新增 `ReadingEvent` 模型: ```prisma model ReadingEvent { id String @id @default(cuid()) userId String eventId String clientSessionId String readingTargetType String @db.VarChar(32) materialId String knowledgeBaseId String? eventType String @db.VarChar(32) position Json? activeSecondsDelta Int @default(0) clientTimestampMs BigInt clientTimezoneOffsetMinutes Int? sequence Int platform String? @db.VarChar(16) appVersion String? @db.VarChar(32) status String @default("pending") @db.VarChar(32) errorCode String? @db.VarChar(32) warningCodes Json? serverReceivedAt DateTime @default(now()) processedAt DateTime? createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) @@unique([userId, eventId]) @@index([userId, clientSessionId]) @@index([userId, readingTargetType, materialId, clientTimestampMs]) @@index([status, createdAt]) @@index([userId, createdAt]) } ``` **关键字段**: - `eventId` + `userId` unique(幂等去重) - `position` JSON(camelCase ReadingPosition) - `status` enum(pending/processed/failed/duplicate/ignored) - `serverReceivedAt`(服务端接收时间) **索引**: - `@@unique([userId, eventId])` — 幂等键 - `@@index([userId, clientSessionId])` — session 查询 - `@@index([userId, readingTargetType, materialId, clientTimestampMs])` — 资料时间线 - `@@index([status, createdAt])` — 状态扫描 **2. NestJS Module** — `src/modules/reading-event/`: ``` reading-event.module.ts — PrismaModule 注入 reading-event.service.ts — bulkUpsert() + findBySession() ```
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wangdl/api-server#107
No description provided.