docs: comprehensive audits + Documenso build plan + admin UX backlog
Six audit documents capture the 2026-05-06 review pass (comprehensive, frontend, missing-features, permissions, reliability) along with the Documenso integration audit + locked build plan that drove the bulk of subsequent feature work. Adds `docs/admin-ux-backlog.md` as a living tracker for the autonomous push — every item marked DONE or REMAINING with file pointers and scope estimates so future sessions can pick up where this one stopped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
196
docs/admin-ux-backlog.md
Normal file
196
docs/admin-ux-backlog.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# Admin / settings UX backlog — STATUS
|
||||
|
||||
Living tracker for the admin/UX backlog. Items are marked DONE or
|
||||
REMAINING based on what landed in the autonomous-push session.
|
||||
|
||||
---
|
||||
|
||||
## DONE in the autonomous push
|
||||
|
||||
### Foundations
|
||||
|
||||
- **Currency API verified end-to-end**. `scripts/test-currency-api.ts`
|
||||
fetches live Frankfurter rates → upserts → reads back → converts.
|
||||
Inverse-rate drift confirmed at ≤0.001.
|
||||
- **Storage abstraction audit complete**. Every byte path
|
||||
(signed EOIs, contracts, brochures, berth PDFs, files, avatars,
|
||||
branding logos) goes through `getStorageBackend()`. `/api/ready`
|
||||
and the system-monitoring health probe now check the active
|
||||
backend (S3 or filesystem) instead of always probing MinIO.
|
||||
|
||||
### User settings
|
||||
|
||||
- Country + Timezone selectors with cross-defaulting + auto-detect
|
||||
banner ("Looks like you're in Europe/Paris — Update?")
|
||||
- Email change with verification flow (`user_email_changes` table,
|
||||
`/api/v1/me/email/confirm/<token>`, `/api/v1/me/email/cancel/<token>`)
|
||||
- Password reset triggered via better-auth `requestPasswordReset`
|
||||
- Profile photo upload + crop (square 256×256) via shared
|
||||
`<ImageCropperDialog>` + `/api/v1/me/avatar`
|
||||
|
||||
### Branding
|
||||
|
||||
- Logo upload + crop modal in admin/branding (uses the same shared
|
||||
cropper, persists via `/api/v1/admin/settings/image` → storage backend)
|
||||
- Email header/footer HTML defaults injectable via "Insert default" button
|
||||
- Brand colour picker, app-name field, logo URL all in one card
|
||||
|
||||
### Storage admin
|
||||
|
||||
- New layout: S3 config form FIRST, swap action SECOND
|
||||
- Test connection button before any switch
|
||||
- Two-button switch: "Switch + migrate" vs "Switch only" with warning modal
|
||||
- `runMigration()` honours `skipMigration` flag
|
||||
|
||||
### Backup management
|
||||
|
||||
- Real `/admin/backup` page driven by new `backup_jobs` table
|
||||
- `runBackup()` service spawns `pg_dump --format=custom`, streams to
|
||||
active storage backend, records size + path
|
||||
- Download button presigns the .dump for offline restore
|
||||
- Super-admin gated
|
||||
|
||||
### AI admin panel
|
||||
|
||||
- Dedicated `/admin/ai` page consolidating master switch +
|
||||
monthly token cap + provider credentials
|
||||
- Per-feature settings (OCR, berth-PDF parser, recommender)
|
||||
linked from the same page
|
||||
|
||||
### Onboarding
|
||||
|
||||
- Real `/admin/onboarding` page with auto-checked steps
|
||||
- Reads each setting key + lists endpoint (roles / users / tags) to
|
||||
decide completion
|
||||
- Manual checkboxes for steps without an auto-detect signal
|
||||
- Progress bar + "Mark done"/"Mark incomplete" buttons
|
||||
- State persisted in `system_settings.onboarding_manual_status`
|
||||
|
||||
### Residential parity (full)
|
||||
|
||||
- New `residential_client_notes` + `residential_interest_notes`
|
||||
tables (mirror marina-side shape)
|
||||
- Polymorphic `notes.service.ts` extended with two new entity types
|
||||
through verifyParent + listForEntity + create + update + delete
|
||||
- New `<NotesList>` accepts `residential_clients` /
|
||||
`residential_interests` entity types
|
||||
- Activity endpoints: `/api/v1/residential/clients/[id]/activity` +
|
||||
`/api/v1/residential/interests/[id]/activity`
|
||||
- Notes endpoints: 4 new routes covering GET/POST/PATCH/DELETE
|
||||
- `residential-client-tabs.tsx` + `residential-interest-tabs.tsx`
|
||||
built using the marina-side `DetailLayout` pattern (Overview +
|
||||
Notes + Activity tabs, Interests tab on the client)
|
||||
- Detail header components mirror the marina-side strip
|
||||
- `useBreadcrumbHint` wired into both detail components
|
||||
|
||||
### Residential pipeline stages — configurable
|
||||
|
||||
- New `residential-stages.service.ts` with list/save + orphan-check
|
||||
- `/api/v1/residential/stages` GET/PUT
|
||||
- `/admin/residential-stages` admin UI with reassign-on-remove
|
||||
modal (select new stage per affected interest before save)
|
||||
- Validators relaxed from `z.enum(...)` to `z.string()` so any
|
||||
admin-defined stage id round-trips
|
||||
|
||||
### Documenso Phase 1 (EOI generate flow polish)
|
||||
|
||||
- Schema migrations applied:
|
||||
`document_signers.invited_at / opened_at / last_reminder_sent_at / signing_token`,
|
||||
`documents.completion_cc_emails / auto_reminder_interval_days`
|
||||
- `transformSigningUrl()` now maps SignerRole → URL segment correctly
|
||||
(approver→cc, witness→witness) so emails don't land on `/sign/error`
|
||||
- New `POST /api/v1/documents/[id]/send-invitation` endpoint with
|
||||
next-pending-signer auto-pick
|
||||
- Per-port settings added: `documenso_developer_label`,
|
||||
`documenso_approver_label`, `documenso_developer_user_id`,
|
||||
`documenso_approver_user_id` (Phase 7 RBAC binding fields)
|
||||
|
||||
### Misc UI/UX
|
||||
|
||||
- Sidebar collapse removed (always expanded)
|
||||
- Audit log filter inputs sized + dates widened
|
||||
- Custom Settings section got a long-form description
|
||||
- Reminder digest timezone uses `TimezoneCombobox`
|
||||
- Port form: currency dropdown + timezone combobox + brand color
|
||||
- Permissions count badge opens a modal with granted/denied
|
||||
- Role names display-normalized via `prettifyRoleName`
|
||||
- Sales email config: token list + tooltips on threshold + body fields
|
||||
- Custom Fields page: amber heads-up about non-integration with
|
||||
search / recommender / audit / merge tokens
|
||||
- Tag form: native `<input type="color">`
|
||||
- FilterBar Select crash fixed (no empty-string item values)
|
||||
|
||||
---
|
||||
|
||||
## REMAINING — large pieces that didn't fit this push
|
||||
|
||||
### 1. Documenso Phase 2 — Webhook handler enhancement (~3-4 hours)
|
||||
|
||||
Cascading "your turn" emails when each signer completes; on-completion
|
||||
PDF distribution; token-based recipient matching; idempotency lock.
|
||||
File to extend: `src/app/api/webhooks/documenso/route.ts`. The
|
||||
schema columns are already in place (Phase 1).
|
||||
|
||||
### 2. Documenso Phase 3 — Custom doc upload-to-Documenso (~6-8 hours)
|
||||
|
||||
Backend service `custom-document-upload.service.ts` + endpoint
|
||||
`POST /api/v1/interests/[id]/upload-for-signing`. Accepts a PDF +
|
||||
recipient list + field-placement JSON, calls `createDocument` →
|
||||
`placeFields` → `sendDocument` on the per-port Documenso client.
|
||||
Persists a row in `documents` table.
|
||||
|
||||
### 3. Documenso Phase 4 — Field placement UI (~10-14 hours)
|
||||
|
||||
The biggest piece. Needs:
|
||||
|
||||
- 4a: Recipient configurator dialog (~2-3h)
|
||||
- 4b: PDF rendering with `react-pdf` (~3-4h)
|
||||
- 4c: Auto-detect anchor scanner via `pdfjs-dist.getTextContent` (~4-6h)
|
||||
- 4d: Drag-drop overlay using `dnd-kit` (~3-4h)
|
||||
- 4e: Send button → calls Phase 3 endpoint (~1h)
|
||||
|
||||
Plan locked in `docs/documenso-build-plan.md` Phase 4 — the
|
||||
field-detector regexes, the anchor patterns, and the type-to-bbox
|
||||
sizing table are all spelled out.
|
||||
|
||||
### 4. Documenso Phase 5 — Embedded signing URL emission verification (~1-2 hours)
|
||||
|
||||
Verify the website's `/sign/<type>/<token>` page handles every signer
|
||||
role + every documentType combination. Update website's
|
||||
`signerMessages` map keyed on `(documentType, role)`. Apply the
|
||||
nginx CORS block from `docs/documenso-integration-audit.md`.
|
||||
|
||||
### 5. Documenso Phase 6 — Polish items (deferred)
|
||||
|
||||
Auto-send delay, audit-log additions, per-document customisation,
|
||||
document expiration, reminder rate-limit display, failed-webhook
|
||||
recovery UI. Each ~2-3 hours; all deferred until Phases 1-4 ship.
|
||||
|
||||
### 6. Project Director — UI binding for the developer-user fields
|
||||
|
||||
Schema + setting keys are now in place
|
||||
(`documenso_developer_user_id`, `documenso_approver_user_id` +
|
||||
`documenso_developer_label` / `_approver_label`). The remaining
|
||||
work is: add a "Linked to CRM user" dropdown in
|
||||
`/admin/documenso/page.tsx` that lists port users; when bound,
|
||||
auto-fill name/email from the user profile and mark name/email
|
||||
fields read-only. Webhook handler can then match against the
|
||||
linked user's email for in-CRM signing-status updates.
|
||||
|
||||
### 7. Custom-fields hardening (~ongoing)
|
||||
|
||||
Remediation paths for the heads-up banner concerns:
|
||||
|
||||
- **Search index**: extend the GIN tsvector to include
|
||||
customFieldValues content
|
||||
- **Audit diff**: extend `diffEntity` to walk the
|
||||
customFieldValues blob
|
||||
- **Merge tokens**: add `{{custom.<fieldName>}}` handling at
|
||||
template-render time, plus surface them in the merge-tokens UI
|
||||
|
||||
### 8. Documenso v2 webhook payload audit (small)
|
||||
|
||||
Risk #4 from `docs/documenso-build-plan.md` — confirm v2 payload
|
||||
shape (`payload.documentId` vs `payload.id`, recipient.token vs
|
||||
`recipient.recipientId`) against a live v2 instance before relying
|
||||
on Phase 2 cascading emails.
|
||||
Reference in New Issue
Block a user