feat(schema): protobuf event registry + buf CI gate (#54)
- Add proto schemas in packages/shared-types/events/ (oo.events.v1): envelope.proto, signals.proto, integration.proto - buf.yaml with STANDARD lint + FILE breaking-change rules - .gitea/workflows/buf-check.yaml: lint + breaking check on every PR touching events/ (needs a Gitea Actions runner to execute) - scripts/buf-check.sh: local equivalent of the CI check - NormalizedEvent TS envelope gains eventId, schemaVersion, producer to align with the proto Envelope message - ml/serving/schemas.py: pydantic models mirroring the v1 proto types - nats_consumer.py: validate payloads via pydantic instead of raw .get() A field-rename PR will now fail buf breaking with exit code 100 and show the offending messages. To make a breaking change: keep the old field reserved, add the new one, bump schema_version to v2. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
50
ml/serving/schemas.py
Normal file
50
ml/serving/schemas.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
Pydantic models mirroring oo.events.v1 proto schemas.
|
||||
|
||||
Field names use camelCase to match the proto3 JSON mapping convention
|
||||
and the TypeScript payload shapes published by services/api.
|
||||
|
||||
Keep in sync with packages/shared-types/events/oo/events/v1/.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal, Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class TaskSyncedPayload(BaseModel):
|
||||
userId: str
|
||||
source: str
|
||||
count: int
|
||||
syncedAt: str
|
||||
|
||||
|
||||
class TipServedPayload(BaseModel):
|
||||
userId: str
|
||||
tipId: str
|
||||
policy: str
|
||||
servedAt: str
|
||||
|
||||
|
||||
class TipFeedbackPayload(BaseModel):
|
||||
userId: str
|
||||
tipId: str
|
||||
action: Literal['done', 'dismiss', 'snooze', 'helpful', 'not_helpful']
|
||||
reward: float
|
||||
dwellMs: Optional[int] = None
|
||||
createdAt: str
|
||||
|
||||
|
||||
class TipRewardFailedPayload(BaseModel):
|
||||
userId: str
|
||||
tipId: str
|
||||
reward: float
|
||||
attempts: int
|
||||
error: str
|
||||
failedAt: str
|
||||
|
||||
|
||||
class IntegrationTokenExpiredPayload(BaseModel):
|
||||
userId: str
|
||||
provider: str
|
||||
detectedAt: str
|
||||
Reference in New Issue
Block a user