fix(audit): wire reminder defaults into createInterest; doc branding gap (R2-H15/H16)

R2-H16: /admin/reminders persisted defaultEnabled + defaultDays to
system_settings but createInterest ignored them — every new interest
defaulted to reminderEnabled=false regardless. The validator now
treats reminderEnabled / reminderDays as optional (no default false),
and createInterest falls back to getPortReminderConfig(portId) when
the caller omits them. Explicit false / null still opts out.

R2-H15: branding admin (/admin/branding) saves 5 settings that no
code reads — the email templates and BrandedAuthShell hardcode Port
Nimara branding. Wiring it end-to-end is a multi-template refactor;
documented the gap inline above getPortBrandingConfig with a
step-by-step wire-up plan so future devs don't think it's done.

The reminder-digest scheduler (digestEnabled/digestTime/digestTimezone)
remains unimplemented — needs a new BullMQ recurring job that batches
pending reminders into per-user/per-port digest emails. Out of scope
for this audit pass.

1175/1175 vitest passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Ciaccio
2026-05-06 22:28:41 +02:00
parent c312cd3685
commit 0a5f085a9e
3 changed files with 33 additions and 1 deletions

View File

@@ -9,6 +9,7 @@ import { yachts } from '@/lib/db/schema/yachts';
import { companyMemberships } from '@/lib/db/schema/companies';
import { tags } from '@/lib/db/schema/system';
import { createAuditLog, type AuditMeta } from '@/lib/audit';
import { getPortReminderConfig } from '@/lib/services/port-config';
import { NotFoundError, ConflictError, ValidationError } from '@/lib/errors';
import { emitToRoom } from '@/lib/socket/server';
import { setEntityTags } from '@/lib/services/entity-tags.helper';
@@ -438,12 +439,21 @@ export async function createInterest(portId: string, data: CreateInterestInput,
data.yachtId,
);
// Per-port reminder defaults — applied only when the caller omitted
// reminderEnabled / reminderDays. Honors the /admin/reminders page.
const reminderConfig = await getPortReminderConfig(portId);
const resolvedReminderEnabled = interestData.reminderEnabled ?? reminderConfig.defaultEnabled;
const resolvedReminderDays =
interestData.reminderDays ?? (resolvedReminderEnabled ? reminderConfig.defaultDays : null);
const result = await withTransaction(async (tx) => {
const [interest] = await tx
.insert(interests)
.values({
portId,
...interestData,
reminderEnabled: resolvedReminderEnabled,
reminderDays: resolvedReminderDays,
leadCategory: resolvedLeadCategory,
})
.returning();