fix: address PR review feedback on user theme preferences
Security:
- Add CSS injection guard to ThemeSwatchPreview (rejects values containing
; < }) matching the pattern already used in admin-themes.tsx
Error handling:
- Split network/JSON try blocks in preview, GET themes list, POST policy
fetch — SyntaxError from res.json() is a data error, not a code bug,
and must not be re-thrown via isProgrammingError
- Promote logger.warn → logger.error for themes list fetch failure
- Add logger.warn to preview endpoint catch block (was silently swallowing
AppView failures)
User-facing:
- Map ?error= codes to friendly messages; drop unknown codes (phishing
vector for crafted URLs showing raw internal codes like "invalid-theme")
Tests:
- Add getSetCookie absence assertions to allowUserChoice:false and
invalid-theme POST rejection tests
- Update ?error=invalid-theme GET test to verify friendly message in
settings-banner--error element
- Add tests for themes list non-ok response and network throw paths
- Add test for unknown ?error= code producing no banner
Docs:
- Align theme-resolution.ts internal section comments to use descriptive
headings instead of "Step N" (conflicted with JSDoc 5-step waterfall)
- CLAUDE.md: clarify settings routes bypass ThemeCache intentionally