Partial-unique index enforcing one active closing package per loan (eClose double-close backstop)
CREATE UNIQUE INDEX uk_mlos_closing_pkg_active_loan ON mlos_closing_package (loan_file_uid) WHERE status <> 'CANCELLED'. Durable backstop behind the assembler's...
Thumbnail scheduled-generated materials in-process
A headless sweep can't drive ConversionService's OTK thumbnail pipeline, so generate a page-0 PNG thumbnail via ImageIO right after storing the export — schedul...
Recurring generation schedules UI
ScheduleManager: create/list/delete schedules (recipe + daily/weekly/monthly + hour/day + optional auto-post targets + caption); launched from Materials, gated ...
Scheduled generation — sweep runs recipes on a cadence
- CanvaScheduleController: CRUD for org schedules (recipe + cadence + hour/day + optional social targets), computes nextRunAt - CanvaGenerationService: headle...
CanvaSchedule entity + repo (recurring generation)
Org-scoped recurring schedule (recipe + cadence + optional social targets) with an atomic-claim query so a MediaService sweep runs each due schedule once.
Inline expandable Whisper transcript on softphone voicemail + call-history rows
Each recorded row (voicemail and call history) gets a 'Transcript' toggle that fetches the recording's Whisper transcript on demand and shows it inline, so memb...
Save + reuse autofill recipes
TemplateAutofill: "Saved recipes" chips load a template + prefilled mapping; "Save as recipe" persists the current template + field values org-wide. + canvaApi ...
Saved autofill recipes CRUD (org-scoped)
CanvaRecipeController: GET/POST /api/media/canva/recipes + DELETE /{id} — save/list/soft-delete a named brand-template + field mapping, scoped to the caller's o...
CanvaAutofillRecipe entity + repo (saved autofill recipes)
Org-shared named binding of a Canva brand template to field values (literal text or a Materials image), so stewards can re-run a standard data-merge.
Add Material ID field to create form, details page, and imports
Threads a nullable materialId (max 40) through the Lead type, leadsApi (create + update wire requests), and the shared leadFields system-field list — which driv...
Enterprise autofill UI — data-merge brand templates
TemplateAutofill: pick a Canva brand template, fill each field with literal text, an org/compliance token (NMLS #, Equal Housing disclosure, org name/phone/ web...
Enterprise autofill — data-merge brand templates
- CanvaApiClient: list brand templates (dataset=non_empty), get dataset, asset-upload jobs, create/get autofill jobs - CanvaController: GET /brand-templates, ...
Persist mapped Material ID on manual import + API intake
Both setDirectFieldOnCreateRequest switches lack a default case, so an unmapped systemFieldPath is silently dropped. Add a materialId case to the manual-import ...
Add Material ID field end-to-end in shared-lib
Adds a nullable, max-40-char materialId to the Lead entity (MATERIAL_ID VARCHAR(40)), registers it in LeadHistoryFieldRegistry (Profile category) so edits are a...
Social attach + email-a-material + public links
Distribution for marketing materials, built on the new signed public-URL seam. - materialsApi.publicLink(imgId) + /api/materials/link proxy - Materials: "Copy ...
Short-lived signed public URLs for marketing assets
Lets social providers (Meta) and email fetch a specific material for a bounded window without exposing the private imaging-materials bucket. - MaterialUrlSigne...
First-class borrower self-submit transition ****************
DRAFT→APPLICATION_TAKEN for a borrower (a loan party, not an operator, so no LOS_TAKE_APPLICATION). Routes through transition() with a scoped predicate that gra...
Delete + preview + import-file-to-Canva
- delete a material (gated on MANAGE_MATERIALS) with confirmation - click a thumbnail to preview it in a lightbox - "Import a file" turns a PDF/PPTX/image into ...
Import a file into Canva as an editable design
- **************** (binary design import) - CanvaController POST /imports (multipart) → create+poll import job → editor deep-link with correlation_state for r...
Shared TranscriptionService + generic endpoint; transcribe VOIP recordings
- Extract a reusable TranscriptionService (ffmpeg normalize -> whisper-asr) and a generic POST /api/conversion/transcribe endpoint, replacing the meet-specifi...
Transcript column on Recording + RecordingMetadata
Adds a TRANSCRIPT TEXT column to the Recording entity and threads a transcript through **************** (with backwards-compat constructors so existing 5- and 9...
Verify return-nav JWT signature; tidy token refresh
- CanvaJwtVerifier: verify the correlation_jwt's Ed25519 signature against Canva's JWKS (/connect/keys), plus aud/exp/type; keys cached by kid. Return-nav n...
Make whisper-asr independently scalable (HPA, multi-node)
Remove the single-node pin and switch to a per-pod model cache so pods can schedule on any node, and add an HPA (min 1 / max 4, CPU 75%, deliberate scale-up giv...
Rebrand Guacamole client connection status text to KamoDesktop
Override **************** so the 'Connecting to Guacamole...' screen (and related status) reads KamoDesktop.
Recording ingest, retention/quota, storage usage, summary pipeline
- MeetRecordingController: internal (X-Internal-Auth) ingest endpoint the jibri finalize.sh posts finished recordings to. - MeetRecordingService: uploads reco...
Sample vars for meeting-summary template preview
Adds a sampleVariables case for the new meeting-summary template so the steward preview UI renders realistic content.
Meeting-summary canonical template
Adds the "meeting-summary" transactional template (subject + branded HTML with {{roomName}} and raw {{summaryHtml}}) and registers it in CANONICAL_KEYS so it se...
Prosody moderator module, whisper-asr, jibri recording upload
- Meet-prosody: version-control the custom-plugins ConfigMap (captures the existing token_verification no-op override that was created out-of-band) and add ...
Recording transcription endpoint for post-meeting summaries
POST /api/conversion/meet/transcribe (X-Internal-Auth): normalizes an uploaded meeting recording to 16kHz mono WAV via a new additive FfmpegService helper, forw...
Calendar integration for scheduled meetings + real recording storage meter
- calendarIntegrationEnabled: when on, a scheduled clubhouse meeting is also added to the creator's calendar (via the existing calendar system) carrying the ...
MeetingRecording entity + repository for captured recordings
New MEETING_RECORDINGS table (org, meeting ref, room, MinIO bucket/object key, size, duration, captured/expiry timestamps, summary status) — the parent record f...
Marketing app, settings hub, Canva materials
Make Marketing a first-class org-enableable app and ship the Canva-powered Materials experience. App-enablement: - AppType.MARKETING mirror, Organization.isMar...
Video poster-frame thumbnails for marketing materials
Canva MP4 exports (and any video upload) skip the Docs PDF path and get a single ffmpeg poster-frame thumbnail (_thumb_p0.png) instead of failing. - **********...
Canva Connect OAuth + designs/export backend
- CanvaApiClient: PKCE authorize, token exchange/refresh/revoke, users, designs (create/list), export jobs, byte fetch - CanvaTokenService: encrypted per-memb...
Canva integration + Marketing as an org-enableable app
- **************** — platform Canva Connect client registration - ImageAssocType.MATERIALS(13, imaging-materials) — org marketing assets bucket - **************...
Require-password gate for anonymous guests (members bypass)
When an org enables requirePassword, anonymous link visitors must enter the room password; authenticated members are never prompted. - sidecar: no anonymousdom...
Enable Guacamole json-auth SSO + KamoDesktop rebrand
- JSON_SECRET_KEY (optional) on guacamole from the shared desktop-sso secret enables the bundled guacamole-auth-json extension the god-SSO links validate agai...
God-only KamoDesktop icons (Linux + Windows) opening auto-connected sessions
Two nav icons left of Analytics, shown only to god-eligible members (isGod added to NavGateContext). Each fetches a short-lived SSO link from SecurityService an...
KamoDesktop SSO token endpoint for god members
GET **************** (god-eligible only) mints a 5-minute guacamole-auth-json token (HMAC-SHA256 + AES-128-CBC, per the extension's wire format) and returns an ...
Org-scoped room names, room-name format, calendar Kamo meetings, start reminders; i18n settings
- useMeeting/MeetingDialog: room names are now namespaced by org token so two orgs can never collide into the same Prosody conference, and honor the org's r...
Auto-record + recording watermark from org settings
overrides.js loadOrgMeetSettings now, when recording is enabled: - watermarkOnRecordings → shows an org "REC" watermark overlay while a recording is active (J...
Scheduled-meeting start reminders + guest-link expiry
- MeetingReminderSweep: @Scheduled sweeper that fires a realtime "meeting starting" reminder to invited members at (start − reminderMinutesBefore) on ******...
Show member availability in chats list; rename tab to Directory
1:1 chat rows now surface the counterpart's live presence + availability the same way the Directory tab does — same useAvailability/usePresence sources and the ...
Hardened KubeVirt remote desktop + Guacamole gateway
Adds a full remote-desktop stack, GitOps-applied via the deploy workflow: - KubeVirt + CDI installed at deploy time (pinned-stable release URLs) - desktop-1: K...
Sub-tabs for chat groups, remember last-open tab
The chats list filtered by a row of multi-select pill chips that looked out of place under the Chats tab. Replace them with a single-select sub-tab bar (one tab...
Explain when email isn't configured; gate compose
The /messages inbox previously rendered its full shell even when the org had no email provider or the member had no mailbox, silently failing every API call. Ad...
All-types Chats list + browser-tab attention
Chats sub-tab now lists member, group, support and social conversations together, most-recent first, with a multi-select filter (Team Members / Members / Social...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.