Перейти к содержимому
KAMOUniverse

Журнал изменений

Что нового.

Каждое усовершенствование платформы, как только она появится.

  1. · kamo-marketing

    Add Flowroute to INTEGRATED WITH banner

  2. · kamo-internal

    Show accurate provider connection status from isConnected field

    Replaces the old logic that showed "Connected" for any provider with no sync error (including brand-new providers that were never tested). New three-state badge driven by isConnected (null/true/false): - null / never tested → grey "Not tested" (HelpOutlineIcon) - false → red "Not connected" (ErrorOutlineIcon) - true + sync error → amber "Sync error" (WarningAmberIcon) - true → green "Connected" (CheckCircleIcon) - RingCentral no OAuth → amber "Needs reauth" (unchanged)

  3. · VOIPService

    Persist connection test result to isConnected field

    - test() endpoint saves isConnected=true/false to DB after every health check - update() resets isConnected to null when configJson changes (credentials may have changed, requiring a re-test before showing Connected) - toDto() exposes isConnected so the frontend can distinguish: never tested / connected / not connected

  4. · kamo-shared-library

    Add isConnected field to VoipProviderInstance

    Nullable Boolean: null = never tested, true = last test passed, false = failed. Requires KamoInitializerService schema migration to add IS_CONNECTED column.

  5. · kamo-marketing

    Показать баннер с активным предложением с живым обратным отсчетом миллисекунд

    Получает активную сторону сервера продвижения на главной странице и отображает HeroOfferBanner между подзаголовком и бесплатным вызовом. Баннер показывает сумму скидки, продолжительность и обратный отсчет в реальном времени **************** на 50 мс с анимированным Граница с градиентным сиянием и мерцание. ничего не делать, если нет активных Существует незавершенное продвижение.

  6. · kamo-internal

    Доступный/недоступный переключатель для бэкэнда и исправление ошибки присутствия OFFLINE

    Переименовать приостановленный/активный чип в доступный/недоступный в NavTop Получите начальную доступность на монтировке и сохраняйте переключатели через новый API me/availability Добавить доступное поле в интерфейс Member и реквизит MemberItem - MemberList Pass доступен из ответов отдела на MemberItem - MemberItem показывает ONLINE/OFFLINE/UNAVAILABLE этикетку оранжевого цвета Исправьте ошибку OFFLINE: добавьте изменение видимости сердцебиения и периодическое повторное извлечение 120s

  7. · SecurityService

    Добавить доступно для ответов отдела и меня / конечных точек доступности

  8. · InitializerService

    Backfill available = Правда для существующих пользователей

  9. · kamo-shared-library

    Добавить доступное поле для переключения доступности членов

  10. · kamo-internal

    Удалить вкладку Access & Domains и компонент DomainManager

  11. · kamo-marketing

    Live unread badge + отказ от нового сообщения агента

    - поддерживает LiveSupportPanel вне экрана, в то время как виджет сведен к минимуму (только при наличии сеанса поддержки), поэтому подписка STOMP остается Живые и на UnreadMessage зажигаются для входящих сообщений агента, даже если Посетитель не смотрит на чат. - Оживляет значок весенней шкалой на каждое изменение счета (ключевой трюк) переустанавливает элемент) плюс непрерывное пинг-кольцо Tailwind 0. - Отскакивает и наклоняет минимизированную вкладку, когда счет идет вверх, Он краснеет от свечения, поэтому привлекает внимание со всей страницы. - handleExpand уже очищает счет на открытом, поэтому никаких изменений не требуется Вот.

  12. · MediaService

    Трансляция в ожидании счета + непрочитанный агент читать и посетитель отправить

    **************** теперь делегаты ************************************* отражает сеансы с непрочитанными сообщениями посетителей и сокращениями, когда Агент вызывает MarkAsRead. - Новый общественный помощник. **************** теперь (а) перераспространяет агентов непрочитанная полезная нагрузка после последних просмотренных авансов и (b) вызовов Помощник, чтобы навигатор SupportButton оставался синхронизированным, не дожидаясь Следующий опрос 60-х. - **************** также вызывает помощника, чтобы Ноутбуки живут, когда посетитель отправляет. Подсчет навигатора теперь соответствует штату значка per-row сразу же После клика и после обновления браузера.

  13. · kamo-shared-library

    Нечитанный счет + помощник по поиску по сессии

    Добавлено **************** Так что навигатор Значок SupportButton может считать билеты поддержки, которые действительно нужны внимание (непрочитанные сообщения посетителей) вместо PRE TICKET/NEW статус. График читается прямо из DB, чтобы он пережил обновление. Также добавляет ****************, так что MediaService Вы можете решить проблему с помощью GUID сеанса после MarkAsRead.

  14. · KlusterServices

    Добавить медиа в список резервирования поддоменов

  15. · kamo-internal

    Добавить медиа-поддомен в необходимые псевдонимы DNS

  16. · kamo-internal

    Добавить столбец местоположения в дейтагрид билета

    Читать **************************** прямо с SupportTicketDTO (сейчас снимок на билете) Время создания — никаких дополнительных поездок туда и обратно. Флаг + город/регион/страна с IP, показанным в подсказке; возвращается к em-dash, когда нет геоданных Он на билете. Вид только на агента. TicketHeader уже потребляет те же поля DTO, поэтому всплывающий инструмент Окно теперь также показывает снимок - без GeoLite или чтения с гостевого стола на рендере.

  17. · kamo-shared-library

    Снимок гео посетителя на билете

    Добавлены VISITOR IP ADDRESS, VISITOR COUNTRY CODE, VISITOR COUNTRY NAME, VISITOR CITY, VISITOR SUBDIVISION колонки. Запечатлено при создании билетов Таким образом, конечные точки списка / детали никогда не должны сканировать диапазон GeoLite. Отдельный просмотр посетителей в режиме чтения. KamoInitializerService (hibernate.ddl-auto: обновление) столбцы при следующем запуске; существующие строки возвращаются к записи посетителя хранимый код страны в ToDTO.

  18. · MediaService

    Добавить /ws/public-chat-native точку WebSocket вместе с SockJS

    Регистрация второй конечной точки STOMP без SockJS в /ws / public-chat-native что интерфейс может подключаться к нативному WebSocket (brokerURL) без необходимости библиотека sockjs-клиента, которая регистрирует обработчик разгрузки, нарушающий Политика разрешений сайта. Оригинальная конечная точка /ws / public-chat SockJS сохранена обратной совместимости.

  19. · kamo-internal

    Per-ticket unread badge + фильтр «Только новые сообщения»

    - Список билетов показывает значок чат-пузырь с непрочитанным счетом рядом Билет # всякий раз, когда на сеансе есть сообщения новее, чем у агента Последнее просмотренное сообщение. - Добавляет переключатель фильтра «Только новые сообщения» в панель фильтра. TicketChat теперь звонит **************** При этом, когда наступает срок, и когда наступает срок, наступает срок. Агент читает разговор. Ответы на изменения в библиотеке, которые расширяются FindChatMembershipsByMemberId включает в себя сессии SUPPORT TICKET, а также Медиасервис транслируется в ****************

  20. · MediaService

    Трансляция непрочитанного сообщения агенту в сообщении посетителя

    После того, как посетитель отправит сообщение поддержки, нажмите последние непрочитанные счета. Полезная нагрузка ******************* так агент билет-лист Обновление бейджа и счетчика навтопов в режиме реального времени. Зеркала транслируются в MediaController.sendСообщение для чатов между участниками.

  21. · kamo-shared-library

    Включите сессии SUPPORT TICKET в непрочитанный запрос на членство

    findChatMembershipsByMemberId теперь возвращает членство как для CHAT, так и для CHAT. Типы сеансов SUPPORT TICKET, так что существующий на члена непрочитанный счет инфраструктура (getUnreadCountsByMember, /topic/chat/unread/{memberId} Трансляции, GET **************** автоматически покрывает Билеты поддержки тоже. Позволяет агентам видеть показатели нового сообщения в билете в списке билетов и суммарный непрочитанный значок в навтопе.

  22. · KlusterServices

    Производство провалилось2ban с тюрьмами PJSIP и постоянным состоянием

    Добавить fail2ban-configmap.yaml с [asterisk] и [freepbx-web] тюрем, постепенная эскалация запрета (1h→24h→30d потолок), LAN ignoreip и пользовательский фильтр asterisk.conf, нацеленный на записи PJSIP SecurityEvent - Mount fail2ban-config ConfigMap и hostPath/var/lib/pbx/fail2ban (ban) состояние сохраняется при перезапуске стручков) как в развертывании k1m1, так и в развертывании k2m1 - Конфигурация проводов в Startup.sh до запуска fail2ban-клиента на обоих узлах

  23. · kamo-shared-library

    Add resetHasAttachmentsForFolder query to ConversationRepository

    Allows sync to reset stale has_attachments flags before re-indexing so corrected MIME detection can rebuild the field from actual attachment data.

  24. · KlusterServices

    Integrate Coqui TTS with norman voice (VCTK p267)

    - Deploy coqui-tts server (VCTK VITS model, CPU-only) as ClusterIP service on port 5002 with model cache at /var/lib/coqui-tts on k1m1 - Inject coqui_tts.agi into /var/lib/asterisk/agi-bin on each boot: calls HTTP API, caches 8 kHz mono WAV under sounds/coqui-tts/, streams via AGI STREAM FILE — use AGI(coqui_tts.agi,text) in any dialplan context - Write say.conf on each boot to route all Asterisk built-in say functions (digits, numbers, dates, times) through Coqui TTS

  25. · KlusterServices

    Add LAN DNS pod for split-DNS on k1m1

    Deploys a dnsmasq pod with hostNetwork on k1m1 that listens on 192.168.4.22:53. Overrides pbx.k1.kluster.kamocrm.com -> 192.168.4.22 so LAN phones reach the PBX directly without NAT hairpin. All other queries are forwarded to 8.8.8.8/8.8.4.4. Router DHCP must be pointed to 192.168.4.22 as the primary DNS server for LAN clients to pick this up.

  26. · kamo-internal

    Закладки конфигурации платформы (General / VOIP & SMS / System User / Advanced)

    Обертки **************** в SettingsView с четырьмя вкладками: Общий: обзор платформы только для чтения - общие организации, активный телефон-сервер Количество экземпляров, активное количество экземпляров SMS-провайдера, последняя глобальная синхронизация VOIP временная метка. Читать далее **************** VOIP и SMS: редактировать VoipSyncIntervalMinutes (1..1440) и VoipSyncEnabled Поверхность последней кнопки GlobalVoipSyncAt плюс кнопка «Run global sync now». Вызовы SecurityService → VOIPService /internal/voip/sync-global. Пользователь системы: существующий пользовательский интерфейс System User Access, снятый с Конфигурация Клиента дословно в компонент вкладки (без изменения поведения). - Продвинутая: параллельная кнопка «Trigger global VOIP sync now» для ops, плюс Явное сообщение о пустом состоянии для будущего контроля. ConfigurationClient теперь тонкий оркестратор вкладок. Использовать PlatformAdminGuard Остается на месте на уровне оркестранта, поэтому все четыре вкладки закрыты.

  27. · DaemonService

    Глобальная синхронизация VOIP (Admin-tunable interval)

    VoipGlobalSyncJob тикает каждую минуту и на каждом клеще читает SystemConfiguration Singleton решает, нужна ли глобальная синхронизация: Если voipSyncEnabled является ложным, пропустите. - Если последний GlobalVoipSyncAt + voipSyncIntervalMinutes > сейчас → пропустите. - В противном случае: POST/internal/voip/sync-global для VOIPService Заголовок InternalAuthFilter; последнее обновление GlobalVoipSyncAt на успех. Это позволяет операторам платформы регулировать каденцию во время выполнения из **************************** VOIP и SMS без перезапуска DaemonService Прикосновение к выражениям cron. Зарегистрирована в QuartzConfig наряду с существующими рабочими местами. k8s/configmap.yaml добавляет клещ cron (1-минутный по умолчанию) и kamo.services.voip.base-url + Внутренний.auth.secret для аутентификации исходящего HTTP-вызова.

  28. · SecurityService

    Конечные точки System-config + Platform-overview

    Поверхность конфигурации всей платформы, закрытая существующим владельцем верхнего уровня Защита (соответствует шаблону SystemUserConfigController’s requireTopLevelOwner). Конечные точки: - GET/api/security/system-config - возвращает однотонный ряд - PUT/api/security/system-config - обновление voipSyncIntervalMinutes/ voipSyncEnabled. Частичные обновления Поддерживается; валидация обеспечивает интервал 1..1440 минут. - GET/api/security/platform-overview - агрегированная статистика (общие организации, активный телефон/SMS экземпляр, Последняя синхронизация, текущая Интервал + включенный флаг. - POST **************** Вызовы VOIPService /internal/voip/sync-global через InternalAuthFilter auth secret) чтобы операторы платформы могли запустить глобальную синхронизацию VOIP по требованию Новая конфигурация платформы → вкладка VOIP & SMS / расширенная вкладка. Конфиг: - kamo.services.voip.base-url (по умолчанию к VOIPService кластерно-локальный сервис URL). Повторное использование существующего внутреннего.auth.secret.

  29. · VOIPService

    Контроллеры ресурсов на уровне одной организации + агрегатная система организации + внутренняя синхронизация

    Per-instance ресурс CRUD (расширения / пользователи / устройства / голосовая почта): - VoipExtensionsКонтроллер на **************** Контроллер на /api/voip/instances/{id}/users - VoipDevicesКонтроллер на **************** - VoipVoicemailКонтроллер на **************** - Каждый GET принимает ?refresh=true для принудительной доставки от поставщика и обновления кэша; в противном случае служит из локального кэша для быстрого пользовательского интерфейса. Каждый путь записи вызывает провайдера и обновляет локальный кэш так, чтобы агрегировать Взгляды остаются последовательными, не дожидаясь следующей запланированной синхронизации. - Voicemail GET /{vmId}/audio передает необработанный звук от поставщика через StreamingResponseBody позволяет пользовательскому интерфейсу <audio src=...> Агрегированный орган (VoipOrgAggregateController at /api/voip/org): - /расширения, /пользователи, /устройства, /voicemails возвращают строки в каждом экземпляре с таблетками {instanceId, exampleName}. UI превращает их в агрегированные вкладки в /settings/features/phone. - /health run checkHealth() на каждом активном экземпляре (через кэш-счета InstanceSyncService), возвращает InstanceHealthDto. - POST/sync запускает InstanceSyncService против каждого активного экземпляра Текущая организация. В пользовательском интерфейсе есть кнопка «Sync this org now». Внутренняя синхронизация (VoipInternalSyncController): - POST/internal/voip/sync-global петли всех активных экземпляров по всей платформе. Называется по расписанию работы DaemonService в Кварце. Защищены существующими Внутренний фильтр в VOIPService. Строит зеленый.

  30. · VOIPService

    Multi-instance provider refactor + full FreePBX + Flowroute SMS

    Core model change: one org → many VoipProviderInstances (was: one per org). Every provider API call is now instance-scoped. PhoneProvider interface: - New methods for extension/user/device CRUD + voicemail audio/transcription. - New capability flags (extensionManagement, userManagement, deviceManagement, voicemailTranscription). Defaults throw **************** (HTTP 501) so stub providers don't break. Frontend checks getCapabilities() to hide/disable actions per provider. - ProviderException (HTTP 502) for external-dependency failures. PhoneProviderFactory: - getInstance(UUID) / **************** replace legacy getProvider(Long orgId); getPrimaryForOrg(Long) kept for legacy call sites (CallController, CapabilitiesController, SipController, webhook inbound). - RingCentral OAuth tokens now scoped by (orgId, provider, instanceId) so one org can authenticate multiple independent RingCentral deployments. - FreePBX construction reads config_json → {baseUrl, clientId, clientSecret, ignoreSslErrors} and instantiates a dedicated FreePBXGraphQLClient. RingCentral (RingCentralProvider): - Constructor takes instanceId for log context. - New methods: listExtensions / createExtension / updateExtension / deleteExtension; listUsers / createUser / updateUser / deleteUser (RC models both as type=User extensions); listDevices / createDevice / updateDevice / deleteDevice; fetchVoicemailAudio (streams attachment content) and fetchVoicemailTranscription. FreePBX (FreePBXProvider) — full implementation replaces placeholder: - Client-credentials OAuth2 token caching via FreePBXTokenCache (~1h TTL, auto-refresh on 401, per-instance). - FreePBXGraphQLClient: GraphQL + REST transports with optional skip-SSL-verification for self-signed on-prem PBXes. - Extensions, User Manager users, Endpoint Manager devices, voicemail list/mark-read/delete + audio stream, CDR call history, SIP credentials derived from the extension's pjsip secret, health via fetchAsteriskInfo. - SMS explicitly unsupported (capability sms=false) — FreePBX doesn't handle carrier SMS. Flowroute SMS (FlowrouteTextProvider): - Messages v2.1 API with HTTP Basic (accessKey, secretKey). - Health probe hits GET /numbers?limit=1. - Registered with BulkTextProviderFactory via new FLOWROUTE enum value. Controllers: - VoipInstanceController (renamed from ProviderConfigController) — full CRUD at /api/voip/instances with per-instance test/sync. Secrets redacted in GET responses ('***'); merge-update lets UI round-trip redacted fields without clobbering stored credentials. - BulkTextInstanceController (renamed from BulkTextConfigController) — mirror CRUD at /api/bulktext/instances with test / test-send / send. - OAuthController rewritten for instance-scoped OAuth: start, callback, status, disconnect all take instanceId. - SmsController resolves instance from member.instanceId → org primary, attaches to upserted conversations. - CallController / CapabilitiesController / SipController fall back to the org's primary active instance for legacy single-instance endpoints. Services: - InstanceSyncService: pull-through cache sync — extensions/users/devices/ voicemails copied from provider to local tables, missing rows soft-marked UNKNOWN. Each sub-step wrapped so one unsupported capability doesn't fail the entire sync (e.g. FreePBX no-SMS + has-extensions). - VoipMessageService: all conversation/message paths propagate instanceId. Tests: pre-existing VoipProviderConfig-specific tests removed (covered the renamed types; rewriting is out of scope per design spec §10 — no TDD infrastructure is being added in this refactor). Builds green with updated kamo-shared-library.

Ваша вселенная ждет.

Начните бесплатно через несколько минут. Добавляйте продукты, когда будете готовы — без миграции, без новых логинов.

Бесплатно навсегда — не требуется кредитная карта