Use outer SettingsView help panel on email provider config page
Push provider-specific help to HelpTipsOverrideContext so the config view uses the same Help & Tips panel layout as the list view, instead of rendering its own ...
Rename email nav sub-item from General to Provider Setup
Uses namespaced key Email - Provider Setup to avoid collision with the existing AI Provider Setup route entry.
Remove duplicate JPA repo scan — use parent package only
com.kamo.z.shared.email covers metadata.repos, scanning both caused BeanDefinitionOverrideException on messageLabelRepository.
Reorder source dropdown, default to user, use team member label
- Default scope changed from "company" to "user" - Dropdown order reversed: Team Members first, Department, then org - "Individual User" renamed to the parent o...
Remove placeholder text from preview, allow sending without subject
- Empty email body in preview no longer shows "Start typing your email..." - Subject is no longer required to send — Send button is enabled with just a recipi...
Template dropdown fills remaining width, other controls right-aligned
The template source dropdown now has flex:1 to fill all remaining space. Edit/Preview toggle, attach button, Draft, and Send buttons are right-aligned with flex...
Wrap email body in template HTML when sending
The send handler was sending raw editor content without the template. Now wraps the body in the full template layout (far bg, margin, near bg, padding, header, ...
Remove horizontal scrollbar and extend preview to full height
- Use padding on the outer far-bg div instead of margin on the inner near-bg div to prevent width:100% + margin overflow - Set overflowX:hidden on the preview...
Repopulate member/org data when switching source scope
The sync ref was set once and never reset, so switching scope left the new scope's config with empty content fields (empty names, email, company, etc.) causing ...
Move template dropdown, preview toggle, and attach to footer row
Move template scope dropdown, Editor/Preview toggle, and attachment button from the subject row to the bottom footer bar, aligned left. Draft and Send buttons s...
Fetch member/org data directly instead of through hooks
Removed useUserInfo, useSignatureData, and useImageResolver hooks which each had independent async fetch cycles causing race conditions where memberId/orgId wer...
Use example data in email preview when member/org data not loaded
The preview was rendering empty signatures because member/org data from useSignatureData returns empty strings while loading (or when memberId/orgId are 0). Now...
Always render template preview even without saved backend template
When no template is saved in the backend (404), fall back to DEFAULT_CONFIG instead of showing plain unformatted content. The preview now always renders with at...
Re-render templates client-side with real data in email preview
The preview was showing placeholder text ({{member.firstName}} etc.) because it used the pre-rendered placeholder HTML from the backend. Now the MessageTool: -...
Add rspamd config to K8s ConfigMap and set ddl-auto to none
The rspamd.base-url property was missing from the production ConfigMap, causing CrashLoopBackOff on deploy. Also corrects dev ddl-auto to none.
Simplify source selector, add dirty tracking and unsaved changes dialog
- Remove department/user sub-type selectors — templates are org-level for the organization, all departments, and all users - Remove the avatar icon to the lef...
Move Live Preview label into email header bar, remove Copy HTML button
Live Preview title and icon now sit right-aligned inside the To/Subject header bar. Removed the Copy HTML button and all clipboard logic.
Move source selector into builder header, 2-col templates, wider preview
- Move Source dropdown from top card into the builder panel header bar (matching the Live Preview title position) - Remove Undo and Reset buttons entirely - C...
Prevent live preview panel from overflowing right edge
Change builder and preview panels from fixed flex-basis (55%/45%) to shrinkable flex so the gap between them is properly accounted for.
Use richTextExtension.configure() instead of RichTextExtension class
RichTextExtension class is not exported from the published @lexkit/editor package. Use the exported richTextExtension instance with .configure().
Remove duplicate ContentEditable — use RichTextExtension's plugin
The richTextExtension already renders its own ContentEditable via RichTextPlugin. Having a second manual ContentEditable created two editable areas. Remove the ...
Overhaul KB editor and article page layouts
Fix editor component: - Wrap in flex column container so toolbar stays fixed and content area scrolls independently - Use position:relative on content wrapper...
Add search request/response logging to RagSearchController
Log orgId, query, result count, and full stack traces on error to diagnose 500 responses seen from AIService.
Add response body and request logging to RagClient for debugging
Log the RAG search request URL, orgId, query, and response body on error to diagnose 500 responses from RAGService.
Enable auto-truncate on embedding model to prevent 413 errors
Add --auto-truncate flag so inputs exceeding the 256 token limit are silently truncated instead of rejected with a validation error.
Reduce chunk size to fit all-MiniLM-L6-v2 token limit (256 max)
Chunk target was 2000 chars (~512 tokens) but the embedding model only accepts 256 tokens, causing 413 validation errors. Reduce to 800 chars (~200 tokens) with...
Load embedding model from local hostPath to prevent HuggingFace download failures
The embedding-model pod was in CrashLoopBackOff because it couldn't download the model from HuggingFace on startup (network/DNS issue). Mount the model from a h...
Use integer match filter for Qdrant searches instead of matchKeyword
The orgId and articleId payload fields are stored as integers via value(Long), but search and delete filters used matchKeyword() which only matches string/keywo...
Index KB articles for RAG on creation, not just when published
Previously the RAG pipeline only indexed PUBLISHED articles, requiring the full review/approval cycle before the AI chat could reference them. Now indexes all a...
Update reviews page to match enriched backend response fields
Use uid as key, articleGuid for navigation, articleTitle for display, and dateSubmitted for date. Matches the new backend response format that includes article ...
Return article guid/title in pending reviews response
The KbArticleReview entity has @JsonIgnore on article, so the pending reviews endpoint was returning reviews without article details (guid, title). Now uses eag...
Surface actual backend error messages in article create/edit
Read errData.error (matching backend JSON format) instead of errData.message. Fix proxy to forward backend JSON errors directly instead of double-wrapping them ...
Add error handling to createArticle endpoint
Wrap createArticle call in try-catch to return proper JSON error responses instead of Spring Boot's default HTML error page.
Add missing richTextExtension to enable editor text input
The RichTextPlugin from richTextExtension is required for the Lexical is silently ignored.
Add shared KB layout with persistent tabs and fix reviews page error
Create app/kb/layout.tsx with KbNavBar tabs shared across Articles, Resources, and Pending Reviews pages. Remove duplicate outer shells and fixed positioning fr...
Update navtop email badge when message is marked as read
Dispatch email:folder-changed event after marking a message as read, so MailButton re-fetches the unread count immediately.
Revert email WebSocket URL to same-origin Next.js rewrite path
Use /email-ws on same origin, proxied by Next.js rewrites to EmailService via k8s internal DNS. SockJS HTTP fallbacks (xhr-streaming, xhr-polling) work through ...
Remove hardcoded WebSocket headers from email middleware
Traefik v3 handles WebSocket Upgrade/Connection headers natively. Hardcoding them broke SockJS fallback transports (xhr-streaming, xhr-polling). Now matches med...
Connect email WebSocket directly to email.{domain} subdomain
Next.js rewrites cannot upgrade HTTP connections to WebSocket, causing the STOMP connection to silently fail after 3 retries. Now uses the same direct subdomain...
Auto-cert service not renewing expired SSL certificates
The auto-cert service was importing expired certs from shared storage and skipping Certificate CR creation, so cert-manager couldn't manage renewals. Also fixed...
Add 30s polling fallback for real-time email updates when WebSocket is unavailable
The WebSocket connection silently fails after 3 retries, leaving the UI permanently stale. This adds a 30-second polling interval as a reliable fallback across ...
Rename Team button to Chat Now and change panel to click-only activation
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.