im 26.800.0 + socialnetwork 26.100.0: чаты крепятся к проекту, markdown в сообщениях, учёт входов по ссылке
Большой парный релиз: im и socialnetwork едут одним батчем, потому что делают одну вещь — сращивают чаты с проектами. Чат теперь можно прикрепить к проекту как дочерний, лента знает о своих IM-сообщениях, а прочтение в одном месте гасит счётчик в другом. Плюс markdown и учёт участников шаринг-ссылок.
Дерево чатов: чат как часть проекта
Центральное новшество — Chat\Tree\ChatTreeAttachmentManager с методами attachToParent(), detachFromParent(), validateAttach(), validateDetach() и парой экшенов Chat::attachToParentAction / detachFromParentAction. Рядом ChatTreeScope / ChatTreeScopeFactory, ChatAncestorFilter и асинхронное UnlinkDepartmentFromDescendantsMessage.
Идея: у чата появляется родитель, а у проекта — набор дочерних чатов. Отсюда же переименования в чтении — операции стали работать не «по типу чата», а «по области дерева»:
Controller\Chat::readByTypeAction→readByRecentSectionAction(CurrentUser $user, Reader $reader, string $recentSection, ?int $parentId = null)ReadService::readByType→readByTreeScope(ChatTreeScope $scope, ...)AnchorCollection::fillParents→fillChatData,AnchorProvider::getParentMap→getChatDataMap
Это ломающие переименования: старых имён нет.
Со стороны socialnetwork под то же самое приехали сообщения ChildChatAttachedToProject / ChildChatDetachedFromProject и события OnAfterAttach/DetachChildExternalChatSonetGroup.
Лента и IM перестали считать прочтения раздельно
Новая таблица b_sonet_log_im_message (LOG_ID, IM_CHAT_ID, IM_MESSAGE_ID, GROUP_ID, DATE_CREATE, PK по log+chat) и сервис LogImMessageLinkService связывают запись ленты с сообщением чата. К ним — хендлеры на чтение и удаление, события OnAfterReadMessages/ReadAllMessagesExternalChatSonetGroup, OnAfterReadAllChats, OnSocNetLogDelete / OnSocNetGroupDelete для зачистки связей.
Раньше это была вечная жалоба: пост прочитан в ленте, а счётчик в чате горит (или наоборот). Теперь связь материализована, и прочтение с одной стороны гасит счётчик с другой. В im появились Integration\Socialnetwork\EventHandler\ContentViewedHandler и LiveFeedReadAllHandler — а массовый сброс счётчиков они делают через CUserCounter::clearLiveFeedCodes(), который завезли в main 26.650.0 того же батча.
Кто вошёл по ссылке — теперь известно
Новая таблица b_im_sharing_link_member (SHARING_LINK_ID, USER_ID, ENTITY_TYPE, ENTITY_ID, DATE_CREATE, BLOCKED, unique по link+user) и SharingLinkMemberService.
Практический смысл в колонке BLOCKED: до этого ссылка была бинарной — либо живёт для всех, либо отозвана целиком. Теперь можно заблокировать конкретного вошедшего, не выкидывая остальных и не переиздавая ссылку.
Права на удаление чата, кстати, сделаны не колонкой таблицы, а параметром чата MANAGE_DELETE (Chat::getManageDelete() / setManageDelete()).
Markdown и превью коллабы
Features::isMarkdownAvailable()плюс парсер в JS (im/v2/lib/parser/src/markdown/*: converter, block/inline/list/table rules). Разметка разбирается на клиенте.Recent\PreviewSource\{CollabPreviewSourcePiggyback, PointerService, Resolver}и две новые колонки вb_im_recent:PREVIEW_SOURCE_CID,PREVIEW_SOURCE_MID. В списке чатов у коллабы показывается осмысленное превью, а не последнее служебное сообщение.Recent::raiseChat()получил совместимый?CollabPreviewSourcePiggyback $previewSource = null.
Что сломается
im:
readByTypeAction,ReadService::readByType,AnchorCollection::fillParents,AnchorProvider::getParentMap— переименованы (см. выше).CopilotChat::sendBanner()— второй аргумент был?string $copilotName, сталbool $force = false. Имя сдвинулось. Позиционный вызов передаст строку туда, где ждут булев флаг — самый неприятный вид поломки, потому что PHP её проглотит при нестрогих типах.Features::__constructснова переехал:collabPreviewSourceEnabledиisMarkdownAvailableвставлены передisCopilotDraftChatAvailable, а в конец добавленыisAttachChatToProjectAvailableиisReplyWithMediaAvailable. Второй релиз подряд — если вы собираетеFeaturesпозиционно, перестаньте.FavoriteChat::sendBanner()без аргументов →sendBanner(?int $authorId = null, bool $force = false).
socialnetwork:
V2\Public\Dto\Project\Feature::__construct— добавлен?string $type = null.ProjectProvider::__construct— добавлены три nullable-зависимости (?ProjectAccessService,?ProjectNotificationSettingsService,?Landing\Service\Project).- Удалены JS-компоненты
socialnetwork/v2/components/elements/ui-date-pickerиui-radio.
Совместимо: у ExternalChat-событий добавлены параметры с дефолтами (AfterReadAllMessagesEvent + $lastMessageId = 0, AfterUsersAddEvent + ?AddUsersConfig, FilterUsersByAccessEvent + FilterContext $context = Interactive).
Ещё в socialnetwork
Заметки коллабы: Collab\Controller\Note, таблица b_sonet_collab_note (COLLAB_ID, COLLECTION_ID, CREATED_BY, unique по COLLAB_ID — то есть одна заметка на коллабу), сервисы BindingService, CollabKnowledgeService, PermissionProjectionService и асинхронная раскладка прав. Плюс AddBotCommand / AddBotHandler для проектов, ProjectsTrialService, передача владельца проекта и новые методы ProjectProvider.
В SQL-установщике im почти все CREATE TABLE переписаны на CREATE TABLE IF NOT EXISTS (и индексы pgsql на IF NOT EXISTS), а агентам проставлен existError: false. Такая ручная защита от повторного выполнения — ровно то, что снимает переход на UpdateSystem\Migration, куда другие модули батча уже уехали.
Что делать
- Проверьте позиционные вызовы
Features::__constructиCopilotChat::sendBanner— это два главных источника тихих поломок. - Ищите в коде
readByType/fillParents/getParentMap— переименованы. - Если делали свою связку «пост ленты ↔ чат», сравните с
LogImMessageLinkService: скорее всего свою таблицу можно списать.