Bundles the prior autonomous-session output that was sitting unstaged: - Em-dash sweep across src/ + tests/ (en-dash/em-dash to hyphen, ~2280 instances) - country-flag-icons rollout (CountryFlag component, replaces emoji glyphs that never rendered on Windows; lazy-loads the 3x2 SVG index as a single chunk after the per-subpath dynamic-import approach silently failed in webpack) - Admin IA Phase 1+2: 7-domain regroup, 41 to 38 pages, /admin/berths index, redirects (ocr to ai, reports to dashboard, invitations to users), docs/admin-ia-proposal.md - Per-template email tester (registry + endpoint + UI on Email admin page) - Cancel-document mode picker (delete-from-Documenso vs keep-for-audit) - Dashboard PDF report: 25 widgets, SVG charts, date-range picker, 11 resolvers - Customize-widgets per-region sortables at xl+ (charts/rails/feed); single flat sortable below xl when the layout stacks; per-viewport saved orders - Audit doc updates capturing each shipped item - Lint fixes: react-compiler immutability in DonutChart (reduce instead of let-reassign), set-state-in-effect disables in CountryFlag and UploadForSigning preview-bytes effect, unused 'confirm' destructures in interest contract + reservation tabs, unescaped apostrophe in test-template card copy
35 KiB
Admin IA — Audit + Proposed Regrouping
Status: Phase 1 (proposal + decisions) — captured 2026-05-22 from B3 #10. Open questions resolved in section 7; final IA reflected in section 8. Phase 2 (execution) is mechanical from here.
Resolved decisions (2026-05-22)
User answered the 5 open questions from section 7:
- Forms + Document Templates → moved to Sales workflow (not "Content"). Both are workflow inputs, not abstract content.
- Webhooks → keep as its own thing; new "Integrations" domain is the right home (Webhooks + Documenso + Website analytics + AI all belong together as "external system + provider config").
- AI configuration → keep a dedicated
/admin/aipanel that consolidates every AI feature in one place; lives under the new Integrations domain. /admin/reports→ DELETE entirely (confirmed duplicative — the dashboard already renders Pipeline funnel + Berth occupancy + KPI cards via widgets). Redirect to/[portSlug]/dashboard./admin/settings(generic KV editor) → keep visible to all admins under System & observability.
Net effect: 7 domains instead of 6; 3 pages deleted (ocr, invitations, reports) instead of 2. Final IA in section 8.
Goal: today's 41 admin pages are organically grown and discoverability is poor (test-email lives on Branding, an SMTP test on Email, an OCR-settings duplicate exists on both /admin/ai and /admin/ocr, etc.). Below: page-by-page inventory + a recommended IA in 6 domains.
Out of scope here: the actual file moves, route redirects, and nav updates. That's Phase 2 (~4–6h once the IA below is locked).
1. Page-by-page inventory (current state, 41 pages)
Sorted alphabetically. Each row: what the page renders today + its current admin-sections-browser group.
| Route | What it renders | Current group |
|---|---|---|
/admin |
<AdminSectionsBrowser> — landing tile grid grouped into 5 categories |
— |
/admin/ai |
<RegistryDrivenForm> (ai master controls + provider credentials) + <OcrSettingsForm> + AI-suggestions card |
Operations |
/admin/audit |
<AuditLogList> — full mutation log search |
Data Quality |
/admin/backup |
<BackupAdminPanel> — backup posture (read-only) |
Operations |
/admin/berths/bulk-add |
<BulkAddBerthsWizard> — generate berth rows in bulk |
(not in landing browser) |
/admin/berths/reconcile |
<ReconcileQueue> — review berths missing required fields |
(not in landing browser) |
/admin/branding |
<RegistryDrivenForm sections={['branding']}> (identity) + email branding form + <PdfLogoUploader> + <EmailPreviewCard> |
Configuration |
/admin/brochures |
<BrochuresAdminPanel> — upload/version port brochures |
(not in landing browser) |
/admin/custom-fields |
<CustomFieldsManager> — per-entity custom-field definitions |
Content |
/admin/documenso |
<RegistryDrivenForm> (api creds, signers, templates, behavior) + <DocumensoTestButton> + <TemplateSyncButton> + <EmbeddedSigningCard> |
Configuration ("EOI signing service") |
/admin/duplicates |
<DuplicatesReviewQueue> — suspected-duplicate clients |
Data Quality |
/admin/email |
<RegistryDrivenForm> (from address + smtp) + <SmtpTestSendCard> + <TestTemplateCard> (new) + <SalesEmailConfigCard> + <EmailRoutingCard> |
Configuration |
/admin/email-templates |
<EmailTemplatesAdmin> — subject-line overrides per transactional template |
Content |
/admin/errors |
error-event list (system errors) | (not in landing browser) |
/admin/errors/codes |
error-code catalog reference | (not in landing browser) |
/admin/errors/[requestId] |
single error-event detail | (not in landing browser) |
/admin/forms |
<FormTemplateList> — public inquiry/intake form schemas |
Content |
/admin/import |
CSV import wizard | Data Quality ("Bulk Import") |
/admin/inquiries |
<InquiryInbox> — public-site submissions awaiting triage |
Data Quality |
/admin/invitations |
(empty body — comment says merged into /admin/users 2026-05-21) |
(not in landing browser) |
/admin/monitoring |
<SystemMonitoringDashboard> — BullMQ queue health |
Operations |
/admin/monitoring/[queueName] |
<QueueDetailTable> — single-queue drill-down |
(not in landing browser) |
/admin/ocr |
<OcrSettingsForm> — DUPLICATES the same form on /admin/ai |
(not in landing browser) |
/admin/onboarding |
<OnboardingChecklist> — cross-page setup checklist for new ports |
Operations |
/admin/pipeline-rules |
per-trigger berth-rules editor + <RegistryDrivenForm sections={['pipeline.auto-advance']}> |
Configuration ("Pipeline auto-advance") |
/admin/ports |
<PortList> — manage marinas (super-admin only) |
Operations |
/admin/pulse |
<RegistryDrivenForm sections={['pulse']}> — pulse chip tuning |
Configuration |
/admin/qualification-criteria |
<QualificationCriteriaAdmin> — lead-qualification rubric |
Operations |
/admin/reminders |
<RegistryDrivenForm sections={['reminders.defaults','reminders.digest']}> |
Configuration |
/admin/reports |
<ReportsDashboard> — saved analytics + ad-hoc queries |
Operations |
/admin/residential-stages |
<ResidentialStagesAdmin> + stage-template registry form |
Operations |
/admin/roles |
<RoleList> — role/permission matrix |
Access |
/admin/sends |
<SendsLog> — brochure + per-berth PDF send retries |
Data Quality |
/admin/settings |
<SettingsManager> — generic system_settings KV editor (escape hatch) |
Configuration ("System Settings") |
/admin/storage |
<StorageAdminPanel> — storage backend selector + migration |
Operations |
/admin/tags |
<TagList> — color-coded tags per entity |
Content |
/admin/templates |
<TemplateList> — PDF + email document templates (merge-field-driven) |
Content |
/admin/templates/[id]/editor |
per-template editor (PDF + email body) | (not in landing browser) |
/admin/users |
<UserList> + <InvitationsManager> (tabs, merged 2026-05-21) |
Access |
/admin/vocabularies |
<VocabulariesManager> — admin-editable enum lists |
Content |
/admin/webhooks |
<WebhookForm> + <WebhookDeliveryLog> + <WebhookSecretDisplay> |
Configuration |
/admin/website-analytics |
Umami creds form + <UmamiTestButton> |
Operations |
2. Issues identified
2.1 Duplicates
/admin/ocrduplicates/admin/ai— same<OcrSettingsForm>is mounted on both. The AI page is the source of truth (it also has the master AI switch + provider creds + AI-suggestions config). Recommendation: delete/admin/ocr+ add a redirect./admin/invitationsis dead — the page body is empty (per the comment, merged into/admin/users2026-05-21). Recommendation: delete the route + add a redirect to/admin/users?tab=invitations.
2.2 Misplaced cards
<EmailPreviewCard>is on Branding but tests email rendering — overlap with the new per-template tester on/admin/email. Recommendation: KEEP on Branding (it's a one-click "does the email LOOK right with current logo/colors?" affordance — that's a branding-validation concern, not a delivery test). Add a sibling link "→ Test individual templates" pointing at/admin/email.<SalesEmailConfigCard>is on/admin/email— correct home, but it's structurally identical to the noreply SMTP card above it (just a second mailbox). Recommendation: keep but reformat so both mailboxes are in matching cards stacked, with a shared "Test send" footer per mailbox.<EmailRoutingCard>is on/admin/email— actually it's a routing-rule editor (when X event fires, route through Y mailbox). Conceptually closer to a workflow rule than a credentials setting. Recommendation: keep on Email for now (the routing IS about email plumbing) but cross-link from Workflows since changing the rule changes behaviour.
2.3 Inconsistent naming
- "Documenso & EOI" page title implies EOI lives separately — but EOI generation is one of multiple Documenso flows. Recommendation: rename to "Signing service (Documenso)".
- "Bulk Import" vs
/admin/import— fine, but the page should explicitly say "Data import" (matches the page title<PageHeader title="Data import">). - "Send Log" vs
/admin/sends— fine; consider renaming the route slug to/admin/send-logfor clarity, but that costs cross-references.
2.4 Pages not in the admin-sections-browser tile grid
A bunch of pages exist as routes but aren't surfaced on /admin:
/admin/berths/bulk-add,/admin/berths/reconcile— only reachable from deep links inside the Berths page/admin/brochures/admin/email-templates,/admin/tags,/admin/vocabularies,/admin/custom-fields,/admin/forms— actually these ARE in the browser under "Content", verified/admin/qualification-criteria,/admin/residential-stages— under Operations/admin/errors,/admin/errors/codes,/admin/errors/[requestId]/admin/ocr(duplicate, recommended for deletion)/admin/invitations(dead, recommended for deletion)
Recommendation: surface every active page on /admin (no hidden surfaces — discoverability matters for admins). Move /admin/berths/bulk-add + /admin/berths/reconcile to a new "Berths admin" landing card.
2.5 Categories that don't quite fit
- "Content" is doing too much heavy lifting — it lumps tag color picker (visual), vocab enum lists (config), form templates (workflow), and document templates (mail merge). These are all things admins tune but their cognitive shape is different.
- "Data Quality" mixes inbound queues (Inquiry Inbox) with cleanup utilities (Duplicates, Bulk Import) — those serve different daily-workflows.
- "Operations" is the catch-all for "anything observability or infra-shaped" but also has things that are pure setup (AI configuration, residential pipeline stages).
3. Proposed IA — 6 domains, 38 pages
Two pages deleted (/admin/ocr, /admin/invitations), one moved out of admin entirely (/admin/reports — see below), one new sub-area (/admin/berths). Net page count: 41 → 38.
Domain 1. Brand & Communication (5 pages)
Everything about how outbound looks + which channel it ships on.
| Page | Action | Notes |
|---|---|---|
/admin/branding |
KEEP | Logo, colors, app name, email header/footer HTML, the visual "does it look right?" tester. |
/admin/email |
KEEP | SMTP creds (noreply + sales), routing, per-template tester, SMTP connectivity probe. |
/admin/email-templates |
KEEP | Subject-line overrides per transactional template. Stays separate from /admin/email because the audience is "copywriter" vs "ops". |
/admin/documenso |
RENAME → "Signing service" | API creds, signer identities, templates, behaviour. Page title currently says "Documenso & EOI" — drop "& EOI" (EOI is one of many doc types). |
/admin/webhooks |
KEEP | Outbound webhook subscriptions + delivery log. Sits here because webhooks are an outbound-comms channel, same conceptual bucket as email. |
Domain 2. Sales workflow (7 pages)
How the pipeline behaves end-to-end — triggers, scoring, templates.
| Page | Action | Notes |
|---|---|---|
/admin/pipeline-rules |
KEEP | Berth-rules engine triggers + auto-advance. |
/admin/pulse |
KEEP | Deal Pulse chip tuning. |
/admin/reminders |
KEEP | Default reminder behaviour + digest window. |
/admin/qualification-criteria |
MOVE FROM "Operations" → here | Lead-qualification rubric — clearly a sales-workflow concern. |
/admin/residential-stages |
MOVE FROM "Operations" → here | Residential pipeline shape. Same domain as the standard pipeline rules. |
/admin/forms |
MOVE FROM "Content" → here | Form templates drive lead intake — workflow input, not "content". |
/admin/templates |
MOVE FROM "Content" → here | Document templates carry merge fields tied to the pipeline (EOI, reservation, contract). These ARE pipeline artefacts. |
Domain 3. Catalog (4 pages)
Tenant-defined data shapes — values that get attached to records.
| Page | Action | Notes |
|---|---|---|
/admin/vocabularies |
KEEP | Admin-editable enum lists (berth_side_pontoon_options, lead_category, etc.). |
/admin/tags |
KEEP | Color tags. |
/admin/custom-fields |
KEEP | Per-entity field definitions. |
/admin/brochures |
MOVE FROM ungrouped → here | Brochure assets are catalog artefacts (per-port versioned PDFs). |
Domain 4. Identity & access (3 pages)
Who can use the system and what they can do.
| Page | Action | Notes |
|---|---|---|
/admin/users |
KEEP | Active users + invitations (already merged). |
/admin/roles |
KEEP | Role/permission matrix. |
/admin/ports |
KEEP | Super-admin only; per-port management. |
Domain 5. Inbox & data quality (6 pages)
Stuff that lands in admin queues + tools to clean up data.
| Page | Action | Notes |
|---|---|---|
/admin/inquiries |
KEEP | Public-site form submissions. |
/admin/sends |
KEEP | Brochure + per-berth-PDF send retries. |
/admin/duplicates |
KEEP | Suspected-duplicate review queue. |
/admin/import |
KEEP | CSV imports. |
/admin/berths |
NEW INDEX | Landing page that surfaces the two berth-admin tools below. |
/admin/berths/bulk-add |
MOVE FROM ungrouped → keep route, surface via /admin/berths | Bulk berth row generator. |
/admin/berths/reconcile |
MOVE FROM ungrouped → keep route, surface via /admin/berths | Berth-pdf reconciliation queue. |
(Counted as one Berths entry on the landing tile + the two existing routes as sub-pages.)
Domain 6. System & observability (10 pages)
Infra, observability, escape hatches.
| Page | Action | Notes |
|---|---|---|
/admin/audit |
KEEP | Mutation audit log. |
/admin/monitoring |
KEEP | BullMQ queue health. |
/admin/monitoring/[queueName] |
KEEP | Single-queue detail. |
/admin/errors |
SURFACE on landing | Error-event list (currently hidden from /admin tile grid). |
/admin/errors/codes |
KEEP as sub-page | Linked from /admin/errors. |
/admin/errors/[requestId] |
KEEP as sub-page | Linked from /admin/errors. |
/admin/backup |
KEEP | Backup posture. |
/admin/storage |
KEEP | Storage backend selector + migration. |
/admin/website-analytics |
KEEP | Umami creds. |
/admin/ai |
KEEP | AI config (master switch, providers, OCR settings, suggestions). |
/admin/settings |
KEEP | Generic KV editor (escape hatch for advanced flags). Stays in this domain because it's an admin-debug surface, not a normal-day setting. |
/admin/onboarding |
KEEP, FLOATS | Cross-cutting setup checklist. Stays accessible from /admin landing but doesn't belong in any single domain — it links to many. |
Out of admin entirely
| Page | Action | Rationale |
|---|---|---|
/admin/reports |
MOVE OUT → /[portSlug]/reports |
Reports are an end-user feature, not admin config. Today it lives in admin only because it's permission-gated; should be a top-level nav item with the same permission gate. Defer to a follow-up; for the IA pass, just stop surfacing it on /admin. |
Deleted
| Page | Action | Rationale |
|---|---|---|
/admin/ocr |
DELETE + 301 → /admin/ai |
Duplicate of /admin/ai. |
/admin/invitations |
DELETE + 301 → /admin/users |
Empty page; functionality merged 2026-05-21. |
4. Misplaced cards / sub-section moves
These are smaller-grained moves within the new IA — cards that should change page even though the routes stay put.
<EmailPreviewCard>(currently on/admin/branding) → KEEP on Branding (visual brand check); add a "→ Test individual templates" link pointing at/admin/email#test-template.<EmailRoutingCard>(currently on/admin/email) → KEEP on Email; cross-link from a "Routing rules" subsection of the new Workflow domain.<TemplateSyncButton>(currently on/admin/documenso) → KEEP; consider surfacing duplicate on/admin/templates(since "Sync from Documenso" populates template IDs there).<OnboardingChecklist>→ consider exposing a slim version as a banner on/adminlanding for ports that haven't completed setup.
5. Proposed /admin landing tile groups
The admin-sections-browser.tsx array should be rebuilt to match the 6 domains above. Sketch:
const SECTIONS: AdminSection[] = [
{
title: 'Brand & Communication',
description: 'How outbound looks and which channels it ships on.',
items: ['branding', 'email', 'email-templates', 'documenso', 'webhooks'],
},
{
title: 'Sales workflow',
description: 'Pipeline behaviour, scoring, document + form templates.',
items: [
'pipeline-rules',
'pulse',
'reminders',
'qualification-criteria',
'residential-stages',
'forms',
'templates',
],
},
{
title: 'Catalog',
description: 'Tenant-defined enums, tags, custom fields, and brochures.',
items: ['vocabularies', 'tags', 'custom-fields', 'brochures'],
},
{
title: 'Identity & access',
description: 'Who can use the system and what they can do.',
items: ['users', 'roles', 'ports'],
},
{
title: 'Inbox & data quality',
description: 'Admin queues + cleanup tools.',
items: ['inquiries', 'sends', 'duplicates', 'import', 'berths'],
},
{
title: 'System & observability',
description: 'Infra, observability, escape hatches.',
items: [
'audit',
'monitoring',
'errors',
'backup',
'storage',
'website-analytics',
'ai',
'settings',
],
},
];
Onboarding checklist surfaces above the grid (or as a banner on incomplete ports), not as a tile.
6. Phase 2 execution plan (~4–6h)
Once the above IA is approved (or amended), the migration is mechanical:
- Update
admin-sections-browser.tsxto the 6-domain shape above. (~30 min) - Delete
/admin/ocr+ addredirect()to/admin/ai. (~10 min) - Delete
/admin/invitations+ addredirect()to/admin/users. (~10 min) - Rename "Documenso & EOI" → "Signing service" (page title + landing label). (~5 min)
- Create
/admin/berths/page.tsxindex that surfaces bulk-add + reconcile. (~30 min) - Move
/admin/reportsout of admin — touches sidebar nav + landing browser + permission docs. Defer to its own task if scope creeps. (~1h) - Cross-link cards per section 4 (EmailPreviewCard → /admin/email link, etc.). (~30 min)
- Smoke pass — click every tile, confirm every page loads, every redirect lands. (~30 min)
- Audit doc update — mark B3 #10 SHIPPED in
alpha-uat-master.md. (~10 min)
Total: ~4 h plus ~1 h for the Reports move if we include it.
7. Open questions (resolved)
| # | Question | Decision |
|---|---|---|
| 1 | Forms + Document Templates placement | Moved to Sales workflow (not Content) |
| 2 | Webhooks placement | New "Integrations" domain (webhooks + documenso + website-analytics + ai) |
| 3 | AI configuration placement | Keep dedicated /admin/ai panel; lives under Integrations |
| 4 | /admin/reports |
DELETE entirely (duplicates dashboard); redirect to /[portSlug]/dashboard |
| 5 | /admin/settings (KV editor) visibility |
Keep visible to all admins under System & observability |
8. Final IA — 7 domains, 38 pages
After resolutions. Three pages deleted (/admin/ocr, /admin/invitations, /admin/reports); one new sub-area (/admin/berths index); one new domain (Integrations) split out from Brand & Communication.
Domain 1. Brand & Communication (3 pages)
How outbound LOOKS — visual and copy.
/admin/branding— logo, colors, app name, email shell HTML, EmailPreviewCard (visual check)/admin/email— SMTP creds (noreply + sales), routing, per-template tester, SMTP probe/admin/email-templates— subject-line + copy overrides per transactional template
Domain 2. Sales workflow (7 pages)
How the pipeline BEHAVES — triggers, scoring, templates.
/admin/pipeline-rules— berth-rules engine + auto-advance/admin/pulse— Deal Pulse chip tuning/admin/reminders— default behaviour + digest/admin/qualification-criteria— lead-scoring rubric/admin/residential-stages— residential pipeline shape/admin/forms— lead intake form templates (moved from Content)/admin/templates— document templates with merge fields (moved from Content)
Domain 3. Catalog (4 pages)
Tenant-defined data shapes that attach to records.
/admin/vocabularies— admin-editable enum lists/admin/tags— color tags/admin/custom-fields— per-entity field definitions/admin/brochures— per-port versioned PDF assets
Domain 4. Identity & access (3 pages)
/admin/users— active users + invitations (merged)/admin/roles— role/permission matrix/admin/ports— super-admin only, per-port management
Domain 5. Inbox & data quality (5 pages, 1 sub-index)
Admin queues + cleanup tools.
/admin/inquiries— public-site submissions/admin/sends— outbound send retry log/admin/duplicates— duplicate-client review queue/admin/import— CSV imports/admin/berths— NEW index page surfacing the two existing sub-tools:/admin/berths/bulk-add(bulk row generator)/admin/berths/reconcile(berth-pdf reconciliation queue)
Domain 6. Integrations (4 pages) — NEW DOMAIN
External-system + provider configuration.
/admin/documenso— signing service (rename from "Documenso & EOI" → "Signing service")/admin/webhooks— outbound subscriptions + delivery log/admin/website-analytics— Umami creds/admin/ai— dedicated AI panel consolidating master switch + provider creds + OCR settings + AI-suggestions config
Domain 7. System & observability (7 pages + 1 floating)
Infra, observability, escape hatches.
/admin/audit— mutation audit log/admin/monitoring— BullMQ queue health (+/admin/monitoring/[queueName]sub-page)/admin/errors— error-event list (+/admin/errors/codes+/admin/errors/[requestId])/admin/backup— backup posture/admin/storage— storage backend selector + migration/admin/settings— generic KV editor (escape hatch)/admin/onboarding— cross-cutting setup checklist (floats above the grid for incomplete ports)
Deleted
| Page | Action | Rationale |
|---|---|---|
/admin/ocr |
DELETE + 301 → /admin/ai |
Duplicate of /admin/ai's OcrSettingsForm |
/admin/invitations |
DELETE + 301 → /admin/users |
Empty page; merged into /admin/users on 2026-05-21 |
/admin/reports |
DELETE + 301 → /[portSlug]/dashboard |
Three widgets all already on the dashboard |
9. Phase 2 execution plan (~4-5 h)
Updated to reflect the resolved decisions. Reports move-out becomes a delete (simpler).
- Update
admin-sections-browser.tsxto the 7-domain shape above. (~45 min — 7 groups, ~30 tiles) - Delete
/admin/ocr+ addredirect()to/admin/ai. (~10 min) - Delete
/admin/invitations+ addredirect()to/admin/users. (~10 min) - Delete
/admin/reports+ addredirect()to/[portSlug]/dashboard. (~10 min) + remove from sidebar nav + landing browser. (~15 min) - Rename
/admin/documensopage title → "Signing service" (page title + landing tile label). (~5 min) - Create
/admin/berths/page.tsxindex page surfacing bulk-add + reconcile sub-tools. (~30 min) - Cross-link
<EmailPreviewCard>on Branding to add a "→ Test individual templates" link pointing at/admin/email#test-template. (~10 min) - Smoke pass — click every tile on the new
/adminlanding, confirm every page loads, every redirect lands. (~30 min) - Update
alpha-uat-master.mdBucket 3 #10 → SHIPPED with this proposal's commit hash. (~5 min)
Total: ~3.5-4 h.