watch: ingest sink (--notify ingest) posting events to a push ingest endpoint

This commit is contained in:
CRTkafa 2026-10-23 15:30:18 +08:00
parent 5b3905679b
commit 487e138f9d
9 changed files with 236 additions and 18 deletions

View file

@ -25,6 +25,8 @@ export interface WatchEvent {
detail: string;
/** The absolute console deep link for the app (App Store Connect / Play Console). */
url: string;
/** Review events only: the store's review id (dedupe key of the ingest sink). */
ref?: string;
}
/** One version on one store, reduced to what the diff needs. */
@ -189,8 +191,8 @@ export function diffApp(prev: AppSnap | undefined, next: AppSnap, at: string): W
if (!prev) return [];
const out: WatchEvent[] = [];
const ids = { ...prev.ids, ...next.ids };
const ev = (store: WatchStore, kind: EventKind, version: string | null, from: string | null, to: string | null, detail: string): void => {
out.push({ at, app: next.name, store, kind, version, from, to, detail, url: eventUrl(kind, store, ids) });
const ev = (store: WatchStore, kind: EventKind, version: string | null, from: string | null, to: string | null, detail: string, ref?: string): void => {
out.push({ at, app: next.name, store, kind, version, from, to, detail, url: eventUrl(kind, store, ids), ...(ref ? { ref } : {}) });
};
for (const store of ['apple', 'play'] as const) {
@ -225,8 +227,8 @@ export function diffApp(prev: AppSnap | undefined, next: AppSnap, at: string): W
const seen = new Set(p.map(r => r.id));
for (const r of n) {
if (seen.has(r.id)) continue;
if (r.rating >= 1 && r.rating <= LOW_STARS) ev(store, 'review_low', null, null, `${r.rating} stars`, `${r.rating}-star review${r.replied ? '' : ', no reply yet'}: ${snippet(r.text)}`);
else if (!r.replied) ev(store, 'review_needs_reply', null, null, `${r.rating} stars`, `${r.rating}-star review without a reply: ${snippet(r.text)}`);
if (r.rating >= 1 && r.rating <= LOW_STARS) ev(store, 'review_low', null, null, `${r.rating} stars`, `${r.rating}-star review${r.replied ? '' : ', no reply yet'}: ${snippet(r.text)}`, r.id);
else if (!r.replied) ev(store, 'review_needs_reply', null, null, `${r.rating} stars`, `${r.rating}-star review without a reply: ${snippet(r.text)}`, r.id);
}
}
return out;