Load env files in notification worker
This commit is contained in:
@@ -28,7 +28,7 @@ npm run start
|
|||||||
npm run notifications:worker
|
npm run notifications:worker
|
||||||
```
|
```
|
||||||
|
|
||||||
Repozytorium nie ma obecnie skryptu testów, osobnego skryptu type-check ani formattera. `npm run build` uruchamia kontrolę TypeScript wykonywaną przez Next.js. `npm run notifications:worker` uruchamia osobny proces Node do cyklicznego wywoływania endpointów Web Push na self-hostingu; wymaga równolegle działającego `npm run start` albo poprawnego `WTR_APP_URL`. Nie opisuj ani nie uruchamiaj nieistniejących komend jako standardowego workflow.
|
Repozytorium nie ma obecnie skryptu testów, osobnego skryptu type-check ani formattera. `npm run build` uruchamia kontrolę TypeScript wykonywaną przez Next.js. `npm run notifications:worker` uruchamia osobny proces Node do cyklicznego wywoływania endpointów Web Push na self-hostingu; wczytuje `.env` i `.env.local`, ale nadal wymaga równolegle działającego `npm run start` albo poprawnego `WTR_APP_URL`. Nie opisuj ani nie uruchamiaj nieistniejących komend jako standardowego workflow.
|
||||||
|
|
||||||
## Konwencje kodu
|
## Konwencje kodu
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ npm run start
|
|||||||
npm run notifications:worker
|
npm run notifications:worker
|
||||||
```
|
```
|
||||||
|
|
||||||
Worker musi mieć dostęp do działającej aplikacji Next.js. Domyślnie odpytuje `http://127.0.0.1:3000`; jeśli aplikacja działa pod innym adresem albo portem, ustaw `WTR_APP_URL`.
|
Worker musi mieć dostęp do działającej aplikacji Next.js. Domyślnie odpytuje `http://127.0.0.1:3000`; jeśli aplikacja działa pod innym adresem albo portem, ustaw `WTR_APP_URL`. Skrypt workera sam wczytuje `.env` i `.env.local`, a zmienne podane bezpośrednio w shellu mają pierwszeństwo.
|
||||||
|
|
||||||
## Źródła danych
|
## Źródła danych
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ NOTIFICATIONS_WARNING_INTERVAL_MINUTES=5
|
|||||||
NOTIFICATIONS_MORNING_BRIEF_TIME=07:00
|
NOTIFICATIONS_MORNING_BRIEF_TIME=07:00
|
||||||
```
|
```
|
||||||
|
|
||||||
Klucze VAPID można wygenerować poleceniem `npx web-push generate-vapid-keys`. Worker `npm run notifications:worker` domyślnie odpytuje `http://127.0.0.1:3000`, więc `npm run start` musi działać równolegle na tym samym hoście albo `WTR_APP_URL` musi wskazywać właściwy adres aplikacji. Worker sprawdza ostrzeżenia co 5 minut i wysyła poranny brief po 07:00 czasu polskiego. Jeśli używasz zewnętrznego crona zamiast workera, cron ostrzeżeń powinien wywoływać `GET /api/notifications/check` z nagłówkiem `Authorization: Bearer <NOTIFICATIONS_CRON_SECRET>` albo `x-cron-secret`. Drugi cron, ustawiony na około 07:00 czasu polskiego, powinien wywoływać `GET /api/notifications/daily-brief` z tym samym nagłówkiem.
|
Klucze VAPID można wygenerować poleceniem `npx web-push generate-vapid-keys`. Worker `npm run notifications:worker` wczytuje `.env` i `.env.local`, domyślnie odpytuje `http://127.0.0.1:3000`, więc `npm run start` musi działać równolegle na tym samym hoście albo `WTR_APP_URL` musi wskazywać właściwy adres aplikacji. Worker sprawdza ostrzeżenia co 5 minut i wysyła poranny brief po 07:00 czasu polskiego. Jeśli używasz zewnętrznego crona zamiast workera, cron ostrzeżeń powinien wywoływać `GET /api/notifications/check` z nagłówkiem `Authorization: Bearer <NOTIFICATIONS_CRON_SECRET>` albo `x-cron-secret`. Drugi cron, ustawiony na około 07:00 czasu polskiego, powinien wywoływać `GET /api/notifications/daily-brief` z tym samym nagłówkiem.
|
||||||
|
|
||||||
## Wdrożenie na Vercel
|
## Wdrożenie na Vercel
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
|
import { existsSync, readFileSync } from "node:fs";
|
||||||
|
|
||||||
const DEFAULT_APP_URL = "http://127.0.0.1:3000";
|
const DEFAULT_APP_URL = "http://127.0.0.1:3000";
|
||||||
const DEFAULT_WARNING_INTERVAL_MINUTES = 5;
|
const DEFAULT_WARNING_INTERVAL_MINUTES = 5;
|
||||||
const DEFAULT_MORNING_BRIEF_TIME = "07:00";
|
const DEFAULT_MORNING_BRIEF_TIME = "07:00";
|
||||||
const LOOP_INTERVAL_MS = 30_000;
|
const LOOP_INTERVAL_MS = 30_000;
|
||||||
|
|
||||||
|
const initialEnvKeys = new Set(Object.keys(process.env));
|
||||||
|
loadEnvFile(".env", false);
|
||||||
|
loadEnvFile(".env.local", true);
|
||||||
|
|
||||||
const appUrl = normalizeAppUrl(process.env.WTR_APP_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? DEFAULT_APP_URL);
|
const appUrl = normalizeAppUrl(process.env.WTR_APP_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? DEFAULT_APP_URL);
|
||||||
const cronSecret = process.env.NOTIFICATIONS_CRON_SECRET ?? "";
|
const cronSecret = process.env.NOTIFICATIONS_CRON_SECRET ?? "";
|
||||||
const warningIntervalMinutes = readPositiveNumber(process.env.NOTIFICATIONS_WARNING_INTERVAL_MINUTES, DEFAULT_WARNING_INTERVAL_MINUTES);
|
const warningIntervalMinutes = readPositiveNumber(process.env.NOTIFICATIONS_WARNING_INTERVAL_MINUTES, DEFAULT_WARNING_INTERVAL_MINUTES);
|
||||||
@@ -12,6 +18,22 @@ let lastWarningCheckAt = 0;
|
|||||||
let lastMorningBriefDate = "";
|
let lastMorningBriefDate = "";
|
||||||
let isRunningTick = false;
|
let isRunningTick = false;
|
||||||
|
|
||||||
|
function loadEnvFile(path, overrideLoadedValues) {
|
||||||
|
if (!existsSync(path)) return;
|
||||||
|
const lines = readFileSync(path, "utf8").split(/\r?\n/);
|
||||||
|
for (const line of lines) {
|
||||||
|
const trimmedLine = line.trim();
|
||||||
|
if (!trimmedLine || trimmedLine.startsWith("#")) continue;
|
||||||
|
const separatorIndex = trimmedLine.indexOf("=");
|
||||||
|
if (separatorIndex === -1) continue;
|
||||||
|
const key = trimmedLine.slice(0, separatorIndex).trim();
|
||||||
|
const rawValue = trimmedLine.slice(separatorIndex + 1).trim();
|
||||||
|
if (!key || initialEnvKeys.has(key)) continue;
|
||||||
|
if (!overrideLoadedValues && process.env[key] !== undefined) continue;
|
||||||
|
process.env[key] = rawValue.replace(/^['"]|['"]$/g, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeAppUrl(value) {
|
function normalizeAppUrl(value) {
|
||||||
return value.replace(/\/+$/, "");
|
return value.replace(/\/+$/, "");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user