feat(recall): telemetryEvents — recall_shown/opened/dismissed/snoozed zod schemas (#6 v0.2.3)
- RecallShownPayload { noteId, ageDays: int>=0 } .strict()
- recall_opened/dismissed/snoozed → NoteIdPayload 재사용
- TelemetryEventSchema union 15 → 19
- 단위 +3 cases (recall_shown valid, extra field 거부, opened/dismissed/snoozed valid)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -306,3 +306,30 @@ describe('validateEvent — tag vocab', () => {
|
||||
})).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateEvent — recall', () => {
|
||||
it('accepts recall_shown event', () => {
|
||||
const e = validateEvent({
|
||||
ts: '2026-05-02T00:00:00.000Z',
|
||||
kind: 'recall_shown',
|
||||
payload: { noteId: 'n1', ageDays: 14 }
|
||||
});
|
||||
expect(e.kind).toBe('recall_shown');
|
||||
});
|
||||
|
||||
it('rejects recall_shown with extra field (privacy)', () => {
|
||||
expect(() => validateEvent({
|
||||
ts: '2026-05-02T00:00:00.000Z',
|
||||
kind: 'recall_shown',
|
||||
payload: { noteId: 'n1', ageDays: 14, content: 'leak' }
|
||||
})).toThrow();
|
||||
});
|
||||
|
||||
it('accepts recall_opened/dismissed/snoozed (NoteIdPayload reused)', () => {
|
||||
for (const kind of ['recall_opened', 'recall_dismissed', 'recall_snoozed'] as const) {
|
||||
const e = validateEvent({ ts: '2026-05-02T00:00:00.000Z', kind, payload: { noteId: 'n1' } });
|
||||
expect(e.kind).toBe(kind);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user