Changelog
Ce qui est nouveau.
Chaque amélioration apportée à la plateforme, à mesure qu'elle est livrée.
· kamo-shared-library
Ajouter un contrôle global de l'unicité de l'alias
Champs d'application par le prestataire, et que a eu raison alors qu'un pseudonyme n'a jamais été résolu que comme (security-provider-id, alias) - la paire derrière un domaine de parent. hôte. Deux organismes relevant de différents fournisseurs pourraient en partager un sans équivoque. Une organisation peut désormais être nommée directement par son pseudonyme, avec ?orga, et Cette consultation n'a pas de fournisseur de portée. Un alias répétés rend le référence à l'échelle de la plate-forme à l'échelle de l'échelle, alors OrgResolutionService le refuse au lieu de cueillir un - ce qui laisse les deux organisations inaccessibles par alias. La succession vivante contient déjà des répétitions (quatre parts d'orgs "acme-corp", deux partages "kia-kaha"), c'est pourquoi le résolveur refuse; C'est ce qui cesse de se créer davantage. exclusId permet à une organisation de conserver son propre alias tandis que d'autres domaines sont Sauvegarder; passer nul quand on crée. 1597 essais passent.
· KlusterServices
Expédier un compte rendu de bogue dans le code VS ouvert de la sauge
Militant URI qui crée une conversation dans une fenêtre de RUNNING et pré-remplie l'entrée, qui est le seul moyen d'atteindre la sale de l'éditeur déjà ouvert au lieu de commencer une seconde à côté. L'URI porte une prompte et rien d'autre, donc le modèle et l'effort passent CodeurProcessuWrapper - une enveloppe qui cartographie un enum validé en vers des drapeaux fixes et ne jamais prendre argv du fichier, donc un fichier falsifié peut choisir un autre modèle et rien de plus. L'URI pré-remplit mais ne soumet pas, donc la soumission est une déclaration synthétique et l'agent attend ensuite une transcription avant de signaler le succès. Le l'aiguille qu'il recherche est en échappé par JSON: les transcriptions sont JSONL, et la recherche pour les nouvelles lignes brutes marqueraient l'échec de chaque message délivré.
· InitializerService
Créer les tables de bogues du système
Pas de contrainte de CHECK sur les colonnes ordinales: support-ticket-status-check is ce qui se passe quand Hibernate gèle un à la taille d'un enum et l'enum puis croît et SystemBugStatusType devrait croître. Appliqué à la main en yb-tserver:5433 également, puisque ce service n'a pas d'IC.
· kamo-internal
Gérer un domaine personnalisé à partir des paramètres de l'entreprise
Un domaine était autrefois la porte d'une organisation: DNS devait être configuré avant que n'importe qui puisse se connecter, c'est pourquoi /setup/dns était atteint à partir du magicien de la création d'une org et d'une bannière "aiguilles" plutôt que des paramètres. Il est facultatif maintenant, il appartient donc au reste du l'étiquetage blanc. Ajoute une section de domaine personnalisée à Paramètres - Essentiel - Comportement - Étiquetage, entre Company Info et Branding. Il montre le domaine actuel de l'organisation, ou dit clairement qu'il n'y en a pas, et ouvre /setup/dns pour ajouter ou changer c'est ça. Le bouton indique "Réglage d'un domaine" ou "Réserve de domaine" en fonction de lesquelles de cela est-ce. La copie mène avec l'espace de travail déjà accessible sur kamocrm.com, Pour un propriétaire qui ne veut jamais sa propre adresse sait que c'est quelque chose qu'il peuvent ignorer. Utilise orgIdStr plutôt que organisation.id: ce champ est un numéro JS et tronque int64 org ids au-delà de MAX-SAFE-INTEGER, qui ouvrirait le DNS page pour une autre organisation. Le bouton est désactivé jusqu'à ce qu'il se résolve plutôt que de naviguer avec un mauvais i-id. Copie débarquée en premier dans le kamo-translation-dictionary (98ee7cb6) et IC clones it non épinglées au temps de construction de l'image, donc app-first est une construction rouge. 2921 essais et les 8 gardes passent, i18n inclus.
· SecurityService
Envoyer l'arborescence sur le point d'extrémité du catalogue de l'application également
Branch Types et applications autorisées construit son éditeur à partir de / caractéristiques/filcatalogue de l'application, non du locataire list, donc c'était la surface qui pouvait ne pas voir quelles applications sont les enfants dont. Un parent décide de ce qu'il les enfants peuvent même être offerts, de sorte que l'éditeur a besoin de la même forme. 947 tests verts.
· kamo-internal
Rendu l'arborescence de l'application, et confirmer ce que prend un interrupteur parent
Les enfants sont maintenant assis sous leur parent dans la liste des applis et des caractéristiques, chacun avec son propre interrupteur. L'imbrication est exprimée par l'ORDRE et par un tiret plutôt qu'un conteneur imbriqué, donc le code de la carte, du mouvement et du gabarit existant est intacte et un enfant dont le parent est filtré hors de l'onglet courant toujours des rendus au plus haut niveau plutôt que de disparaître. Deux comportements rendus nécessaires par la cascade: Le basculement s'applique maintenant à l'ensemble de la liste des fonctionnalités du serveur au lieu de baster la ligne cliquée. L'activation d'un enfant change ses parents et désactive un parent change chaque enfant, de sorte qu'une mise à jour locale à une seule ligne serait en congé l'UI en désaccord avec le serveur sur tout le reste la cascade touchés. Les deux critères d'évaluation ont déjà renvoyé la liste complète; rien de nouveau n'a été nécessaire côté serveur. L'ancien chemin à une rangée reste en remplacement d'un SecurityService qui n'envoie pas de liste. Changer d'un parent demande d'abord, nommer les enfants qu'il prendra avec c'est ça. C'est une action plus importante que la genouillère. L'arbre vient du point de terminaison des caractéristiques plutôt que d'un miroir TypeScript de ServiceType - ceux qui ont déjà dérivé de Java, et le serveur est le seul endroit qui connaît le catalogue opérateur. 203 fichiers de test / 2921 tests verts, build clean.
· InitializerService
Prix des enfants du commerce et du DSE, avec un gardien de la totalité
Aucune carte des prix n'avait de contrôle total, et les deux modes de défaillance sont différent et aussi bien silencieux. Manquant de CATALOG, une application n'est nulle part sur la matrice des prix. Manquant de TIERS, chaque niveau écrit est - allégée - fausse - un DENIAL explicite que le droit à l'ouverture en panne N'est-ce pas se sauver, parce que l'ouverture en défaut ne s'applique que lorsqu'un plan n'a pas de rang de ligne du tout Et ceci en écrit un. Donc une application oubliée est soit donnée à tout le monde ou cadenas pour tout le monde, et qui dépend d'un détail personne Se souvient de l'époque. Les cinq secteurs verticaux du commerce sont exactement à l'échelon de POS. Ils n'étaient pas achats séparés devant l'arborescence de l'application et tout ce qu'un POS d'org contenant pourrait faire, il pourrait le faire - donc les mettre n'importe où ailleurs serait rétroactivement la charge des capacités dont les gens disposent déjà. Une broche d'essai que sur POS plutôt que dans un littéral, donc le mouvement du POS les déplace. Le DSE est négocié en entreprise comme les systèmes de départ: pas de prix catalogue, CUSTOM ne planifie que, en l'absence de tous les niveaux. Embarquer un client de l'Institut signifie un BAA et un examen de conformité, et non une caisse en libre-service. 159 tests verts.
· kamo-marketing
Arrêter de compter les visites d'un membre à son propre lien
Un membre qui vérifie que son propre lien de suivi fonctionne est le plus courant d'abord visitez n'importe quel code, et c'est pire que inutile: il gonfle le nombre ils sont mesurés, il est indiscernable d'une perspective réelle chez le visiteur tiroir, et il leur laisse tenir un cookie permanent de visiteur donc chaque visite ultérieure visite compte à nouveau. Un code indiquant trois visites, toutes la personne qui l'a frappée, est un dossier de paiement qui y lie. Ce site est la seule origine qui puisse répondre à la question - il n'a pas de session et aucun membre, et la console interne ne peut pas mettre un cookie sur www.-apex de interne. Qu'est-ce qui croise cette brèche est un lien: arriver avec ?mrt-self-Moncs l'exclusion, et à partir de là sur le navigateur est exclue à chaque visite, que ce soit ou pas le paramètre est là. L'onglet Codes de suivi interne cultive le contrôle qui produit ce lien. Ne pas frapper n'est pas suffisant, de sorte qu'une visite exclue DELETES le visiteur et la source Les biscuits aussi. Un membre qui a prévisualisé son lien avant que celui-ci soit expédié, ou qui a opté sur un navigateur déjà compté, est toujours transporté un GUID - et les feux de balise pour tous ceux qui en ont un. Sans supprimer, l'opt-out n'aurait jamais fonctionné que pour les personnes qui n'en avaient pas besoin. L'exclusion n'est pas délibérément dans TRAKING-COOKIES: cet ensemble est ce que le cookie Le contrôle de suppression de la politique s'écoule et balaye un OUTOU avec les identifiants rerôlerait silencieusement le seul visiteur qui a demandé à ne pas être compté - sur le le contrôle le plus susceptible d'être poussé par exactement cette personne. le cookie de contrôle passe de 50 à 72, couvrant la valeur correspondante, orthographe des paramètres, exclusion de l'ensemble de suppression et invariants de source (le milieu de la vaisselle doit supprimer l'identité, la balise doit cautionner localement parce que intergiciels fonctionne sur les demandes de documents pendant que la balise fonctionne sur chaque côté client la navigation).
· kamo-internal
Le widget de tableau de bord des ventes affiliés
Une colonne de grille large et deux rangées de grandeur: les dix personnes dans l'organisation en faisant le plus par leurs liens de suivi, aujourd'hui, ce mois-ci, année ou tout temps, ouverture sur les visiteurs ce mois-ci. Le réordonneur est la caractéristique. Toutes les autres façons de montrer quatre métriques sur quatre les fenêtres sont seize listes séparées; c'est une liste qui se réarrange. Lignes sont clavetés par un membre et portent une animation de mise en page, de sorte que les diapositives de la catégorie de commutation les mêmes personnes passent les unes les autres plutôt que de vider la vitre - et le crochet garde chaque planche qu'il a récupéré, donc la presse qui déclenche cette animation a des données à animer sur la même trame. Les sélecteurs sont stockés contre le PROFIL du membre, et non localStorage, donc le quelqu'un mis en place à leur bureau est le tableau qu'ils prennent sur leur ordinateur portable. Les deux Les lecteurs dégradent une valeur non reconnue au défaut plutôt que de la refuser le serveur applique la règle identique et résonne ce qu'il a utilisé, de sorte qu'un La préférence écrite par une construction plus ancienne ne peut jamais laisser un membre sur une vitre vierge. Un membre en dehors du top dix obtient sa propre ligne en dessous de la liste, et un membre avec rien encore l'obtient au rang zéro. Un tableau qui ne peut dire que "vous êtes pas dessus" est la seule chose à laquelle un tableau de bord ne doit pas faire aux personnes pour lesquelles il existe motiver. Ici aussi, parce que c'est le même problème de l'autre côté: un contrôle "prévisualisation" sur l'onglet Codes de suivi qui ouvre un lien SANS compter la visite. Contrôle où votre propre lien atterrit est la première visite la plus courante de tout code jamais obtenu, et le comptage met les clics du membre eux-mêmes dans l'enregistrement sur lequel ils sont mesurés. buildTrackingPreviewLink est le lien réel et le marqueur du site de marketing lit: un contrat entre-réve, de sorte que le test broie le nom du paramètre.
· MediaService
Critère d'évaluation des ventes affiliés
GET et répond à cela le top dix de l'organisation pour une métrique sur une fenêtre, plus le propriétaire de l'appelant debout quand ils ne sont pas dessus. Les compteurs sur MARKETING-TRACKING-CODES ne peuvent pas soutenir ceci: ils sont toujours enroulements sans dimension temporelle, et il n'y a rien dans un total courant qui dit quand l'un de ce soit de cela s'est produit. La vérité fenêtrée est dans les rangées. - pour l'acquisition, et chaque conversion propre Timbres sur MARKETING-VISITORS. C'est aussi pourquoi tout le temps est d'accord avec le code grille: les mêmes données, comptées de la même manière, et non une deuxième comptabilité. Quatre décisions méritent d'être prises: - L'acquisition est datée par PREMIER contact, et non par activité. Comptabiliser les visiteurs qui étaient simplement actifs dans la fenêtre recréditerait la même personne chaque mois, Le travail qui a été fait autrefois avançait le travail accompli maintenant, pour toujours. - Classement des conversions par attribuéTrackingCodeId seul. Cette colonne gèle le moment un compte existe; lastTrackingCodeId continue à bouger, et classement par rapport à celui-ci permettrait à un membre de prendre la conversion fermée d'un autre avec un clic supplémentaire. - La fenêtre est découpée dans le calendrier de l'EMBER et comparée en UTC. "Ce mois" diffère d'une journée en fonction du calendrier de laquelle est demandé, et de chaque colonne dans ce schéma est un LocalDateTime sans décalage signifiant UTC. - Les quatre métriques sont calculées par demande, de sorte que la catégorie de commutation est un instant une série de rangées déjà à l'écran plutôt qu'une fileuse. Gated on AFFILIATE-SCOREBOARD-WIDGET et rien d'autre - voir le droit javadoc. Il n'achète pas de forage: il n'y a pas d'id de code, pas de visiteur id et pas de membre paramètre sur le point d'extrémité, et chaque critère d'analyse by-id passe toujours à travers MarketingTrackingScopeResolver inchangé. Les quatre agrégations utilisent la virgule-join plutôt que JOIN..ON parce que ni l'un ni l'autre La clé étrangère est une association de l'APP et la virgule forme des pars sur chaque Hibernate Version de la flotte de la flotte - MarketingTrackingHqlTest est maintenant à l'ordre du jour de la modèle d'entité réelle sur 6.2.13, et éping la création, l'attribution et le locataire présent ce qui échoue silencieusement s'ils dérivent.
· kamo-shared-library
Ajouter les droits de widget du tableau de bord des ventes d'affiliation
Cinq droits, 234 à 138, dans le groupe MARKETING et suspendu le blocage de VIEW-REFERRAL-CODES: un classement des numéros de référence est le suivi-code, et un membre qui peut ne pas voir l'onglet Codes de suivi n'a rien à voir avec elle. Le widget - pas "VEW-ALL-MEMBER" est ce qui divulgue d'autre les totaux des membres, et c'est délibéré. 200/201 porte les NALYSIQUES: dont visiteurs dont les adresses, dont le calendrier, est résolu par membre cible par résolveur de champ d'application. Un tableau de bord divulgue un nom, un rang et un numéro, à Tout le monde à la fois. Exiger le droit d'analyse à l'échelle générale le rendrait visible uniquement aux administrateurs qui en détiennent un, qui est un rapport plutôt qu'un conseil d'administration. NE PAS ensemencés délibérément, pour la même raison 200 et 201 ne sont pas: publier les totaux de renvoi de chaque détenteur existant à ses collègues sur le coffre qui l'a expédié, qui est une décision de divulgation prise par un déploiement plutôt que par un administrateur. 229/166/32/31 sous la forme auditée - tous les cinq sont des enfants et des VOIERESREFERRAL-CODES est lui-même un enfant de VEW-MARKETING, donc aucun seau à racine ne bouge.
· kamo-login
Marque et portée de l'écran d'inscription avec l'orge
login.kamocrm.com est l'écran de connexion pour chaque organisation qui n'a pas l'hôte qui lui est propre, donc le nom d'hôte ne peut pas dire dans lequel est la signature. est : il désigne l'organisation par id ou alias, sélectionne le marquage à peinte, et voyage avec les références en tant qu'organisation, ils sont vérifiés contre. Un indice, pas un certificat. L'adhésion est éprouvée face à serveur dans les deux sens, donc nommer une organisation à laquelle vous n'appartenez pas obtient le même refus que de nommer un fictif. La pire référence est la mauvaise lecture du logo sur une page publique. L'image de marque provient de SecurityService's /org/public/'ref', relayé plutôt que réimplémenté de sorte que la règle sur ce qu'une référence devinabilité peut exposer reste en un seul endroit. La base thématique suit ensuite l'organisation au lieu de l'hôte, utilisé comme donné: abandonner sa première étiquette la façon dont le chemin d'accueil fais irait acme.kamocrm.com en kamocrm.com et peindrait un locataire dans le Le marquage de la plate-forme. La première peinture utilise nécessairement le marquage de l'hôte, car la référence n'a pas encore été résolue; KAMO-THEME-REAPPLY repeint une fois qu'il l'a fait. Visite que l'absence de nom d'organisation n'éclaire aucune référence sur une visite antérieure enregistrée dans cet onglet, donc l'écran de la plate-forme ne garde pas quelqu'un d'autre Logo.
· SecurityService
Servir une image de marque d'une org à un écran sans session
La connexion, l'enregistrement et le hall des réunions brossent les couleurs de l'organisation avant qu'une session n'existe. Ils savaient lequel du nom d'hôte, qui est exactement ce qu'une organisation sans nom d'hôte ne peut pas fournir. GET /api/security/org/public/'ref' devient une référence explicite. l'id comme les chiffres, ou l'alias -- en quelque chose à peindre. Marque UNIQUEMENT: nom, logo, couleurs, lieu, hôte de thème. Pas de caractéristiques, pas les droits, pas les domaines, pas les membres. La première tentative à ce sujet a été réutilisée l'enregistrement de l'organisation projetée et le finchet d'extrémité l'a refusé, correctement -- les alias sont devinables, donc un bilan complet derrière un devinable La référence énumère la configuration de chaque organisation. Ce qui reste est ce que toute personne qui ouvre la page d'inscription de cette organisation voit déjà, et un les noms de test les champs exclus individuellement, de sorte que le renvoi d'un délibérés. Lire uniquement. L'application de l'auto-prestation de scie. effet indésirable ; un critère d'évaluation joignable par devination ne doit pas être écrit. Une référence inconnue 404s, de même qu'un pseudonyme ambigu -- parPublicRef Déçoit déjà un nomant plusieurs orgs, et cette épingle que le refus atteint l'appelant comme "pas d'organisation de ce type" plutôt que comme celle de quelqu'un d'autre le marquage. L'appelant revient à la plate-forme. themeDomain porte la même valeur que le shell et l'utilisation de l'agent de distribution de thèmes, donc un écran de pré-session lit le marquage d'une og à partir du dossier il était En fait écrit à -- 'alias'.kamocrm.com pour un og sans domaine. 947 essais passent.
· MediaService
Refrus d'enregistrement de réunion pour un locataire qui s'occupe de l'IPS
La division des capacités a permis ServiceType.MEET - une conférence en direct sur la rencontre auto-organisée ne quitte jamais l'amas - alors que REETING est resté bloqué, parce que ce pipeline affiche la totalité de la transcription à la Un routeur d'IA multi-fournisseur et envoie ensuite le résultat par courriel à chaque participant y compris les invités extérieurs. Il s'agit d'une copie tierce non réfutable. Le garde s'assied dans l'ingeste privé() des deux points d'entrée publics à travers, donc il refuse avant qu'un octet n'atteigne MinIO, et encore à nouveau au sommet de runSumaryPipeline, qui est public et 'Async. 200 tests verts.
· VOIPService
La capacité bloquée surpasse maintenant la droite, et le mode dieu
Lecture d'appel PhiPlaybackAuthorizer gated PHI sur VEW-CALL-LOGS. C'était la vérification complète parce que ServiceType.VOIP mappé à la section bloquée Module VOIP-RECORDING, donc un locataire de PHI ne pouvait pas avoir le système téléphonique à Tout et cette classe n'a jamais couru pour un seul. La répartition des capacités made VOIP elle-même autorisée - la gestion des appels est pendant le groupe d'études, alors que VOIP-RECORDING est resté BLOCKÉ-PENDING-WORK pour des raisons qui n'ont pas changé: la lecture n'effectue aucune vérification d'autorisation, les transcriptions rouler dans les métadonnées, et il n'y a pas de chemin de rétention ou de suppression. Laissée seule qui aurait été un affaiblissement direct: un locataire de l'Institut pourrait permettre le système téléphonique et, avec un droit accordé, de tout jouer. Donc PhiCapabilityGuard court d'Eau et son refus est définitif. Il ne faut pas paramètre de l'appelant, donc pour un locataire de PHI, pas de bon ascenseur - et ni ni l'un ni l'autre fait une session divine active, qui est la propriété qui compte le plus. - est maintenant - Trois tests encodant l'ancien contrat et sont réécrits plutôt qu'ils supprimé, chaque enregistrement pourquoi l'attente a basculé. Le message de refus de la messagerie vocale ne blâme plus le droit manquant, qui Ce n'est généralement plus la raison. 152 test vert.
· SecurityService
Servir l'arborescence de l'application et fixer l'auto-regardé non surveillé
Le contrôleur envoie maintenant les parents/les enfants/les parents/issale sur chaque série appli afin que le client puisse rendre les enfants imbriqués sous leur parent. Servi d'enfants plutôt que de refléter dans TypeScript à dessein: les rétroviseurs de type Service ont déjà dérivé de Java deux fois et une deuxième copie de l'arbre serait être encore une chose à dériver. Aucune nouvelle forme de réponse n'était nécessaire pour la cascade Résérialiser déjà l'ensemble de la liste de fonctionnalités, donc les changements d'entraînement arrivent sans que le client réconcilie quoi que ce soit. Les deux boucles d'auto-approvisionnement saute maintenant un enfant dont la plate-forme est le parent ne pas offrir, puisque permettreFeature cascades le parent et serait autrement Allonger un parent que personne ne publie. La boucle de contrôleur d'organisation n'avait pas de contrôle PHI alors que FeatureController était équivalent, sur un critère d'évaluation non authentifié public. Pour un locataire de l'Institut de santé publique le premier module bloqué, le cap entourant a enregistré un avertissement, et Caractéristiques irrécouvrantes en rangs brutaux sans modèle appliqué projection. Il demande maintenant plutôt que d'attraper, exactement comme les caractéristiques C'est le cas de l'inscription. /api/sécurité/ehr enregistré. Les préfixes commerciaux restent cartographiés à POS: le parent est la bonne porte grossière et affine déjà par marché. 938 tests verts.
· kamo-internal
Réalisez les six applications pour enfants de commerce, et arrêter la dérive des miroirs
Les deux rétroviseurs TS sont maintenant GÉNÉRATS de ServiceType.java plutôt que Maintenu à la main. Ils avaient mal dérivé de Java et les uns des autres: stri "intégration du RAG" et "Retour à l'organisation de base SMTP" Copie que Java a supprimée en 2026-08, POS a marqué PLANNING dans ServiceType.ts alors qu'AppType.ts a dit COMPLETED, et des descriptions différentes pour la même app dans chaque fichier. Il vaut la peine de savoir avant de leur faire confiance: displayNom et description ici sont lire par RIEN. Chaque consommateur n'utilise ces constantes que pour son identité hasFeature() correspond à id, appServiceIcons sur le nom. La copie vient de GET/api/sécurité/caractéristiques, qui honore PLATFORM-APP-CATALOG les miroirs ne peuvent pas voir. Les cordes sont synchronisées de sorte qu'un lecteur n'est pas induit en erreur. et l'en-tête du fichier dit de ne pas commencer à les rendre. Le parent/l'enfant est délibérément NE reflété pas - les caractéristiques le critère d'évaluation envoie parent/enfants/isparent par application, et une deuxième copie du la forme serait une chose de plus à dériver. Egalement: une icône par nouvelle verticale plutôt que d'emprunter celle de la société mère la vitrine, et les getters de l'Organisation, y compris l'Ehr.
· kamo-internal
Une barre de défilement, trois fois plus large, chaque conversation
La barre à côté des messages était 8px dans le chat des membres et les SMS, 6px dans les tickets d'assistance et social, et dans le chat d'IA, ce n'était rien du tout: cette liste a été déclarée "scrollbar-width" en ligne à côté de ses règles:-webkit-scrollbar, et depuis Chrome 121 une barre de défilement non initiale ou Couleur de la barre de défilement permet au navigateur de rejeter le bloc entier -webkit - donc il a demandé 12px et obtenir la ligne de coiffure de la plate-forme. des documents globals.css qui règlent la page scroller; rien l'a appliquée, et la discussion sur l'IA avait été discrètement du mauvais côté. Les cinq lire maintenant une constante de CHAT-SCROLLBAR : une gouttière 24px et trois fois la discussion des membres une longueur de pouce avec l'encart de 6px de part et d'autre par une bordure transparente, donc une barre de largeur toujours se lit comme une pilule dans un bac plutôt qu'une dalle soudée sur le bord de la fenêtre. La discussion sur l'IA les propriétés standard passent dans «soutien ne pas sélectionner::-webkit-scrollbar)» globals.css les met et le seul endroit où Firefox les lit sans coûter à Chrome ses règles. Le test est au niveau de la source car le sujet est une feuille de style et le jsdome n'impleme pas de barres de défilement: il fourre-tout qu'aucune fenêtre n'est de taille de sa barre d'un littéral, et qu'aucun d'entre eux ne fixe la norme les biens non gardés à nouveau.
· InitializerService
Étendre le grand-père du marché dans le remblai de l'app-tree
grand-pèreExistingGatedMarkets déjà marchés actifs de chaque org, résolu getRequiredService() et a permis l'application manquante - c'était juste Limité aux verticales isGated(), i.e. MORTGAGE et PERSONNAL-LAnzants. Maintenant que chaque type de commerce nomme son propre application enfant, la restriction a disparu, donc les mêmes graines de boucle DÉTAIL / LOCATION / SERVICE / SUBSCRIPTION / Lignes de contrôle. Aucune nouvelle migration n'est nécessaire. Semelles également RETAIL pour les organisations qui détiennent des POS sans aucun marché, qui avaient le commerce de travail avant l'arbre parce que le commerce de détail n'avait pas besoin d'une application propre. Les orges de premier niveau ne sont plus sautés, et c'est la solution qui compte. L'exemption était juste lorsque cela n'accordait que les deux applications de prêt - a L'org de plate-forme-opérateur ne doit pas acquérir silencieusement MLOS - mais c'est une erreur pour l'arborescence de l'application, parce qu'il est AppEffectivelyEnabled nécessite un OrgFeature ROW et n'a pas d'exemption de haut niveau. La première série a fait état d'un succès alors que en quittant KamoCRM, qui gère des marchés de DÉTAIL et de SUBSCRIPTION, avec pas de lignes pour l'un ou l'autre; il aurait perdu les deux de /commerce sur le suivant Service de sécurité. Pris en interrogeant la base de données, et non en lisant le journal. enableFeature maintenant cascade un enfant à son parent, donc ensemencer un enfant aussi garantit la ligne POS. RUN contre le produit 2026-08-24. Vérifié: chaque ligne commerciale active et marché a maintenant un enfant actif OrgFeature row, zéro manquant.
· SecurityService
Contrôler tous les droits, pas seulement les deux portes
Chaque type de commerce nomme maintenant sa propre application enfant sous POS, donc le est-s-Gated() court-circuit qui agite le commerce de détail, les locations, le service, les abonnements et les achats ont cessé. Ces marchés sont maintenant contrôlés contre leur propre application - qui est le point: une verticale peut être vendue, et éteint, seul. Cela dépend du remblayage de KamoInitializer ayant couru.
· kamo-internal
La recherche de la barre d'outils est un glyphe qui s'ouvre dans un champ
La discussion entre les membres portait un boîtier de recherche permanent en face du haut de la fenêtre - la largeur de la une barre d'outils entière, passée sur un contrôle qui est vide presque tout le temps et utilisé dans les rafales. Il est maintenant une loupe de 28px qui s'ouvre dans le champ en cliquant, et la barre d'outils se lit comme quatre glyphes et air. L'idée qu'il est construite : le loupe ne bouge jamais et n'est jamais échangée. Collapsed, le la pilule est 28px et l'icône se trouve en son centre, 14px à partir du bord gauche; ouverte, la pilule a 6px de rembourrage avant une icône 16px, ce qui place le centre de l'icône à 14px à nouveau. La pilule croît donc hors de derrière un glyphe qui tient immobile, et le contrôle se lit comme un objet ouvrant plutôt que deux états d'étamage croisé. La largeur ressort avec un petit dépassement sur le chemin de l'ouverture et aucune sur le chemin fermé; l'espace réservé accompagne la croissance de 60 ms de sorte que le texte arrive dans une boîte qui Il n'y a déjà de place; le contrôle clair ne ressort qu'une fois qu'il y a quelque chose à nettoyer. La fermeture efface toujours la requête, et le champ ne peut pas être mis de côté pendant qu'il en contient un: a Loupe effilée filtrant toujours la conversation serait la fenêtre allongée sur ce qu'elle est montrant. Le flou le laisse ouvert avec le texte dedans, et un clic égaré sur le glyphe focalise le champ plutôt que de rejeter la recherche. La motion réduite est respectée tout au long, le glyphe porte l'anneau de mise au point pour un onglet ainsi qu'un cliquez, et l'espaceur 50px l'ancienne boîte nécessaire est parti avec.
· kamo-shared-library
Chaque position verticale est son propre application enfant
obligatoireService devient total maintenant que chaque verticale a une application enfant sous ServiceType.POS, qui supprime le "noll signifie que le POS seul suffit" cas particulier et est-ceGated() avec lui. Chaque verticale peut maintenant être allumée, licences et titulaires d'un PHI-classifiés indépendamment - ce qui permet un médecin La pratique utilise le commerce du tout, puisque RETAIL reste bloqué pour un locataire de PHI alors que le reste du commerce ne le fait pas. SANTÉ(ServiceType.EHR) est ce qui fait apparaître le DSE à lorsque l'application est activée, sans nouvelle étape de port code: assertCommerceTypeAlowed, getAllowedCommerceTypes, le le critère d'évaluation des types permis derrière les deux cueilleurs du marché, et la liste de marché filtre tous S'y a déjà permis de résoudre par getRequiredService(). NON PUSHED jusqu'à ce que le revalorisation de KamoInitializer ait été activé. assertCommerceTypeBillé lires getRequiredService() directement, donc le moment où SecurityService voit ceci chaque ingre avec un marché de détail ou de location a besoin d'un enfant Org pas encore.
· MediaService
Que la configuration publique soit traitée par org id, pas seulement par hôte
Le side-car de rencontre vers le haut levé la prise de rencontre d'un organisme pour décider si un invité a besoin d'un mot de passe de réunion. Il a demandé par le nom d'hôte, qui, sur la réunion partagée, l'hôte décide à l'organisation de la plate-forme -- donc un locataire qui a besoin d'un un mot de passe aurait été lettre silencieusement pour chaque invité l'adhésion par liaison. Un invité n'a pas de session, donc la seule chose qui nomme son locataire est la chambre. qui porte maintenant un giclon d'orge. Les deux critères d'évaluation publique acceptent donc un orgId explicite et retomber dans la recherche de domaine lorsqu'aucun n'est donné, donc Rien de ce que l'hôte demande aujourd'hui ne change. Les Ids arrivent comme chiffres et sont parsed comme un long: ils sont passés 2x53, donc un acheminé à travers un double nom d'une organisation différente. 200 essais passent.
· kamo-shared-library
Permettre/désactiver la fonction de cascade à travers l'arborescence de l'application
Permettre à un enfant permet à ses parents; la désactivation d'un parent invalide enfant; invalide le dernier enfant quitte le parent. Permettre à un parent laisse les enfants seuls, donc un parent s'est allumé délibérément sans les enfants restent allumés. La cascade est animée par des événements et il n'y a délibérément pas de réconciliation. balayer. Il s'agit d'un bien sûr: un parent en permanence qui a été mis en place avec les enfants qui ne sont pas en mesure d'éteindre" l'invariant désactiverait le commerce pour chaque l'org existant le moment où il a été expédié, parce qu'il n'y a pas de rangs d'enfant jusqu'à ce que le remblayage de KamoInitializer. Un enfant affirme la garde de l'IPH sur le module de ses parents ainsi que sur le leur, avant toute inscription, sinon un enfant autorisé sous un parent bloqué soit serait bloqué ou irait silencieusement le parent bloqué.
· kamo-shared-library
Ajouter PhiCapabilityGuard pour les contrôles de capacité d'appel-heure
PhiTenantGuard fonctionne à l'heure de la fonctionnalité et à nulle part ailleurs - trois appels sites, tous dans FeatureService. Maintenant que PhiModule est à grain de capacité, un une application dont le noyau est autorisé peut encore contenir une capacité qui ne l'est pas, et la vérification du temps d'activation ne permet pas de voir la différence. Même signature délibérée que PhiTenantGuard: une fonction pure de (status, module) sans appel, paramètre droit ou dieu-mode, donc il y a Rien à élever. Classe ordinaire plutôt qu'un stéréotype - un partage-lib :: L'élément qui a besoin d'un dépôt non scanné a quatre services en boucle de crash. temps; chaque service de consommation déclare son propre Bean. NOTA: RENOUVELAGE ET VOIE-RECORDING ne sont plus à présent non liés. ServiceType mais pas encore gardé sur leurs sites d'appel - c'est le suivant engager MediaService et VOIPService. C'est inerte dans la production pendant ce temps parce que chaque orgg a actuellement des poignéesPhi-false, mais l'appel les sites doivent atterrir avant que tout locataire ne soit signalé.
· kamo-shared-library
Split PhiModule de l'application à la prise de capacité
POS mappés en ECOMMERCE-SYNC (BLOCKED-NO-BAA) et à l'ensemble du commerce la surface pend du POS, donc un org avec des poignéesPhi-vrai ne pouvait pas changer le commerce du tout - pas de marché, pas de commerce, et pas de vertical clinique Construit dessus. Les dix adaptateurs de synchronisation de détail sont la chose qui quitte le frontière, pas la colonne vertébrale du commerce. Les points de l'ordre du jour sont désormais conformes aux champs d'application COMMERCE-CORE (autorisé) et de la part de l'ECOMMERCE-SYNC à l'enfant du DÉTAIL. Même correction pour MEET (conférence en direct contre le un pipeline récapitulatif qui envoie des transcriptions à des conclusions extérieures) et VOIP (téléphonie ou enregistrements et transcriptions stockés). RÉUNIONS ET REPRÉSENTANTILLONS La VOIP-RECORDING n'a plus de type ServiceType du tout: ce sont des capacités joignable uniquement par le code, et le javadoc de PhiModule déclare maintenant la règle qu'une telle constante DOIT être vérifiée par PhiCapabilityGuard à son appel site. Reclassement d'une application comme permis sans la conserver à l'intérieur, il se lit comme conforme tout en ne faisant rien. L'AzASSISTANT et le RAG-SEARCH restent délibérément bloqués: KlusterServices a des enracinements, des chuchotements et des traductions, mais pas de LLM génératif, et RAG partage une collection Qdrant isolée par un filtre de charge utile. Fracture Il s'agirait d'un changement de papier. Deux tests codaient le modèle à grains d'application et sont mis à jour plutôt qu'à la mise à jour. étendu: l'assertion bloquée de PhiServiceTypeMappingTest, et FeatureServicePhiGateTest, dont l'exemplaire bloqué passe de la VOIP à DÉTAIL - La VOIP n'est plus applicable au moment de l'autorisation.
· kamo-internal
Atterrir à l'intérieur d'une régg nouvellement créée au lieu de la configuration DNS
La création d'une union acheminé le créateur vers /setup/dns, et la raison était réelle: L'entrée signifiait une redirection OTK vers l'intérieur. org n'a pas de DNS, de sorte que l'hôte était inaccessible. La configuration du DNS a donc été le prix d'ouverture de la chose que vous veniez de faire -- le mur exact que c'est travaux enlève. L'appel de création retourne déjà une clé à une seule fois; le magicien n'avait plus nulle part pour le dépenser. Il le dépense maintenant pour l'origine actuelle, où la session nomme l'organisation, donc il n'y a pas d'hôte pour attendre. Un domaine vaut toujours la peine d'avoir et Paramètres est là où il vit maintenant: un une étape optionnelle en marque blanche plutôt qu'une porte. Les avertissements de marque sont transportés par l'un ou l'autre, et si aucune clé ne revient l'orge existe toujours, Donc le magicien atterrit sur le point de vue du domaine plutôt que d'échouer. la navigation de contrôle a correctement repéré la fenêtre.location.href. C'est le sien noms docstring noms /valider avec une clé unique en tant que véritable borne de session Sautez, donc c'est autorisé listé avec cette raison plutôt que de travailler autour -- le routeur garderait la session de la LAL du Créateur, qui est précisément ce qui est en train d'être remplacé. 2857 essais et tous les 7 gardes passent.
· kamo-shared-library
Donner un arbre parent/enfant à deux niveaux
Six enfants de commerce dans les nouveaux ids 26-31, câblés à POS dans un bloc statique le motif de type "Rythme" (une constante enum ne peut pas faire référence à une autre ses propres arguments de constructeur). MLOS et LOS sont réparents sans changer d'id, parce qu'ORG-FEATURES persiste l'id via ServiceTypeConvertisseur et se déplace On réaffecterait toutes les lignes existantes. La copie du POS devient des "Lignes d'affaires" maintenant qu'il sert des prêts et dossiers de patients; le nom constant reste POS parce que Pertinte les noms sous forme de chaînes. Son ancien description se déplace à DATAI, où il est exact et déjà vérifié par ServiceTypeCustomerCopyTest. Nouveau vaisseau de nouvelle constantes PLANNING/disponible donc FeatureController.list's La boucle d'auto-approvisionnement ne peut pas les allumer pour chaque g. PhiServiceTypeMappingTest échoue par conception jusqu'à ce que les cartes d'engagement suivantes de nouvelles constantes; les deux atterrissent en une seule poussée.
· kamo-internal
Rendre un org sans domaine entrable
L'entrée d'un org signifiait naviguer vers Sans domaine que l'URL rendue comme littéral L'entrée était invalide et propriétaire ont été acheminés vers /setup/dns à la place -- DNS était la porte, pas un option de marque blanche. L'espace de travail s'ouvre désormais sur l'origine de l'ACTUAL lorsqu'il n'y a pas de coutume en direct l'hôte, et la session nomme l'organisation. Un locataire doté d'un domaine de travail sur mesure Il s'ouvre toujours sur son propre hôte, donc rien ne change pour personne de marque blanche. Un domaine personnalisé inachevé est traité comme aucun domaine: que HOST ne peut pas servir encore, ce qui n'est pas la même chose que l'ordonnance n'est pas joignable. peut EnterOrg donc les clés sur la chose qui a toujours été la vraie une condition préalable - une adhésion utilisable - plutôt que sur un domaine. needsDomainSetup et orgStatus continuent délibérément à signaler une déclaration inachevée domaine: ce n'est plus une barrière, mais c'est toujours l'exceptionnel de quelqu'un la tâche, et le point de vue de la succession est là où cela se fait remarquer. La coquille a également dû cesser de demander au nom d'hôte dans lequel il se trouve. La racine Ensembles déshabillaient "interne." et regarda l'hôte vers le haut, qui répond "qui possède ce nom" -- la même question que " quel espace de travail suis-je" seulement alors que Chaque locataire avait un hôte pour lui-même. Sur la plate-forme hôte, il retourne le propriétaire de plate-forme, de sorte qu'un membre entrant dans une organisation sans domaine aurait été montré. Le marquage, les caractéristiques et les droits de KamoCRM Inc. Il demande maintenant la première session via /api/org/current et retombe à l'hôte lorsqu'il n'y a pas de session, qui maintient le rendu de la coque rabattue. Le cookie est ce qui fait qui est accessible à la sessionStorage est invisible pour une demande de document. 2857 tests et les 7 scripts de garde passent.
· SecurityService
Laissez la coquille aller chercher son orge de la session, pas l'hôte
La mise en page de racine de kamo-internal lit l'en-tête de l'hôte, se déshabille "interne". et fetche /org/domain/that. Sur un hôte au service d'un locataire qui est le même question comme "qui est moi" ; sur un hôte partagé, c'est une question différente avec une mauvaise réponse -- il rends celui qui possède l'hôte, donc un membre qui L'inscription d'une organisation sans domaine serait classée par KamoCRM Inc. et drapeaux. Ajout de GET/api/security/org/current, en renvoyant le bilan prévu pour l'organisation de la SESSION de l'appelant. La disposition peut l'atteindre parce qu'il Déjà en avant l'en-tête Cookie et un cookie existe, de sorte que le serveur peut voir une session même si sessionStorage est invisible pour un document demande. Ne prend aucun paramètre, délibérément. Le premier projet a accepté un identifiant ou un pseudonyme. et - a refusé correctement: cette forme rend l'enregistrement de chaque org énumérable en devinant un alias, et les alias sont devinable. La session sait déjà dans quel org il se trouve, donc un paramètre ne pouvait jamais poser de questions sur un autre. À la session, la session a été résolue le cliquet passe seul plutôt que d'avoir besoin d'une entrée initiale. La projection est extraite plutôt que copiée. Deux critères d'évaluation renouant deux les formes du même enregistrement est l'échec qui vaut la peine d'être empêché - un client ne peut pas dire ce qu'il détient, et ils dérivent la première fois qu'une seule est mise à jour. 928 essais passent.

Votre univers vous attend.
Commencez gratuitement en quelques minutes. Ajoutez des produits quand vous êtes prêt. Pas de migration, pas de nouvelles connexions.
Gratuit pour toujours — aucune carte de crédit requise