fix(audit-wave-9): onboarding + first-run UX fixes (onboarding-auditor)
Address the CRITICAL and high-leverage HIGH items from the onboarding-auditor report: **C1 — checklist auto-checks were reading the wrong setting keys** A port that had actually been configured still showed three steps as incomplete, permanently capping the checklist at < 70 %. - email step: `sales_email_smtp_host` → `smtp_host_override` (the key the email admin page actually persists). - documenso step: `documenso_api_url` → compound gate `documenso_api_url_override` + `documenso_developer_email` + `documenso_approver_email` + `documenso_eoi_template_id`. All four are required for `buildDocumensoPayload` not to error out; checking only the URL falsely greenlit the step until a rep tried to send an EOI and Documenso 404'd. - settings step: `recommender_top_n_default` → `heat_weight_recency`. The defaults are layered (port > global > built-in), so a port using the built-ins never writes the `top_n_default` row — old key was an unreachable green. heat_weight_recency genuinely means "admin tuned the recommender". **C2 — forms step href was broken** `STEPS[8].href = '../'` resolved through the Link template to the dashboard, not `/admin/forms`. Fixed to `'forms'`. **C3 — EOI signer-identity gate** Folded into the new compound-gate logic on the documenso step (see C1). Now matches what the EOI pipeline actually requires before it can send. **C4 — ensureSystemRoots failure mode poisoned port creation** `ports.service.createPort` awaited `ensureSystemRoots` after the port row had committed, so a throw bubbled out as a 500 even though the inline comment said "non-fatal if this throws". Wrap in try/catch + logger.warn — the row stays live, the next admin action self-heals via `ensureEntityFolder`, and the operator doesn't retry into a 409. **H5 — berth-list empty-state copy misleads fresh ports** "Berths are imported from external sources. Adjust your filters..." implied data existed but was hidden. Branch on whether any filter is active: with none, suggest running `import-berths-from-nocodb.ts`; with filters, the original "adjust filters" message. **M4 — admin-sections-browser description was wrong** "Setup checklist for fresh ports (read-only references)" implied the page was read-only when it has working manual-completion checkboxes and discouraged clicking in. Reworded. Additionally, the OnboardingStep type gains an optional `autoCheckSettingKeysAll` field for compound gates (used by the documenso step), and the auto-detected hint shows all keys when the gate is compound. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { ports } from '@/lib/db/schema';
|
||||
import type { PortSettings } from '@/lib/db/schema/ports';
|
||||
import { createAuditLog, type AuditMeta } from '@/lib/audit';
|
||||
import { ConflictError, NotFoundError } from '@/lib/errors';
|
||||
import { logger } from '@/lib/logger';
|
||||
import { emitToRoom } from '@/lib/socket/server';
|
||||
import type { CreatePortInput, UpdatePortInput } from '@/lib/validators/ports';
|
||||
import { ensureSystemRoots } from '@/lib/services/document-folders.service';
|
||||
@@ -41,9 +42,20 @@ export async function createPort(data: CreatePortInput, meta: AuditMeta) {
|
||||
})
|
||||
.returning();
|
||||
|
||||
// Non-fatal if this throws: ensureSystemRoots is re-runnable, and
|
||||
// scripts/backfill-document-folders.ts heals orphaned ports.
|
||||
await ensureSystemRoots(port!.id, meta.userId);
|
||||
// Non-fatal if this throws: ensureSystemRoots is re-runnable (any
|
||||
// subsequent admin action self-heals via `ensureEntityFolder`'s
|
||||
// fallback, and `scripts/backfill-document-folders.ts` covers
|
||||
// orphaned ports). Swallow + log instead of propagating, so the
|
||||
// operator doesn't see a 500 from `createPort` against an already-
|
||||
// committed port row — they'd retry and hit a 409 slug-exists.
|
||||
try {
|
||||
await ensureSystemRoots(port!.id, meta.userId);
|
||||
} catch (err) {
|
||||
logger.warn(
|
||||
{ portId: port!.id, err },
|
||||
'ensureSystemRoots failed after port create — port row is live; system folders will be created on first admin action.',
|
||||
);
|
||||
}
|
||||
|
||||
void createAuditLog({
|
||||
userId: meta.userId,
|
||||
|
||||
Reference in New Issue
Block a user