PBI-55: src/lib/push-trigger.ts – fire-and-forget push helper with 5s AbortController timeout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0d6bf8dd0d
commit
18c34b63de
2 changed files with 26 additions and 0 deletions
|
|
@ -3,3 +3,7 @@ DATABASE_URL="postgresql://user:pass@host:5432/dbname"
|
||||||
|
|
||||||
# API token from Scrum4Me → /settings/tokens
|
# API token from Scrum4Me → /settings/tokens
|
||||||
SCRUM4ME_TOKEN=""
|
SCRUM4ME_TOKEN=""
|
||||||
|
|
||||||
|
# Internal push endpoint (main-app) for web-push notifications
|
||||||
|
INTERNAL_PUSH_URL=""
|
||||||
|
INTERNAL_PUSH_SECRET=""
|
||||||
|
|
|
||||||
22
src/lib/push-trigger.ts
Normal file
22
src/lib/push-trigger.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
export type PushPayload = { title: string; body: string; url: string; tag?: string };
|
||||||
|
|
||||||
|
export async function triggerPush(userId: string, payload: PushPayload): Promise<void> {
|
||||||
|
const url = process.env.INTERNAL_PUSH_URL;
|
||||||
|
const secret = process.env.INTERNAL_PUSH_SECRET;
|
||||||
|
if (!url || !secret) return; // feature-gated
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timeout = setTimeout(() => controller.abort(), 5000);
|
||||||
|
try {
|
||||||
|
const res = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'content-type': 'application/json', authorization: `Bearer ${secret}` },
|
||||||
|
body: JSON.stringify({ userId, payload }),
|
||||||
|
signal: controller.signal,
|
||||||
|
});
|
||||||
|
if (!res.ok) console.warn('[push-trigger] non-2xx', res.status);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[push-trigger]', err);
|
||||||
|
} finally {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue