Changelog
Ce qui est nouveau.
Chaque amélioration apportée à la plateforme, à mesure qu'elle est livrée.
· kamo-shared-library
Projeter tout le terme en avant, et le dire sur la citation
Un écueil qui facture au début a vu le taux mensuel sur un contrat de trois ans. Le fixant la décision de voir si l'on c'était déjà mais il n'a atteint que QuoteConversionService, au moment de la conversion. Le Le document lui-même était toujours payé comme si le client payait par période. appliqueOptionHeadlineTotals ramifie désormais sur la base: FULL-CONTRACT prend contractTotal (qui est déjà payant, de sorte qu'il ne doit pas être ajouté deux fois), PREMIERE PREMIERE-PERIOD-PUS-SETUP conserve la première facture. mensuelEquivalent n'est pas touché au titre des deux - les badges d'épargne sont comparés à ceux des badges d'épargne mensuelEquivalent, et le déplacement, il changerait chaque étalon sur la page. La base est mise en place sur la citation lorsqu'elle est soulevée plutôt que résolue en direct. Un terme indique les termes, et un administrateur qui retourne le commutateur d'orge la semaine prochaine doit ne pas les reformuler sur un document qu'un client détient déjà. Lecture du réglage de l'orge au temps de conversion, c'est exactement cela: il a réévalué les citations qui étaient déjà accepté. La conversion lit maintenant le timbre de la citation, et révise le porte De sorte qu'une révision ne peut pas réévaluer silencieusement une négociation en direct. La colonne est annulable parce que chaque ligne existante l'est avant; nul se résout comme suit: PREMIERE PREMIERE PUS-SÉTÉTÉ, ce que ces citations ont été envoyées sous, donc rien les mains d'un client change de valeur.
· DaemonService
Le report du rapport de Tick SecurityService
Toutes les cinq minutes. Un calendrier est fixé à la minute, donc une croix plus fine n'achète rien un membre en avisera et un rapport plus grossier un rapport de 8 heures arrive à 8h15. DaemonService est propriétaire de cela pour la même raison qu'il possède le paquet juridique et leads-emails balayages: répliques: 1 avec stratégie Recréer signifie que l'ancienne gousse a disparu avant que le nouveau commence, donc une fenêtre de déploiement ne peut pas doubler-feu. A (Tolés) SecurityService, qui roule avec une poussée, peut prouver - et il n'y a pas de ShedLock n'importe où dans cette flotte, donc le nombre de gousses est l'ensemble de la garantie. «Désactiver l'exécution parce qu'un long balayage ne doit pas avoir un second a commencé en plus de lui: les deux trouveraient les mêmes horaires attendus, puisque nextRunAt est n'a avancé qu'une fois que le premier les aurait réclamés, et le même rapport serait publié. deux fois. Des temporisations explicites pour la même raison que les travaux des frères et sœurs ont un défaut RestTemplate attend toujours, et un fil épinglé ici signifie que le balayage ne court jamais à nouveau jusqu'à ce que la gousse redémarre, ce qui est indiscernable de "rien n'était dû". Rien dans un rapport ne croise ce processus : le retour de balayage compte, jamais les lignes.
· SecurityService
Réculez les rapports qui sont attendus et envoyez-les
Un critère d'évaluation interne, X-Internal-Auth, par rapport au temps, comparé à ce DaemonService coche. Le cron reste dans le daemon parce qu'il s'agit de répliques: 1 avec stratégie Recreter, de sorte qu'une fenêtre de déploiement ne peut pas doubler le feu; qui roule avec une poussée de manière prouvée, et il n'y a pas de ShedLock nulle part dans cette flotte. Pour un emploi dont la production est un chiffre d'une organisation envoyé par courrier électronique à une liste d'adresses, "généralement une fois" n'est pas un bien. Chaque emploi du temps est son propriétaire, les droits étant recalculés à l'heure d'exécution. les concessions stockées - non pas comme le daemon, qui n'a pas, et non comme celui qui a été édité en dernier le calendrier. Donc, le retrait de l'accès de quelqu'un arrête ses horaires produisant des données ils ne devraient plus voir à la toute prochaine course, plutôt qu'à chaque fois qu'une session expire. Sans cela, un calendrier est un moyen d'avoir le serveur lire des données sur votre au nom que vous ne pouviez pas lire vous-même. nextRunAt est avancé AVANT la tentative de livraison. Un accident à mi-chemin coûte alors un envoi manqué plutôt qu'une boucle non liée de doublons, et une fois par semaine manquée Le rapport est un échec beaucoup moins cher que le même rapport arrive à quarante fois. Le fichier rendu se présente sous la forme d'une pièce jointe plutôt que d'un lien, parce que ceux-ci sont , , , , , , , , , , , , , , , , , , , , , , , , , , Une mauvaise adresse est ne pas coûter au rapport des autres bénéficiaires, mais une course en cas d'échec de chaque adresse a enregistré FAILED plutôt que livré à personne. Un rapport vide n'est envoyé que si le propriétaire l'a demandé: un courriel hebdomadaire qui arrive toujours cesse d'être lu.
· EmailService
Laisser un envoi transactionnel porter une pièce jointe
Ajouté pour les rapports programmés, qui sont des documents de poche rendus ou un manuel qui doivent atteindre les personnes qui n'ont peut-être pas de compte - un lien ne serait pas une livraison pour elles. La couche SMTP a pris des attaches depuis qu'elle a été écrite; ce chemin est passé simplement null. Donc rien sur la façon dont le courrier est construit change, le champ est facultatif, et tous L'appelant actuel prend exactement la voie qu'il a toujours tracée. Base64 plutôt que multiparte parce que ce point d'extrémité est JSON serveur à serveur et Chaque appelant construit déjà un corps JSON. Les attaches surdimensionnées et mal formées sont REFUSÉ plutôt que tronqué: un manuel de 40MB rebondit coûte le domaine d'envoi réputation, et un tronc de manière silencieuse est un fichier que le destinataire ne peut pas ouvrir et ne peut pas expliquer. Le lancer est ce qui permet à l'appelant d'enregistrer un échec de courir au lieu d'un a été livré.
· kamo-shared-library
L'e-mail un rapport programmé arrive en
RAPPORT - SCHÉLÉ, enregistré dans CANONICAL-KEYS - absent de cette liste, un modèle est un 404, permanent, quels que soient les fichiers présents à côté d'elle. L'organisme indique la portée des données. Un bénéficiaire qui n'est pas le propriétaire de l'horaire n'a pas d'une autre façon de dire un total d'une organisation entière couvrant uniquement ce que le propriétaire peuvent voir, et ce sont des documents différents. Il nomme également le propriétaire deux fois: une fois comme qui a établi le calendrier, et une fois comme les chiffres de ceux-ci.
· SecurityService
Les listes d'un choix de dialogue d'actions à partir de, et un objectif de partage qui correspond à chaque id
GET - rend les gens de l'organisation, les départements et les rôles en tant qu'options de cueillette, dans un seul appel et sous une forme. Construit les fournisseurs d'options de notification plutôt que sur les membres, les départements et les rôles; points d'extrémité: chacun répond à une question d'écran différent et renvoient un autre la forme, et un dialogue de partage en consommant les trois cassent chaque fois que l'un d'entre eux a été modifié pour des raisons sans rapport avec l'établissement de rapports. Gated on SHARE-REPORTS (en anglais) Tout le monde dans l'organisation n'est pas quelque chose à remettre à un membre sans raison pour le voir. Une cible de partage est maintenant une chaîne tout au long. Un membre id est un Long à 19 chiffres et un département ou role id est un UUID; la colonne Longe qui a commencé avec pourrait contenir la moitié les genres, et la moitié il n'aurait pas pu échouer en s'associant silencieusement Personne. Les contrôles de département et de rôle se comparent en tant que texte et résolution par membre MAINTENANT plutôt que par ce qu'une session a occupé quand la part a été faite. Chacun des trois contrôles d'adhésion échoue. Une part qui ne peut pas être l'évaluation n'accorde pas.
· kamo-internal
Passez à travers chaque résultat de recherche, pas seulement le plus récent
La recherche en haut d'une fenêtre de discussion a marqué chaque occurrence de la requête, puis a fait défiler vers exactement l'un d'entre eux - le plus récent - sans rien dire combien d'autres Il n'y avait pas et il n'y avait aucun moyen de les atteindre. Un membre effectuant une recherche dans une conversation pour obtenir une facture nombre pouvait voir le mot mettre en évidence trois écrans vers le haut et n'avait aucun contrôle qui serait les amenez-les. Il se comporte maintenant comme la barre de recherche qu'il ressemble déjà: un compteur libellé "3/12", une flèche vers les messages plus anciens et un vers les nouveaux, Enter and Shift - Enter pour la même deux coups, et le coup se tenait sur en scission en plein ambre contre le jaune du Repos. Atterrir sur le plus récent succès est inchangé, de sorte qu'un membre qui n'a jamais tapé une requête et lire le résultat voit ce qu'ils ont toujours fait, maintenant avec le comte à côté. Deux décisions en dessous valent la peine d'être formulées. Les coups sont comptés par occurrence plutôt que par message, et contre les mots bulles dessinent en fait - la traduction où un message en a un, que l'ancienne recherche n'a pas fait. Le compteur et les marques sont deux vues d'une liste établie par une seule Scanner (trouverOccurrences, partagé avec le surligneur), donc "12" est toujours exactement le nombre de marques à l'écran. Deux scans qui n'étaient pas d'accord même légèrement laisseraient des flèches Atterrir sur rien. paged: les messages arrivent en bas pendant qu'une recherche est ouverte et les pages plus anciennes atterrissent au niveau de la comme "résultat 3" deviendrait discrètement un message différent. Il s'ensuit que "1 de 3" à la Le plus vieux n'est pas signifiant qu'il n'y a rien de plus en plus vieux - seulement ce n'est plus que ce n'est plus fsoché - donc, fureur de là demande la page précédente et atterrit sur ce qu'il est apporte, le même mouvement que la liste fait déjà quand quelqu'un défile vers le haut. Il s'enroule au plus récent seulement une fois que le serveur est épuisé, ou après l'arrivée de cinq pages ne pas avoir de coups: une presse d'une flèche ne doit pas être capable de marcher pendant des années la conversation à son premier message. La géométrie de repos de la barre d'outils n'est pas touchée. Le compteur et les flèches apparaissent avec le une question plutôt qu'avec le champ, parce qu'ils ont coûté environ soixante pixels et un vide La boîte de recherche n'a rien à compter.
· kamo-shared-library
Un rapport de service-travail et un objectif de partage qui correspond à chaque id
ServiceWorkReport est le dixième rapport de départ et celui qui fait la portée de la ligne. réel plutôt que simplement présents. Le commerce porte la paire de la plate-forme ou de l'ensemble VOIR-VOYAGE-SERVICE-WORK se trouve à côté de VIEW-SERVICE-WORK en tant que frère ou sœur - et une visite est attribué, donc un technicien ne détenant que le droit plus étroit voit leur propre travail pendant que leur superviseur voit la succursale. Une définition, deux réponses, et rien n'a été inventé pour la déclaration. Sans elle, elle et TEAM seraient chemins non testés dans la partie de ce système il est moins acceptable de laisser non testés. Les rangées sont des visites, pas des emplois: un emploi avec trois visites est de trois tâches, peut-être par trois personnes sur trois jours, et s'effondrer leur fait "qui a fait quoi, quand "inexourcées. ReportViewShare.targetId devient cible-clé, une chaîne. Un membre id est un id à 19 chiffres Long mais un département et un rôle sont UUIDs, donc une colonne INT8 pourrait contenir la moitié de la Partage des types - et la moitié, il n'aurait pas pu échouer en s'associant silencieusement Personne. Renommée plutôt que retapée car la mise à jour du schéma d'Hibernate ajoute un colonne et ne le re-toi pas; l'ancienne colonne n'a jamais été écrite. LeadPipelineConversionReport applique désormais le plancher non attribué de la grille principale. Sans cela, le rapport est une deuxième façon, non vérifiée de voir le pool non assigné, et son groupe compte en désaccord avec /leads sans raison visible.
· kamo-internal
Pinez les dossiers bien connus jusqu'au sommet de la barre latérale
Boîte de réception, brouillons, Envoyé, Junk, Trash and Archive Ils détiennent cet ordre en haut de la liste des dossiers, et tout ce que le membre a fait se trouve en dessous sous la rubrique "Mes dossiers", toujours librement réaptidable. Les rangées épinglées ne sont pas du tout enregistrées avec le dnd-kit au lieu de refuser le pas: une rangée qui ne fait que découper pour déplacer est toujours une cible de chute, donc l'abandon d'une un dossier sur la boîte de réception animerait la liste entière, puis le met en silence dos. Ils gardent la colonne de préhension comme espace vide, donc les deux groupes partagent un à gauche l'avantage de lire sous la forme de deux listes. L'épinglage est délibérément plus étroit que celui de SystemFolder, qui correspond à la feuille à n'importe quelle profondeur de sorte que les clients d'un membre.Archive dessine l'icône de l'archive. C'est le bon appel à une icône et la mauvaise pour une position, donc pinnedRank regarde Une personne classée sous sa propre société reste la leur. arranger, ainsi que les sous-dossiers d'un dossier épinglé. Le spam est assis dans le créneau de Junk. Le backend se normalise à Junk partout où il écrit, donc un serveur répertoriant "Spam" nomme le même dossier et ne devrait pas tomber parmi le membre. Le rang vit dans le dossierTirs, qui possède déjà le dossier partagé vocabulaire, donc le picker de mouvement commande ses racines de la même façon et les deux les surfaces ne peuvent pas dériver à nouveau. applicationFolderOrder se déplace vers lib/courrier électronique à côté it: les vitest incluent les globs ne couvrent pas l'application/les crochets, de sorte que la logique de commande laissée là a été collecté par rien et n'a jamais couru. Les membres qui ont traîné leur boîte de réception avant que ce changement ne le désigne toujours dans leur sauvegardée Préférence. Ces entrées sont ignorées, et la traînée suivante les écrit.
· kamo-marketing
Reconstruire l'indice en tant que carte du produit
C'était une liste récursive des trois cents articles, mis en évidence par la profondeur. Tout était sur la page et rien n'était trouvé, et la page pesée 3.9 MB. La forme est empruntée au produit. La porte d'entrée d'un client KamoCRM est la Floc de pas de lancement domestique -- une grille de zones parmi lesquelles vous choisissez -- donc l'avant du centre d'aide la porte est le même geste, et quelqu'un qui arrive sait déjà comment le lire. Les tuiles sont une carte à l'échelle plutôt qu'une grille de cartes. Chaque liste ce qui est réellement à l'intérieur avec de vrais comptages, donc une tuile est aussi grande que sa surface est grande: Client Le responsable des relations a huit sections et quarante-neuf articles et le regarde, ensuite au calendrier avec cinq. Les cartes à hauteur égale avec une icône pièce seraient plus allongées et présenterait mécontentrait le produit -- et seize grandes glyphes différencient Seize domaines bien pires que seize tableaux de fond. Domaines qui n'ont pas Les sections énumèrent leurs articles à la place, donc aucune tuile ne dit seulement son propre nom. La recherche est l'action principale et se trouve maintenant au-dessus de tout, classée (un succès à le début d'un titre bat un plus tard, qui bat un dans le corps) et groupé par zone, parce que "quelle partie du produit est celle-ci" est la plupart de la réponse. Les matchs sont en place. Une bande de point de départ pour un visiteur primo-arrivant, délibérément non numérotée: trois lire comme une séquence et ne sont pas une, puisque le troisième est un administrateur La plupart des membres ne feront jamais. Les dénombrements et les sourcils sont placés dans le visage mono déjà dans la marque, et le secondaire beige -- que le site avait presque cessé d'utiliser -- porte le structure. Cela empêche la page d'être monochrome vert sans introduire tout ce qui n'est pas déjà KamoCRM. Les pages de la catégorie et de la section cessent également d'être des impasses: "Dans cette section" maintenant rend les liens que le serveur n'a jamais été envoyé, deux-up avec des extraits et un compter où une section en a une.
· kamo-internal
Le Studio de rapport - une bibliothèque, et un responsable de la mise en ligne pour chaque rapport
/reports est une étagère, pas une grille de carte: deux cents boîtes arrondies identiques est un mur à numériser, et une rangée donne la salle de nom d'un rapport à lire. Vues sauvegardées nids dans le rapport auquel ils appartiennent, ce qui enseigne la distinction la totalité - il n'y a pas de contrôle "Nouveau rapport" sur le sous-système, parce qu'un rapport est une classe Java et ce qu'un membre sauve ici est une configuration de un. Le studio est trois groupes: ce que vous demandez, une phrase disant ce qu'il y a dedans l'écran, et la réponse. La bande moyenne est porteuse. Un écran de rapport échoue quand quelqu'un peut voir des chiffres et ne peut pas dire ce qu'ils sont des chiffres de l'extérieur, et chaque question dans cette catégorie - combien de lignes, sur quelle période, ont réduit comment, et couvrir la part de l'organisation - correspond à une phrase. La note de champ de données s'y tiens in extenso, parce qu'un total produit sous "votre propre dossier uniquement" est un Un document différent et rien d'autre à l'écran les distingue. Rien dans les app/composants/rapports ne demande quel rapport il rend. visibleStudioControls lit les capacités déclarées d'une définition et tire le des contrôles de mise en correspondance; Émissions de contrôle du paramètre sur le type d'un paramètre; chaque cellule rend par le descripteur ReportFormat de sa colonne. Un rapport uniquement sur les indicateurs clés de performance est obtenu période et un bouton Run et rien d'autre, sans une ligne de code qui le sait existent - et le jour où cela cesse d'être vrai, l'ajout d'un rapport cesse d'être un Java changement. formatters.ts est le seul endroit où une valeur devient une chaîne, et son jumeau Java lit le même descripteur, donc une figure à l'écran et la figure dans un PDF téléchargé ne peut être en désaccord. Les dates passent par app/lib/serverTime.ts plutôt qu'une seconde parser: Java écrit LocalDateTime sans décalage et un navigateur le dit comme heure locale, qui est des heures de sortie. La palette graphique est hexagone fixe, non dérivée de -color-primaire. Tous les autres la couleur ici est une teinte de la marque de l'organisation, qui est bonne pour le chrome et incorrect pour un graphique - un primaire de marque blanche pâle donnerait une palette de séries personne pourrait se déformer. L'ordre a été recherché et validé plutôt que visionné: les huit passent la bande de légèreté, le chroma plancher, la séparation CVD, la vision normale Contrôles de sol et de contraste sur la surface lumineuse de cette application, qui est la seule surface c'est ce qu'elle a. Le rapport suit exactement le modèle -legal-- et -training--------------------------------- - travail d'accent, que la palette de panneaux de vues nomme déjà l'accent "tâches, calendrier, rapports". Les rapports prennent sa place dans la navigation, le miroir AppType, les drapeaux de l'Organisation et l'arbre d'autorisation. Ses cinq droits ne sont pas élevés sans ce dernier.
· SecurityService
Run, export et programmer les rapports du Studio du rapport
La moitié du cadre de service: le catalogue, le parcours, les sélecteurs, quatre les exportateurs, les vues et les calendriers économisés. L'autorisation est explicite sur tous les chemins, parce que ce service fonctionne sous licence All à la chaîne de filtre. Deux droits sont toujours en jeu - VEW-REPORTS ouvre le module, et le droit de domaine du rapport décide si ce rapport peut être exécuté et comment une grande partie de l'organisation qu'elle couvre. VOIRRESSE seule n'admet personne à aucune donnée, C'est ce qui rend l'application sûre pour l'allumage d'un locataire. ReportScopeResolver lit les droits de OWN/ALL de la plateforme. Rien n'a été inventé pour le rapport. Un rapport ne nommant pas de droit plus étroit est dans l'ensemble de l'organisation et le dit dans une note, le studio et chaque impression d'exportation exugtion - un total produit sous la rubrique "votres propres dossiers uniquement" n'est pas le même document tel qu'il est produit sur l'ensemble de l'organisation, et un lecteur ne peut pas le dire autres que sinon. assaisis() est la limite qui maintient une vue sauvegardée de devenir une définition de l'utilisateur rapport: une demande ne peut choisir que parmi ce que la définition a déjà déclaré. Il bandes de colonnes inconnues, niveaux de regroupement et paramètres, mais feuilles délibérément une colonne inconnue dans un FILTRE pour que le moteur de requête refuse - larguer un caché la colonne change la présentation, en laissant tomber un filtre change la réponse. Les exportations lisent le même rapportRésultat de l'écran et le formatage à travers le même descripteur ReportFormat, donc un chiffre dans un PDF et la cellule il est venu ne peut être en désaccord. Le manuel écrit des nombres sous forme de numéro avec un masque de format plutôt que comme des cordes préformatées, qui est la différence entre un tableur et a CSV avec une extension différente. Le PDF porte l'organisation, la période, le champ d'application des données, qui l'a exécuté et les numéros de page. Un rapport programmé est publié comme son propriétaire, les droits étant recalculés au moment de l'exécution. la révocation de l'accès arrête un calendrier lors de sa prochaine course plutôt que chaque fois qu'une session nextRunA avance avant livraison: il n'y a pas de ShedLock dans cette flotte et répliques: 1 est tout ce qui empêche un double envoi. pdfbox et poi-ooxml sont ajoutés ICI et non à la bibliothèque kmo-shared, laquelle Les composants de service - ils expédieraient autrement dans des images de 60 dollars qui n'ont jamais rendre un rapport. kamo.reporting.enabled est défini dans la ConfigMap de ce service et nulle part ailleurs; cette propriété est ce qui empêche un bean de rapport en construction en des services qui ne peuvent pas s'en satisfaire. Renomme également une entrée rassis dans l'étude ec2ae5e rebaptisée - à la zsyncLabels sans pour autant que ce soit ligne de base, qui a échoué à l'origine/principal dans les deux sens à une fois. Le manipulateur résout un appelant et getOrganizationFromRequest, 401 quand null - donc c'est un renom, pas un élargissement.
· kamo-shared-library
Le cadre du rapport Studio et neuf rapports s'appuient sur celui-ci
Un rapport est maintenant un cours de Java ici et rien d'autre. RapportDéfinition décrit ce qu'est un rapport, ce qu'on peut lui demander, quelles colonnes il a et comment chacun doit être lu; le frontend rend tout ce qui déclare, donc en ajoutant un Le rapport n'a pas besoin de point d'extrémité, de page et de n'a pas de site TypeScript. Les pièces qui portent le poids: - La capacité de rapport est la raison pour laquelle le frontend peut être générique. Un rapport qui déclare Seules FAVORITE et SCHEDULE n'a pas de constructeur de filtre, pas de gestionnaire de colonnes et non Le groupe d'experts - ManagementOverviewReport existe en partie comme le canari pour cela. - ReportFormat est un descripteur, jamais une chaîne rendue, donc une monnaie dans le Tableau, l'infobulle graphique, le CSV et le PDF ne peuvent pas être en désaccord. - ReportSecurityScope provient des droits de propriété de chaque rapport, jamais d'un le droit de rapport. Un rapport de vente s'élargit sur VEW-ALL-LEADS exactement comme le principal Le réseau le fait, de sorte que les rapports ne peuvent jamais devenir un moyen de contourner le modèle de sécurité. - ReportQuerySupport donne la priorité au prédicat de portée, rejette une colonne inconnue la clé au lieu de le laisser tomber, et à gauche de toute association - une adhésion implicite est un INNER, et les rangées avec rien de l'autre côté sont celles Quelqu'un est à la recherche. - ReportAggregator conserve un groupe nul en tant que propre groupe, de sorte que les sous-totaux continuent d'ajouter jusqu'au grand total. - Les dates se résolvent dans le fuseau horaire du MEMBRE et sont à moitié ouverts. À 3 h 30 UTC le Le 1er septembre, un membre de Los Angeles est toujours en août. Chaque classe de rapports porte sur la composition et la «ConditionnelOnPropérité». Ce n'est pas décoration: chaque service scanne com.kamo mais déclare que son propre caractère explicite Liste des dépositaires Jpa, donc un composant ayant besoin d'un EntityManager est construits dans tous et CrashLoops ceux qui ne peuvent pas le satisfaire. Le les biens sont fixés uniquement dans SecurityService, et ReportBeansAreConditionalTest échoue la construction si un rapport l'oublie. Les rapports sont une application (ServiceType id 32) avec cinq droits (295-299). Les VOYÉROPORTS sont la porte du module et n'accorde pas de données par elle-même. Les noms de VEW-REPORTS et Les PORTÉS ont existé aux ides 1 et 2 jusqu'en 2026-08-14, lorsqu'ils ont été retirés. ainsi que les pages de stub derrière eux; les droits persistent comme getId(), donc aucune subvention fait avant qu'ensuite puisse s'y résoudre. PhiModule.REPORTING est PERMITTED - le moteur lit dans le groupage et ne stocke pas copie. L'exportation et la programmation quittent la frontière et sont régies par leur les droits propres et par le Président.
· kamo-internal
L'importateur, et trois choses qu'il nous a apprises
Publie le corpus en pilotant la véritable API KBService plutôt qu'en écrivant lignes -- un INSERT direct saute la ligne de version, l'événement kb.article.published c'est la seule chose indexant un article pour l'assistant d'IA, et le Ventilation de traduction. Une importation qui semblait réussie et a laissé "Train AI With Cet article "ne rien faire sur trois cents articles est le genre d'échec Personne ne remarque pendant un mois. Trois défauts qu'il est apparu, tous fixés ici: Les ids à 19 chiffres ne doivent jamais toucher un numéro JavaScript. Numéro(1168485648209608710») est 116848564820808700. Une session frappée avec cet org id authentifie parfaitement et décide d'une organisation qui n'existe pas - la vue d'ensemble est revenu vide et a été lu comme "la base de connaissances est vide". Le même piège a une deuxième fois sur l'article uid, où la réordonnance a répondu 403 parce que le parent id avait été arrondi et n'avait rien à voir avec la même chose. Les ids de session sont maintenant inscrits dans le JSON en tant que littéraux bruts, et les ids de l'article sont lus hors du texte de la réponse avant JSON.parse peut les toucher. Le parent nul d'une catégorie est la section, pas la racine. L'envoi nul aurait ont publié seize articles de haut niveau de leur gré, et le site de commercialisation -- qui demande que l'arbre sous le centre d'aide -- aurait montré une page vide. kubectl port-forward ne survit pas à quelques milliers de demandes. Transports échecs maintenant réescamotées avec la backoff; les erreurs HTTP ne le font pas, car répéter un 403 Quatre fois ne tard pour échouer. L'auteur est Sage, qui en est déjà l'article du Centre d'aide. Un article l'auteur et le dernier éditeur viennent de la session qui l'a écrit et sont montrés par Nom sur chaque article de la console.
· kamo-shared-library
Persister la règle du contact de cotation d'un marché, et refuser une règle à moitié déclarée
Les DTO ont porté citationContactMode et citationContactMemberId mais pas d'écrivain lire L'ensemble a été arrondi à travers le formulaire et a été laissé silencieusement tomber. Les chemins de création et de mise à jour l'appliquent maintenant. Le membre n'est détenu qu'en vertu de EXPLICIT et autorisé autrement, de sorte qu'un marché que les bascules ne laissent pas une personne derrière elle pour être réintroduite par un basculement ultérieur, et EXPLICIT ne désignant personne n'est rejeté plutôt que discrètement dévalorisé - le Une version calme imprime un nom différent sur la citation suivante que celui qui a sauvé le formulaire attendu. La recherche est org-scoped: les ids membres sont globalement uniques, donc un un l'un d'entre eux laisserait un locataire nommer le personnel d'un autre locataire sur son propre document.
· kamo-internal
Choisissez qui un devis nomme comme contact du client
Le dialogue de marché permet d'obtenir le "comtéléité future" sous Enable quotes: le lead's un agent affecté, un choix fait par devis, ou une personne explicite choisie avec le Le même AgentSelector utilise le filtre /leads. Sous Réglable par Quote, l'éditeur cultive une section Contact, ensemencée à partir de l'instantané que le serveur a pris lorsque la citation a été élevé - qui est l'agent principal, de sorte qu'il s'ouvre sur la personne qui y est déjà - et sauvegarde le changement avec le reste de la citation. Les trois décisions du client sont sorties de deux grandes composantes app/lib/quotes/quoteContact.ts. On leur a demandé à la fois dans les écrans et dans les écrans. le désaccord est invisible jusqu'à ce qu'un document imprime la mauvaise personne; en tant que module Ils sont également testables, ce qui n'a pas été le cas des terrs en ligne dans un dialogue de 1300 lignes. L'aperçu montre un contact nouvellement choisi par son nom avec le titre, le téléphone et le courrier électronique. vierge: ceux-ci sont résolus côté serveur à partir de la boîte aux lettres et de l'extension de ce membre, donc porter le nombre de la personne précédente sous un nouveau nom serait un mensonge La bannière non-changeuse ne dispense pas.
· SecurityService
Honorez la règle de contact du marché partout où un devis nomme quelqu'un
Les détails du personnel, la prévisualisation du personnel et la propre page du client résolvent maintenant la page suivante: contact par une méthode, de sorte qu'ils ne peuvent pas être en désaccord sur la personne imprimée sur la le même document. Sous ASSIGNED-AGENT, c'est l'agent du plomb résolu par lecture, comme précédemment; sous les deux autres modes, c'est l'instantané que la citation porte, avec l'agent principal en tant que repli d'une citation soulevée avant l'existence du cadre ou quelqu'un qui nomme quelqu'un qui est parti depuis. Créer des timbres l'instantané du marché plutôt que de l'organe de demande, et la mise à jour n'applique un nouveau contact que lorsque le marché fonctionne et le membre appartient à l'organisme, un marché qui nomme un contact explicite signifie que c'est un PATCH fait à la main, c'est comment cette promesse serait autrement rompue. Les cinq manutentionnaires de QuoteController ont construit un client/agent/réglable séparément; Ils partagent maintenant un personnelView, ce qui maintient les trois cohérentes.
· kamo-internal
Le corpus de l'article, et le pipeline qui le construit
307 articles dans 16 catégories et 29 sections, extraits du projet 248 articles sous Documentation/ plus 59 écrits ici: chaque catégorie et section page de destination, un ensemble de démarrage recouvrant l'intégration b) Les projets n'ont jamais été atteints, une catégorie de plate-forme le dossier de la source n'avait jamais eu README pour, et les deux articles de création de membres qui manquaient tout simplement. Quatre pièces: lib/markdown-lexical Markdown à la forme stockée par la base de connaissances. L'ensemble de noeud est une liste blanche de ce que les deux évaluateurs manipulent déjà, parce que le moteur de rendu public tire un noeud inconnu en tant que div nue -- pas d'erreur, non avertissement, un paragraphe qui a discrètement perdu son style sur une page personne n'est regarder. Les listes étaient la partie dure: une ligne blanche ne doit pas en finir (le Les brouillons ont des écarts de capture d'écran entre les étapes, et la fin redémarre le numérotée à 1) et un élément en retrait est une sous-liste, et non une phrase jointe en annexe à l'étape au-dessus de celui-ci. lib/propre-source Ce qu'un projet doit cesser de dire avant sa publication. Les constantes d'autorisation deviennent les mots sur l'écran; les parenthèses nommaient a fichier .tsx ou champ d'entité aller entièrement; la case à cocher de révision et le champ les renvois à un projet de méthode d'appel; et les renvois sont re-titrés plutôt que supprimé, donc "voir Comment puis-je voir mon horodat?" pointe sur l'article Nom publié au lieu d'un nom qui n'existe plus. lib/titres Questions-titres aux titres publiés. Les mesures prises en compte sont prises en compte; les 53 les concepts sont nommés à la main, parce qu'une règle qui pourrait tourner "Qu'est-ce que le différence entre statut et sous-état d'être ?" en un nom de page aurait plus exceptions que les cas. Les limaces sont vérifiées pour détecter les collisions dans l'ensemble. arborescents avant qu'une importation ne s'exécute - la base de données les contraint par organisation, pas par parent. Le graphique, construit non orienté parce que les liens sont symétrique du produit. 594 liens, 3 à 6 par article. Saisie à la b) Le cas échéant, que quelqu'un choisit en écrivant; surmontés de la position dans l'arbre. La similitude du texte classe les candidats mais ne s'est jamais qualifié d'un seul à lui-même - "Notes" et "Comment rechercher et filtrer votre Les pistes partagent chaque mot sur la recherche et n'ont rien à voir avec chacun autres. Aucune page n'est liée à son propre parent ou à son propre enfant: une section déjà énumère ses articles, et un article a déjà de la chapelure. 57 tests, et les vitests incluent la liste croît une ligne donc ils courent en fait.
· kamo-shared-library
Un marché décide qui désigne un devis comme étant le contact du client
QuoteContactMode donne trois réponses à un LeadMarket: l'agent assigné du plomb (Révéitée en lecture, c'est ce que chaque citation fait aujourd'hui et quelle colonne nulle signifie), une personne explicite, ou un choix fait sur chaque citation. Ces deux derniers sont instantanée sur Quote.contactMemberId lorsque la citation est soulevée, changeant donc un l'esprit du marché ne réécrit jamais le contact qu'un client était déjà donné, et un la révision porte l'instantané à l'avance - c'est la même offre. QuoteService prend le contact résolu comme argument plutôt que de le lire sur le corps de demande: ce module n'atteint l'avance que par id soft, et une valeur un client pourrait laisser quelqu'un nommé sur un document. Actualisation en l'honneur uniquement lorsque l'appelant en passe un, c'est-à-dire comment est-il appliqué côté serveur plutôt que par l'éditeur cachant un champ. agentForMember est nommé plutôt que surchargé - agentFor(nulle, ...) serait ambigu sur n'importe quel site d'appel passant un nul littéral - et la forme de prise de vue Les délégués maintenant à celui-ci, de sorte que les deux ne peuvent pas dériver sur un document imprimé.
· InitializerService
Colonnes pour le contact d'un devis du marché et le instantané per-quote
Un marché cite sa réponse dans QUOTE-CONTACT-MODE (- QUOTE-CONTACT-MEMBER-ID lorsque que la réponse est une personne explicite), et chaque devis maintient le contact qu'il était Les deux ne sont pas des défauts: un mode nul dit comme l'agent affecté et un instantané nul lui retombe, de sorte que chaque marché et cotation existant est inchangé jusqu'à ce que quelqu'un en décide autrement.
· kamo-internal
Contre les articles relatifs à un article
KbRelatedPanel est un composant en trois endroits: il est conservé dans le compositeur. et l'éditeur, et donne une lecture sur l'avis de l'article. Ajout d'un article ici ajoute également celui-ci à cet article, et le panel le dit -- sinon le la seconde moitié de l'écriture ressemble à quelque chose d'édition d'un article ne devrait pas l'ont fait. Deux modes, parce que des liens peuvent être choisis avant l'existence de l'article. Avec un guid le panneau est propriétaire de son état et écrit chaque changement directement: un réordonné L'oublié Save est un réamorteur que personne ne fait deux fois. Sans l'un, le Compositeur maintient la sélection et le PUT après création, comme un appel séparé pour la même raison pour laquelle le soumettre-pour-examen est une -- un lien qui ne parvient pas à épargner devrait laisser l'article écrit derrière lui plutôt que de l'enlever. Les suggestions viennent du serveur, qui classe les frères et sœurs avant les articles qui partager simplement le vocabulaire, et les filtre à travers la même portée de lecteur que n'importe quel autre lecture. Le panneau maintient la réponse du serveur plutôt que la liste qu'il a envoyée, donc un guid que le serveur a laissé tomber n'est pas indiqué comme sauvegardé.
· KBService
Articles connexes, et un chemin public qui garde l'arbre
Trois choses, toutes atteignent la même page. Articles connexes. KbArticleRelationService est propriétaire de la symétrique "voir aussi" liens: liste, set, suggest, et un clair qui fonctionne sur soft delete donc un retraité Un article ne s'attarde pas dans la liste de quelqu'un d'autre et la raccourcit silencieusement. Les lectures passent par KbReaderScope -- une relation non filtrée liste nomme les titres des articles exactement cachent les drapeaux d'audience, qui est l'oracle lire() répond 404 pour éviter, en arrivant par une autre porte. Le public lire est plus étroit encore: publié et public-visible seulement, donc une page marketing ne peut pas lier un visiteur au contenu uniquement par un membre. Chemin de garde d'œuvre. KbPublicArticleDTO porte maintenant la voie et les ancêtres. la racine de la section, donc /centre d'aide/centre d'aide est non représentable et un consommateur peut construire un lien emboîté au lieu d'un lien plat. Ce n'est pas cosmétique: la recherche d'article se résout sur le dernier segment de chemin, donc a link construit à partir de la limace nue rend toujours la page de droite et la perte la hiérarchie n'apparaît nulle part jusqu'à ce que quelqu'un lit le sitemap. Un lire au lieu de quatre. buildPublicTreeIndex remplace la séparation buildUidToGuidMap / buildPublicChildrenScous scans -- une seule page d'article était faire trois lectures de table complète plus un quatrième pour son parent, toutes projections de la même liste. Les bat-crumbs et les cartes connexes sont maintenant traduits avec l'article plutôt que de rester l'anglais sous un corps traduit. 98 essais, dont 30 nouveaux: forme de trajectoire et cycles en KbPublicPathTest, miroir la maintenance et le filtrage de la portée dans KbArticleRelationServiceTest.
· InitializerService
Migration pour les KB-ARTICLES-RELATIONS
Miroirs KbArticleRelation dans la bibliothèque kmo-sahi. Écrit explicitement que laissée à ddl-auto de sorte que l'UID et la DATE-CREATED par défaut vivent dans le base de données, qui est ce qui permet à un SQL d'insertion simple de travailler sans les nommer. L'indice unique est sur la paire commandée, et non sur la paire non ordonnée: (A,B) et (B,A) sont à la fois censés exister, et la limitation de la paire non ordonnée serait rejeter la rangée miroir que le service écrit sur chaque lien. Déjà appliquée à la production en exécutant ces déclarations comme kamo app utilisateur; ils sont idémpotents, donc une course KI complète plus tardive est un no-op.
· kamo-shared-library
Relations article-article
KB-ARTICLE-RELATIONS maintient les liens "voir aussi" les liens entre les articles de une base de connaissances. Les rangées sont par direction et la paire est maintenue symétrique par KbArticleRelationService, qui est la seule chose autorisée à les écrire -- une paire demi-écrite montre le lien sur un article et non sur l'autre, et est invisible du côté qui a encore sa rangée. Deux rangées plutôt qu'une de sorte que chaque direction porte sa propre SORT-ORDER: un article ordonne la liste sous-point sans perturber l'autre extrémité, et tous les lire reste une seule recherche indexée sur ARTICLE-ID. La DDL est déjà atterri à - en KamoInitializerService, appliqué à Yugabyte en tant qu'utilisateur de l'application kamo).
· SecurityService
Page et recherche dans le répertoire de l'orge, et arrêter deux constructeurs de rangs dérivants
Les points d'extrémité des réseaux répondent avec l'ensemble de l'ensemble dans un corps. C'est très bien pour un membre d'une douzaine d'adresses et impossible pour un opérateur sur un domaine destiné à atteindre à montrer vingt. Ajout GET/org/répertoire de réseau, qui correspond, commandes et fenêtres dans la base de données et retourne une page. le champ d'application - tout est fermé sur exactement le contrôle de tous les réseaux s'applique PlatformRightsService, donc les trois voies vers le bon maintien en activité et la liste ne peut jamais être plus large que l'action qui sous-tend. La même réponse revient comme can EnterAsSystemMember, donc un client construit ses lignes et ses boutons à partir d'une réponse. my-networks et tous les réseaux avaient chacun un constructeur de rangée manuscrit, et les copies avaient déjà dérivé: tous les réseaux n'ont jamais émis de primaireCouleur, logoUrl ou logoSimpleUrl, Ainsi /network a dessiné chaque opérateur d'un opérateur n'était pas membre de la console par défaut l'accent plutôt que l'org. Rien ne l'a signalé - les clés étaient tout simplement absentes Et le repli du client a fait le reste. Tous les trois partagent maintenant OrgNetworkRowBuilder.
· kamo-marketing
Base de démarrage sur 10 dollars sur chaque terme
69 / 59 / 49, à partir de 59 / 49 / 39. L'échelle d'engagement n'est pas affectée par la conception toujours exactement 10 dollars de rabais pour un an et 20 euros pour trois, ce qui est la norme la surface indique maintenant en dollars plutôt qu'en pourcentage. Les rétrospections de cinq fichiers se déplacent avec, et les jetons de contrôle du prix retirent le Des chiffres dépassés de sorte que personne ne passe un vieux prix de démarrage à une comparaison page. Les trois descriptions de métadonnées citaient "39/siège/moi" comme prix à partir du prix; Un résultat de recherche montre un résultat de prix comme tout autre. Le commentaire de caselement dans PricingClient conserve ses chiffres de 53/59 dollars, mais est maintenant daté : ils sont la raison d'une décision passée, pas d'une citation vivante, et d'une virgule non datée le prix dans un commentaire se lit comme un bug à la personne suivante. Vérifié contre le catalogue en direct plutôt que contre les replis: Starter's three-years Le siège rendait 49 dollars / maintenant 32,83 dollars, et la bande de la page d'accueil est en accord avec /prix.
· kamo-internal
L'offre en cours, sur les plans et la facturation et sur le tremplin
La console cotée est passée par les prix de la liste tandis que kamocrm.com a fait une troisième lecture de la même plan, parce que rien dans le kimo-interne ne pouvait voir qu'il existait une offre. Il est maintenant lit l'offre résolue de BillingService et montre ce qu'elle fait au prix: une bannière au-dessus du cueilleur de plan avec un compte à rebours et ce qu'il économise sur l'ordre dans et chaque carte de plan couverte a été frappée par son taux engagé à la offert un. L'estimation ci-dessous coûte déjà ce que la carte montre, donc les deux ne peut être en désaccord. Le pavé de lancement gagne une pilule à une seule ligne à côté de la pilule d'essai - à sa gauche, et a montré si la pilule d'essai est en place ou non, puisqu'une organisation a passé son procès sans est exactement à qui l'offre est destinée. Il est fermé sur la possibilité d'agir sur c'est-à-dire un membre qui peut acheter son siège, ou un propriétaire qui peut acheter le organisation, et qui ne paie pas déjà. Ce dernier test se lit comme suit : couverture.source, pas coverage.paidDy et payantPar dit que l'OMS couvre le siège, et quelqu'un assis sur l'abonnement libre par défaut de l'organisation lit ORGANISATION sans plan payant. Offrir une mise à niveau à quelqu'un déjà payant est le moyen le plus rapide de rendre une bannière invisible. planOffer.ts maintient l'arithmétique de sorte que la pilule et la console ne peuvent pas dériver, et parce qu'il s'agit de nombres pour lesquels les gens dépensent de l'argent: le pourcentage s'écarte du taux pour le terme COMMISSARIÉ à, jamais le prix de la liste mensuel, appariement 18 essais couvrent cette commande, le siège et la mise à l'échelle, qu'un plan non découvert est laissé seul, et que la date de fin est la Le dernier jour, le code fonctionne plutôt que le premier jour qu'il ne l'est pas. check-server-timestamps a pris l'analyse de l'expiration: "new Date(-d-T23:59:59)" est UTC explicite et correct, mais le garde ne peut pas le dire à partir du bug à cordes n'allons pas Il existe pour attraper, et un gardien apprend à se disputer est pire que le bug. Il passe par parseServerDate maintenant, qui conserve une valeur de date uniquement à UTC minuit Le délai est donc celui plus un jour, ce qui est également plus clair sur les raisons.
· BillingService
Servir l'offre de course, et dire si un siège est réellement payé pour
Ajout de l'EGET/marchés/-id-/promotion. Il n'y avait aucun moyen pour un aire d'achat dans l'application pour savoir qu'une offre était en cours d'exécution - le site de marketing lise des promotions à travers le polaire du catalogue public, et kamo-internal n'avait pas d'équivalent, donc les plans et la facturation les prix de liste de la console cités tandis que kamocrm.com annonçait un tiers sur le même plan. Il retourne l'offre RÉSOLU, pas la ligne brute. Chaque consommateur de forme brute a dû re-dernier les trois mêmes choses : si c'est en direct aujourd'hui, ce qui prévoit il couvre par code plutôt que par UUID, et quels cycles - et tout ce qui a fait Le site de marketing a élargi un code à deux plans en un chaque code de plan en comparant UUID avec les codes plans, et son héros filtré sur le TYPE de réduction et n'a rien fait silencieusement fait de l'objet d'une publicité pendant des mois. La vie n'est pas SubscriptionPromotions.check, le même calcul de prédicatPrix s'applique lorsqu'il fait des remises de prix une commande, donc une surface ne peut pas faire la publicité d'un code checkout va décodeur. Les plans reviennent dans l'ordre d'affichage, parce que les surfaces les écrivent dans un La phrase et "Business and Starter" se lit comme si les niveaux couraient en descente. /self/coverage maintenant retourne aussi "source". L'OMS couvre un siège, qui est une question différente de savoir si quelque chose est payé pour cela: un membre sur l'abonnement libre par défaut de l'organisation indique que l'organisation est payée pas de plan payant du tout. Tout ce qui offre une mise à niveau doit pouvoir les informer. à part, et payée Ennui ne peut pas.
· kamo-marketing
L'offre atteint le héros et la bande de prix
Le héros avait déjà un ruban de compte à rebours, et il avait rendu RIUN RIEN depuis le catalogue est passé à un pourcentage: EPMATHMARKEREP filtré sur FLAT-PER-SEAT parce que la copie de la bannière était "18 dollars/siège tous les mois pendant 12 mois". Deuxièmement, la définition plus étroite de "quelle offre est en cours" était l'ensemble du problème, il s'agit donc d'une définition plus étroite de "qu'est-ce que l'offre est en cours d'exécution". a disparu - le héros, la page des prix, la page de l'offre, la calculatrice et maintenant le la page d'accueil lisez tous les retours de la "PagePromotion" de la suivante: Le ruban est re-clé au pourcentage, aux liens avec /pricing/offre, et les nombres jusqu'à la fin du dernier jour (au milieu de la nuit l'a parcouru un jour plus tôt). Il porte le accent bricolé de l'offre s'use sur toute autre surface, il est donc reconnaissable comme le promotion avant qu'un mot de celui-ci ne soit lu; son encre CTA est mesurée par rapport à celle-ci gradient plutôt que blanc laissé, qui est inférieur à 4,5:1 aux deux extrémités. La bande de la page d'accueil rend désormais la même composante PlanPrice/fichant la même composante de prix. Maintenant, et ce que vous économisez - au lieu de son propre échelle laminée à la main sur le prix annuel. Les deux s'ouvrent sur HOME-TERM, nommé une fois dans le plan-tarif.ts parce que trois surfaces étaient en cas de défaut, et les CTA de la bande portent le code sur les plans couvertures d'offres. Les plans d'identification sur une promotion résolue reviennent maintenant dans l'ordre CATALOG. L'API revient dans l'ordre de la requête - Business avant Starter - et le héros les écrit dans un phrase, donc il se lisait "sur tous les sièges de Business and Starter", comme si les niveaux a creusé. Les clés check-i18n ne pouvaient pas voir Hero.tsx AT ALL: elle lie la const [t, diaporama. et le garde n'est compris que «const t»... Trois clés manquantes dans la composante la plus lue du site, invisibles à la garde dont l'objectif est de capturer un chemin de touche brut rendu comme visible texte. Il comprend maintenant la forme déstructurée, et plus important encore - un fichier qui traduit clairement mais ne donne pas d'espace de noms n'est soumis au lieu que de sauté, Donc la prochaine nouvelle forme de reliure coûte une mise à jour de garde au lieu de l'expédition "home.heroOfferCta" dans le héros. La couverture est passée de 1044 clés à 1073. le taux de prix de contrôle s'élève à 55 contrôles, couvrant la manière dont les plans d'une offre sont rédigés Prochainement contre la forme que l'API revient réellement - y compris qu'une promotion dont les plans ne sont pas résolus est refusée plutôt qu'élargir. Vérifié contre le catalogue en direct plutôt que contre le repli: page d'accueil et /prix les deux rendent 0 / 26,13 dollars / 66,33 dollars / Custom.
· kamo-marketing
Un engagement ferroviaire à trois mandats et une promotion de la page peuvent prouver
Nouveaux prix : départ 59 dollars 49 dollars/39 dollars et Entreprises 119 dollars/109 dollars par siège et par mois durée mensuelle, annuelle et trois ans. Le rail remplace la paire mensuelle/annuelle et sa pilule "Save 18%" - un pourcentage était la mauvaise unité pour un appartement de 10/20 dollars par personne. siège, donc la pilule a cité le plan "Trois" est arrivé à revenir en premier, et un la basculement ne peut de toute façon exprimer trois options. Son pouce est un cadenas qui se ferme comme le terme s'allonge, qui est la légende au-dessus d'elle ("Lock dans votre taux aujourd'hui") rendus littéraux. La bande d'offre indique la promotion en cours d'exécution une fois, au-dessus des cartes, et dit qu'elle est appliquées automatiquement. C'est vrai plutôt que décoratif: le plan CTA est maintenant , le code, que RegisterFlow indique déjà dans le code sp-checkout, et uniquement sur prévoit que l'offre couvre et envoie AUTUMN à la caisse à partir de la Free ou La carte d'entreprise promettrait une réduction que le serveur décodeur. Démarreur et carte de visite montrer Was / Now / What you Save, et la promotion vient hors du taux TERM, pas le prix catalogue et engagement d'abord, puis retirer le pourcentage le nombre déjà réduit, apparié Quatre surfaces faisaient chacune cette arithmétique eux-mêmes et étaient en désaccord, donc il se déplace dans app/lib/plan-pricing.ts et ils lisent tous la même réponse. Le Le pourcentage de promo du calculateur était facturé contre les add-ons, les boîtes aux lettres, les extensions et le stockage ainsi que les sièges, donc son estimation est sortie en dessous de ce que le serveur factures; il est maintenant prévu pour les sièges du plan comme celui du serveur. /prix/offre est reconstruite autour de la promotion du catalogue. Il avait "18DOFF / 18 ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' sur neuf chaînes de dictionnaires, et le catalogue avait dépassé les trois. De plus, package-lock.json n'était pas synchronisée avec package.json (swc/helpers manquants), C'est ce que fait le Dockerfile, qui est en train d'échouer. L'image construite a été brisée indépendamment de ce travail.

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