Skip to content

Document-field TipTap — Production Readiness Audit ​

FieldValue
Date2026-10-03
StatusGo for production after companion PR merge + migrate-first Backend + SPA/Mobile/Docs deploy + staging smoke
ScopeShared TipTap RichTextEditor on document bodies only: announcements body, Help Desk ticket description, task/project description, activity body. Not notes, chat, addresses, SMS/WhatsApp templates, or automation JSON.
Catalogannouncements 1.1.0 → 1.2.0 · help-desk 1.10.0 → 1.11.0 · tasks 1.6.0 → 1.7.0 · projects 1.6.0 → 1.7.0 · activities 1.1.0 → 1.2.0
CompanionAnnouncements · Help Desk · Tasks · Projects · CHANGELOG · Upgrade

Executive summary ​

Workspace document fields that people re-read (announcements, ticket descriptions, task/project descriptions, activity bodies) now use the existing Knowledge Base TipTap editor. HTML is stored as a string (Knowledge Base pattern — not billing DocumentHtmlSanitizer, which strips style and would drop text color). The SPA sanitizes with DOMPurify before dangerouslySetInnerHTML. Snippets, dashboard previews, notifications (strip_tags), and mobile Text use plain text.

Platform freeze is intact: no new shell, auth, or settings store. File a complaint stays a short textarea (plain text still round-trips into the HTML viewer).

Go / No-Go: Go.

GateResult
Editor reuse (RichTextEditor) — no new packagePass
Display never unsanitized HTMLPass (A1, A4)
TipTap text color survives display sanitizePass (A1)
Unsafe javascript: / data: link insert blockedPass (A2)
Empty <p></p> not treated as contentPass (A3)
Catalog MINOR migrate-only (no db:seed)Pass
Pest HTML store + catalog bumpPass
Vitest sanitize helpersPass
Docs user / API / developer / CHANGELOG / navPass
Mobile TipTapOut of scope — strip tags on view/edit
File a complaint TipTapOut of scope (short note)

Audit findings (initial → remediated) ​

IDSeverityFindingRemediation
A1HighsanitizeKnowledgeBaseHtml omitted style, so TipTap text color (inline span style) vanished on view even though it stored.ADD_ATTR: ['target', 'style']. DOMPurify still strips scripts and javascript: hrefs.
A2MediumLink toolbar accepted any href (javascript:, data:).isSafeRichTextHref — http / https / mailto / same-origin path. Display sanitize remains a second gate.
A3MediumRichTextHtml treated <p></p> as content; Help Desk gated on raw ticket.description.Empty check uses htmlToPlainText.
A4MediumInbox/view/dashboard could have shown raw tags before this ship.RichTextHtml on full bodies; htmlToPlainText / htmlSnippet on previews.
A5MediumAutomationEngineSupportTest still expected payments 1.4.0 while CatalogSeeder is 1.5.0 — CI fail once this file is in the PR.Companion map 1.5.0.
A6LowMissing production-readiness page / VitePress / upgrade row.This page + sidebar + upgrade + changelog link.
I1InfoFile a complaint description remains a textarea.Accepted — short dialog; stored plain text renders via RichTextHtml.
I2InfoMobile create/edit stay FormTextarea; HTML from web is stripped for display.Accepted (plan).
I3InfoLIKE search can match HTML tags.Accepted — same as Knowledge Base.

No High or Medium open residuals for ship.


Security summary ​

ControlStatus
No new auth / tenancy / billingPass
HTML render only after DOMPurifyPass
Scripts / forms / iframes forbidden on document HTMLPass
Link insert allow-listPass
Notifications already strip_tags on announcement bodyPass
Tenant isolation unchangedPass

Change inventory ​

Backend ​

  • Migration 2026_10_03_182400_bump_document_rich_text_module_versions — five MINOR catalog bumps
  • CatalogSeeder versions aligned
  • Pest: announcement + Help Desk HTML store; catalog bump test; Automation companion versions

Frontend ​

  • RichTextHtml + htmlToPlainText / htmlSnippet
  • Forms: announcements, Help Desk, tasks, projects, activities
  • Display: view pages, announcement inbox, dashboard snippet, peeks
  • Playwright fillRichText helper
  • Vitest src/lib/sanitize-html.test.ts

Mobile ​

  • lib/html.ts htmlToPlainText on announcement/task/project/help-desk/activity view and edit load

Docs ​

  • User / API / developer guides; CHANGELOG; this audit; upgrade; VitePress

Test evidence ​

herd php artisan test --compact tests/Feature/Central/Catalog/DocumentRichTextModuleVersionBumpTest.php
herd php artisan test --compact --filter=HTML tests/Feature/Tenant/Announcement/AnnouncementTest.php tests/Feature/Tenant/HelpDesk/HelpDeskTicketTest.php
npm run test:unit -- src/lib/sanitize-html.test.ts

vendor/bin/pint --dirty --format agent on Backend PHP changes.

Playwright: test:e2e:announcements, test:e2e:help-desk, test:e2e:tasks, test:e2e:projects (and activities if the suite fills body) after SPA deploy.


Upgrade & staging smoke ​

  1. Deploy Backend and run php artisan migrate --force (2026_10_03_182400_bump_document_rich_text_module_versions). Do not db:seed.
  2. Confirm catalog: announcements 1.2.0, help-desk 1.11.0, tasks 1.7.0, projects 1.7.0, activities 1.2.0.
  3. Deploy Frontend, then Mobile (OTA) and Docs.
  4. Staging:
    • Create a published announcement with heading, list, link, and red text → inbox dialog + record page render HTML (not tags); dashboard snippet is plain text; second user notification preview has no tags.
    • Edit a Help Desk ticket / task / project / activity description in TipTap → view page shows lists; peek snippet has no <p>.
    • Existing plain-text rows still load in the editor and display as text.
    • File a complaint still uses a textarea.
    • Mobile announcement/task view shows text without tags.

Rollback ​

Revert SPA first (stops HTML authoring). Catalog bump is display-only SemVer — leaving it is harmless. Stored HTML remains valid strings; a reverted SPA would show tags until re-deployed.

Sign-off ​

RoleResult
EngineeringGo after companion CI
OperatorStaging smoke above before production traffic

Official documentation for the EloSync SaaS Platform.