fix: email
This commit is contained in:
6
bun.lock
6
bun.lock
@@ -95,7 +95,7 @@
|
||||
"@orpc/zod": "catalog:",
|
||||
"dotenv": "catalog:",
|
||||
"drizzle-orm": "^0.45.1",
|
||||
"nodemailer": "^8.0.1",
|
||||
"nodemailer": "^8.0.2",
|
||||
"zod": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -1511,7 +1511,7 @@
|
||||
|
||||
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
|
||||
|
||||
"nodemailer": ["nodemailer@8.0.1", "", {}, "sha512-5kcldIXmaEjZcHR6F28IKGSgpmZHaF1IXLWFTG+Xh3S+Cce4MiakLtWY+PlBU69fLbRa8HlaGIrC/QolUpHkhg=="],
|
||||
"nodemailer": ["nodemailer@8.0.2", "", {}, "sha512-zbj002pZAIkWQFxyAaqoxvn+zoIwRnS40hgjqTXudKOOJkiFFgBeNqjgD3/YCR12sZnrghWYBY+yP1ZucdDRpw=="],
|
||||
|
||||
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
|
||||
|
||||
@@ -1987,8 +1987,6 @@
|
||||
|
||||
"@jridgewell/remapping/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@kk/auth/nodemailer": ["nodemailer@8.0.2", "", {}, "sha512-zbj002pZAIkWQFxyAaqoxvn+zoIwRnS40hgjqTXudKOOJkiFFgBeNqjgD3/YCR12sZnrghWYBY+yP1ZucdDRpw=="],
|
||||
|
||||
"@noble/curves/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
|
||||
|
||||
"@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@orpc/zod": "catalog:",
|
||||
"dotenv": "catalog:",
|
||||
"drizzle-orm": "^0.45.1",
|
||||
"nodemailer": "^8.0.1",
|
||||
"nodemailer": "^8.0.2",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
9
packages/api/src/constants.ts
Normal file
9
packages/api/src/constants.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Single source-of-truth for event details used across the API
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const EVENT = "Open Mic Night — vrijdag 18 april 2026";
|
||||
export const OPENS = "maandag 16 maart 2026 om 19:00";
|
||||
|
||||
// Registration opens — used for reminder scheduling windows
|
||||
export const REGISTRATION_OPENS_AT = new Date("2026-03-16T19:00:00+01:00");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -348,7 +348,7 @@ export const drinkkaartRouter = {
|
||||
.then((r) => r[0]);
|
||||
|
||||
if (cardUser) {
|
||||
sendDeductionEmail({
|
||||
await sendDeductionEmail({
|
||||
to: cardUser.email,
|
||||
firstName: cardUser.name.split(" ")[0] ?? cardUser.name,
|
||||
amountCents: input.amountCents,
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
sum,
|
||||
} from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import { REGISTRATION_OPENS_AT } from "../constants";
|
||||
import {
|
||||
emailLog,
|
||||
sendCancellationEmail,
|
||||
@@ -32,8 +33,7 @@ import { adminProcedure, protectedProcedure, publicProcedure } from "../index";
|
||||
import { generateQrSecret } from "../lib/drinkkaart-utils";
|
||||
import { drinkkaartRouter } from "./drinkkaart";
|
||||
|
||||
// Registration opens at this date — reminders fire 24 hours and 1 hour before
|
||||
const REGISTRATION_OPENS_AT = new Date("2026-03-16T19:00:00+01:00");
|
||||
// Reminder windows derived from the canonical registration open date
|
||||
const REMINDER_1H_WINDOW_START = new Date(
|
||||
REGISTRATION_OPENS_AT.getTime() - 60 * 60 * 1000,
|
||||
);
|
||||
@@ -879,13 +879,15 @@ export const appRouter = {
|
||||
email: input.email,
|
||||
});
|
||||
|
||||
// Fire-and-forget — don't let a mail failure block the response
|
||||
sendSubscriptionConfirmationEmail({ to: input.email }).catch((err) =>
|
||||
emailLog("error", "email.catch", {
|
||||
type: "subscription_confirmation",
|
||||
to: input.email,
|
||||
error: String(err),
|
||||
}),
|
||||
// Awaited — CF Workers abandon unawaited promises when the response
|
||||
// returns. Mail errors are caught so they don't fail the request.
|
||||
await sendSubscriptionConfirmationEmail({ to: input.email }).catch(
|
||||
(err) =>
|
||||
emailLog("error", "email.catch", {
|
||||
type: "subscription_confirmation",
|
||||
to: input.email,
|
||||
error: String(err),
|
||||
}),
|
||||
);
|
||||
|
||||
return { ok: true };
|
||||
|
||||
4
packages/env/src/server.ts
vendored
4
packages/env/src/server.ts
vendored
@@ -15,13 +15,13 @@ export const env = createEnv({
|
||||
server: {
|
||||
DATABASE_URL: z.string().min(1),
|
||||
BETTER_AUTH_SECRET: z.string().min(32),
|
||||
BETTER_AUTH_URL: z.url(),
|
||||
BETTER_AUTH_URL: z.url().default("https://kunstenkamp.be"),
|
||||
CORS_ORIGIN: z.url(),
|
||||
SMTP_HOST: z.string().min(1).optional(),
|
||||
SMTP_PORT: z.coerce.number().default(587),
|
||||
SMTP_USER: z.string().min(1).optional(),
|
||||
SMTP_PASS: z.string().min(1).optional(),
|
||||
SMTP_FROM: z.string().min(1).optional(),
|
||||
SMTP_FROM: z.string().min(1).default("Kunstenkamp <info@kunstenkamp.be>"),
|
||||
NODE_ENV: z
|
||||
.enum(["development", "production", "test"])
|
||||
.default("development"),
|
||||
|
||||
Reference in New Issue
Block a user