Code quality plan, MR E: UI lint, leaks, and type drift

Phase E of the code quality action plan (https://gitlab.com/postgres-ai/database-lab/-/blob/docs/code-quality-action-plan/docs/plans/20260913-code-quality-assessment-action-plan.md). One MR, or two if 21b needs a separate sign-off.

Findings

  • only packages/ce/src is linted: 235 of 314 UI files never see ESLint; packages/shared has no eslint, no test runner, one devDependency
  • useWsScroll.tsx:36 uses the deprecated DOMNodeInserted event, so auto-scroll is dead in current browsers
  • Logs/index.tsx:216 opens a WebSocket with no cleanup
  • Instance/Configuration/index.tsx (1345 lines) deep-clones the config every render and feeds the clone into three dependency arrays
  • no error boundary anywhere in ui/
  • CloneDto lacks revision, deleteAt; metadata lacks logicalSize, maxIdleMinutes
  • 132 files carry a "Proprietary and confidential" header in an Apache-2.0 repo; shared/package.json and ce/package.json have no license field

Tasks

  • 17a. Shared ESLint base config; lint devDependencies and lint script in shared; CI runs pnpm -r lint
  • 17b. Vitest, happy-dom, testing-library in shared with a test script (ce uses Vitest, not Jest)
  • 18. MutationObserver with the existing tagName guard as a nodeName filter; socket closed on unmount
  • 19. Error boundary component in shared, wrapped around the ce root
  • 20. useMemo the clone; narrow the three dependency arrays to primitives
  • 21a. Sync CloneDto with models.Clone; formatter test
  • 21b. license field in both packages; header sweep in a separate commit. Needs maintainer sign-off: shared is published to npm, so this is a publishing-license change

Out of scope

  • MUI v4 → v5 consolidation and React 17 → 18: separate migration plan once the lint baseline exists