- Event model + ToJSON - EventSink interface + ChannelEventSink (non-blocking Submit) - event_repo: batch INSERT ON CONFLICT DO NOTHING dedup - event_service: 7-type whitelist + 1KB props limit + ReceivedAt auto-fill - event_flusher: 100/1s batch + sync metric_recent_level_ups on level_up - metric_weekly + metric_upcoming workers (5min/15min with pg_try_advisory_lock) - partitioner: 7-day pre-create + 30-day cleanup (00:05 create / 00:30 cleanup) - 22 unit + integration tests (model/repo/service/sink/worker) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
34 lines
993 B
Go
34 lines
993 B
Go
package model
|
||
|
||
import "time"
|
||
|
||
// Event 通用事件模型
|
||
// 关联: spec §2.2 + plan Task 4
|
||
type Event struct {
|
||
EventID string `json:"event_id"`
|
||
UserID int64 `json:"user_id"`
|
||
StarID int64 `json:"star_id"`
|
||
EventType string `json:"event_type"`
|
||
OccurredAt time.Time `json:"occurred_at"`
|
||
ReceivedAt time.Time `json:"received_at"`
|
||
Properties map[string]string `json:"properties"`
|
||
}
|
||
|
||
// ToJSON 序列化为 map(用于日志/调试/Redis 缓存)
|
||
// 时间字段转为毫秒时间戳(与 proto event.proto 字段类型一致)
|
||
func (e *Event) ToJSON() map[string]interface{} {
|
||
props := e.Properties
|
||
if props == nil {
|
||
props = map[string]string{}
|
||
}
|
||
return map[string]interface{}{
|
||
"event_id": e.EventID,
|
||
"user_id": e.UserID,
|
||
"star_id": e.StarID,
|
||
"event_type": e.EventType,
|
||
"occurred_at": e.OccurredAt.UnixMilli(),
|
||
"received_at": e.ReceivedAt.UnixMilli(),
|
||
"properties": props,
|
||
}
|
||
}
|