Dedupe rights, no-op security models when locked, validate title length
Hide deprecated play (and app/media) with case-insensitive matching
- Lowercase statusMap keys and lookups so verification aligns with API casing - Treat hidden infra labels case-insensitively - Strip deprecated labels from effe...
Read session rights as list or legacy CSV for member endpoints
KSessionService and SecurityRoleController store rights as List<String> of RoleRightType names. MemberSecurityController cast to String and split on comma, caus...
Verify-dns checks every KnownAliases label; skip deprecated app/media in optional
Security role save for locked roles and clearer API errors
- When isAllowEditSecurity is false, omit rights and securityModelIds from the PUT body so SecurityService accepts metadata-only updates (session timeout, d...
Proxy PATCH membership-type to SecurityService
The member profile UI called **************** but no App Router handler existed, so Next returned HTML 404 and the client showed Unknown error after failed JSON...
Persist RoleRightType by stable getId() instead of ordinal
Hibernate @Enumerated(EnumType.ORDINAL) writes/reads the declaration-index of the enum. When a RoleRightType value is removed (e.g. MANAGE_USERS, id=19), every ...
Avoid transaction-poisoning DDL and harden multi-pod races
The previous self-heal put DDL inside a @Transactional syncAll(). When an ALTER TABLE ADD CONSTRAINT fired on an existing constraint (normal case after first bo...
Drop stale CHECK constraints on default-role-rights enum columns
Hibernate auto-generates CHECK (column IN ('VAL1', 'VAL2', ...)) constraints on CREATE TABLE for @Enumerated(EnumType.STRING) columns, freezing the enum's value...
Add missing unique constraints for role-right upserts
**************** + syncSecurityModelRoleRights use `ON CONFLICT (role_id, right_type) DO NOTHING` and `ON CONFLICT (default_role_id, right_type) DO NOTHING`, wh...
Add unique constraint on (role_id, right_type) in OrgRoleRight
Required for ON CONFLICT DO NOTHING in **************** Without this constraint, the sync query fails with "no unique or exclusion constraint matching the ON CO...
Remove getType() calls from OrganizationController after OrganizationType removal
Stop overwriting member avatar with logged-in user's avatar on profile view
fetchAvatars fetched /api/security/avatars (no memberID scope — always returns the logged-in user's avatars) and called setActiveAvatar, clobbering the correct ...
Add missing sync-rights proxy route
POST /api/security/roles/sync-rights was missing a Next.js proxy handler, causing the Sync Rights button in Security Roles settings to always fail.
Use PublicChatVisitor displayName for requestorName on visitor tickets
Visitor-initiated tickets hardcode requestor to the org system member, so the DTO was surfacing the org owner's name in the Requestor column. Fall back to the P...
Gate Support/Settings by rights, fix Network copy, loading on tab switch, nav divider
- Network card: updated description to use dynamic branch title label - Support card: fixed 404 by changing href /help → /support; gated by isSupport + VIEW_SUP...
Support chat UX — name updates, titles, notification count, datagrid
- TicketChat fires onVisitorNameChanged when NAME_CHANGED WS event arrives - SupportTicketWindow dispatches tool:title with requestorName on load and on name ...
Render system events as friendly text in visitor support chat
NAME_CHANGED system events no longer show raw JSON in the chat bubble; they display as a centered italic pill ("Changes name to {name}"). Other system events ar...
Show AG Grid loading overlay instead of empty state on leads page
Initialize loading state to true so the grid shows "Loading leads..." until the first fetch completes, preventing a flash of "No leads found".
Use getOrganizationByIdWithFeatures in AppAvailabilityInterceptor
Resolves LazyInitializationException on /api/security/leads and all other CRM/POS-gated paths. The interceptor called org.getFeatures() after the transaction cl...
Add findByIdWithFeatures to eagerly load Organization.features
JOIN FETCH prevents LazyInitializationException when features are accessed outside a transaction (e.g. in AppAvailabilityInterceptor).
Build error in GeoLookupService and add NATS publish for agent messages
- Fix Optional vs List type mismatch in **************** - Inject NatsMessageService into MediaController - Publish to chat.session.{guid} after agent creates a...
Correct message sides in history and handle visitor name change events
- Use messageType=VISITOR_MESSAGE from API to determine left/right in history load - Add NAME_CHANGED system event rendering in SystemMessage and TicketChat
Real-time chat delivery, message sides, notifications, and name sync
- Keep NATS subscription alive on client unsubscribe to avoid breaking agent real-time delivery - Tag visitor messages with messageType=VISITOR_MESSAGE in getMe...
**************** uses instanceof for MEMBER type
Hibernate TYPE(m) = :type returns 0 results when bound to the base Member class in JOINED inheritance. For MEMBER type, fetch all and filter with !(m instanceof...
Resolve Members tab showing empty due to Hibernate TYPE() base-class issue
Hibernate's TYPE(m) = :type JPQL filter returns 0 results when the bound parameter is the base Member class (JOINED inheritance). This affects the members-subsc...
Tag visitor messages as VISITOR_MESSAGE type, add senderName to GET messages
- PublicChatService: set messageType=VISITOR_MESSAGE so frontend can distinguish visitor echoes from agent responses on the STOMP topic - MediaController.getM...
Treat VISITOR_MESSAGE type as always-from-them in TicketChat
Visitor messages published via PublicChatService carry messageType=VISITOR_MESSAGE. Explicitly mark these as author='them' regardless of memberId so they always...
Skip VISITOR_MESSAGE echoes in LiveSupportPanel STOMP handler
Visitor messages are now tagged messageType=VISITOR_MESSAGE by the backend. Skip these in the STOMP subscription so the visitor's own messages don't re-appear o...
Wire up status filter and auto-seed required templates on list
- EmailTemplateController.list() now accepts ?status= param and filters using the existing findByOrgIdAndStatus repository query - Auto-seeds required templat...
Three support/chat issues — NATS relay, auto-popup, topic fallback
1. Switch SupportNotificationService and SupportStompRelayController from JetStream to core NATS — the CHAT_MESSAGES stream only covers chat.> so JetStrea...
Allow god-mode users to provision ownerless orgs; prefer FQDNs in domain resolution
Always trigger provision-theme on branding save; let backend resolve domain server-side
Add @Transactional to provision-theme for lazy domain loading; remove hardcoded domain from provision request
Write contact form description as chat message on public ticket creation
The description was only stored on the ticket entity and never appeared in the chat window. Added writeTextMessage() helper and call it after the system event s...
Separate ticket number/badges row from title in TicketHeader
Title was sharing a nowrap flex row with the ticket number and two badges, causing it to be cut off. Now ticket number and badges occupy their own compact row, ...
Handle tickets key in support ticket list response
MediaService returns { tickets: [...], totalElements } but the frontend only checked for data.content, causing the list to always render empty.
Use PATCH /org/{id}/colors for branding save to avoid nullable boolean constraint failure
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
