Direkt zum Inhalt
KAMOUniverse

Changelog

Was ist neu?

Jede Verbesserung an der Plattform, wie sie geliefert wird.

  1. · kamo-shared-library

    Zählen Sie die heutigen Ausgaben für die Produkte eines Mitglieds in einer Abfrage

    Manage-Credits will pro Mitglied zeigen, wie viele Leads sie angenommen haben, so weit heute - die laufende Summe der Max Daily Spend Cap wird gegen verglichen. ************ antwortet für ein Produkt, so würde ein Raster eine Abfrage pro Mitglied x Produkt besorgen. Gleiches DatumSpent Fenster, gruppiert nach Produkt. Bewusst keine zweite Definition von "heute": Der Anrufer geht den eigenen lokalen Start-of-Day des Mitglieds, genau wie CreditLeadAssignmentService tut, wenn es die Obergrenze durchsetzt, weil eine Zahl neben der Kappe, die einen anderen Tag gezählt würde schlimmer als keiner angezeigt.

  2. · kamo-shared-library

    Zählen Sie den zuordenbaren Pool für jedes Produkt des Herstellers auf einmal

    countAssignablePool antwortet für ein Produkt, so dass ein Anrufer nur nachfragen kann Produkte, die es bereits hält. Manage-Credits war iterating Kleinotments zu entscheiden was zu fragen, was bedeutete, ein Produkt niemand hielt eine Kreditregel für gemeldet keine verfügbaren Leads - aber viele saßen in seinem Pool. Elf frisch erstellte Produkte zeigten 0 gegen Pools von bis zu 6.730. Verfügbarkeit ist eine Eigenschaft des (Produkt, Markt) Pool, nicht von jedermanns Kredit Regel, so muss es ohne eine reklambar sein. Eine gruppierte Abfrage statt einer Zählung pro Produkt.

  3. · InitializerService

    Composite-Indizes für geolite_locations

    Allein Country war der einzige Index auf einer 80.429-Reihen-Tabelle. Maßgemessen an der Produktion: Stadtauflösung (Land + Unterteilung) Index-gescannt alle 18.870 US-Reihen zu halten 984 für US+CA (138 ms), und der Land-Picker sequentiell-gescannt alle 80.429 Reihen zur Rückgabe von 251 (168 ms). Rein additiv, idempotent, gleiche 40001 Retry wie der Geschwisterindex Migrationen. Nahlos auf diesem Tisch - es wird Großhandel durch die wöchentliche GeoLite Sync und nie auf einen Anfragepfad geschrieben.

  4. · kamo-internal

    Zeigt die Anfrage oder die Systembenutzertür an, die Systembenutzertür an ihren Agenten an.

    Der Support-Chat-Header nennt jetzt die Organisation, von der die Anfrage kam, jeder, der das Gespräch führt und zu niemandem sonst - die Person, die es angesprochen hat würde nur ihren eigenen Briefkopf lesen, und es schiebt den Chat das Fenster hinunter. Daneben, für einen Agenten der Server sagt, ist berechtigt, eine Schaltfläche, die öffnet, dass Organisation in einer neuen Registerkarte als System-Benutzer angemeldet. Das ganze Prädikat lebt server-Seite und kommt als eine Flagge; Re-Derivierung eines von ihnen hier würde eine Sekunde machen Kopie einer Sicherheitsregel frei mit der ersten nicht einverstanden, und die Kopie, die driftet ist die auf dem Bildschirm. systemUserAccess.ts besitzt die beiden Dinge, die der Client tut entscheiden: Die Flagge wird als "=== true" (abwesend bedeutet, dass der Server die Nutzlast gebaut hat für niemanden, was keine Entscheidung ist), und dem Antragsteller wird nie der Button angeboten. Mitglieder-IDs werden als Strings verglichen - sie überschreiten den genauen Integer-Bereich von JavaScript, und zwei benachbarte Mitglieder rund um die gleiche Nummer. Der Austausch selbst ist das /Netzwerk ENTER AS SYSTEM MEMBER Flow wörtlich, einschließlich die Registerkarte synchron beanspruchen, bevor die Wartezeit: ein Fenster.ÖN, das nach einem läuft ist ein Popup der Browser sah nie eine Person fragen, und Safari blockiert es. Interaction Center - Chats - Support-Zeilen gewinnen die Quelle org, einen Status-Chip und die Das Alter des Tickets. Der Chip ist der gleiche StatusBadge das Ticket-Fenster und / Support-Nutzung, so ein Status trägt nie zwei Farben an zwei Stellen; seine Labelkarte wird jetzt exportiert Das Arien-Label der Reihe liest die gleichen Worte, anstatt eine zweite Liste der gleiche fünfzehn Status.

  5. · MediaService

    Benennen Sie den Org des Antragors und beenden Sie den Zugriff des Systembenutzers, wenn sich das Ticket bewegt

    Drei Dinge, alles über einen Support-Desk, der mehr als einen Mieter beantwortet. Das Ticket-Detail enthält nun ein pro-Betrachter Urteil darüber, ob "offene requestor's org als Systembenutzer", gelöst durch den Share SupportSystemAccessResolver - die gleiche Klasse SecurityService Wiederholungen vor der Münzarbeit alles, also kann hier nichts Zugang gewähren, nur offenbaren. Die eine Bedingung hinzugefügt vor Ort geht es um die KONVERSATION und nicht um die Gewährung: nie die eigene Antragsteller Knopf. Es konnte sowieso nicht geprägt werden, aber ein Support-Fenster, das dem Kunden ein administrative Tür in sich selbst ist alarmierend, ob die Tür öffnet sich und auf einem Widget-Ticket ist der "Antraggeber" das Systemmitglied der Org, der normalerweise Person, die die Warteschlange arbeitet. MediaService ist auch der Ort, an dem dieser auf ENDS zugreifen. Umschichtung, eskalieren, bewegen zugewiesen Ticket und Schließen oder Lösen einer alle überprüfen Sie den Agenten, der es verloren gegen die Organisation des Antragstellers; der Umkehrer kehrt aus der Datenbank zurück, so ein Agent mit einem anderen offenen Ticket von der gleichen org . oder die Decke SYSTEM_USER rechts behält ihre Sitzung und kein Anrufer hat, um das zu erarbeiten. Rechecks laufen AfterCommit: Wiederlesereihen, die diese Transaktion gerade geschrieben hat, ist das, was einen 40001 erhöht Neustart auf YugabyteDB, die die Umwidmung mit sich nehmen würde. Der bisherige Agent behält die CHAT, absichtlich - das ist der Punkt der Neuzuweisung statt Wiedereröffnung - aber nicht der Mieter. Jeder Mutationsendpunkt beantwortet das Urteil auf dem Weg nach draußen, weil das Fenster Swaps in was auch immer sie zurückkehren und toDTO weiß nichts darüber, wer sucht; ohne es der Knopf verschwand in dem Moment, als ein Agent die Priorität Dropdown berührte. Es ist ein keine Nebenwirkung anstelle eines Wrappers, der das Ticket zurückgibt: das Wrapper-Formular verwandelte den gesamten Antwortkörper in null, wo dieser Dienst verspottet wird, und die Controller-Tests gefangen. Schließlich, requestorOrgName / requestorOrgIsPlatform auf dem Ticket (bulk-geladen auf der list path - requestorOrg ist faul und eine Warteschlange ist Reihen von verschiedenen orgs von Definition) und org, Status und Ticketalter auf den Chats-Feed-Support-Reihen. Alter ist die Erstellung des Tickets, nicht zuletzt Aktivität: ein ruhiges, drei Tage altes Ticket liest sich wie frisch durch Aktivität und ist die dringendste Zeile auf der Liste.

  6. · SecurityService

    Mint eine System-Benutzer-Sitzung für das offene Ticket eines Support-Agenten

    enter-as gewinnt einen zweiten Grund, ja zu sagen. SystemUserEntryPolicy dreht den Anrufer *** in die Fakten der gemeinsame SupportSystemAccessResolver nimmt, und dass die Auflösung Das gleiche, das MediaService verwendet, um zu entscheiden, ob das Support-Fenster eine Taste zeigt ist das einzige, was konsultiert. Die UnterstützungTicketId im Antragsgremium ist beratend: es geht auf der Prüfungslinie und ist kein Input zum Urteil, so dass jemand benennt Das Ticket der anderen, ein geschlossenes oder eine zufällige UUID ändert nichts. Eine Ticket-kopierte Sitzung ist mit SupportSystemSessionRevoker registriert, bevor Einmal-Taste existiert, weil die OTK ist, was es in einem Browser und eine Sitzung, die einen Browser erreicht, ohne auffindbar zu sein, konnte nur durch seine TTL beendet werden. A Decke-Rechts-Sitzung ist absichtlich NICHT registriert - nichts davon kann ablaufen, und es auf eine Umwidmung herunterzureißen, würde jemanden vertreiben, der berechtigt ist, dort zu sein. SupportGrantSweep erhält jedes registrierte Stipendium für einen Zeitschalter als Backstop für "MediaService starb zwischen der Neuzuweisung des Tickets und dem Entzug der Sitzung"; es loggt bei WARN, weil das Erreichen bedeutet, dass ein Push verpasst wurde. Zwei Dinge, die auf dem Weg vorbei festgelegt sind: - Das System Benutzertor verwendet ************, das liest Administrator ROWS nur. Der /network-Button wird von Platform-access/me, die auch die Top-Level-Eigentümer und Active-God-Mode-Fußböden ehrt - so die Der eigene Besitzer der Plattform sah ENTER AS SYSTEM MEMBER und bekam einen 403 davon. Beide Seiten jetzt die gleiche Weise zu lösen, das ist, was diese Klasse behauptet, als ihre unveränderliche. - Session Fact Parsing (memberID, orgID, isOrganizationOwner, GD+godModeActive) ist jetzt SessionPlatformFacts, einmal lesen. Zwei davon sind Etagen, die jeden gewähren Plattform rechts, und ein zweiter Leser, der GodModeActive etwas falsch bekam . GD allein, sagen wir, würde die Plattform zu verteilen. Antwort trägt nun auch das Ziel url. /network baut seine eigene aus der org Reihe hält es; ein Anrufer aus einem Support-Gespräch hat ein Ticket und keine Domain.

  7. · kamo-shared-library

    Lassen Sie ein offenes Ticket gewähren seinem Agenten die Org des Antrags und verfallen mit ihm

    Ein Support-Agent muss in den Mieter des Kunden schauen, um das Ticket zu beantworten sie halten. Bisher war der einzige Weg in die Deckweite SYSTEM_USER Plattform rechts, das ist alles-Organisationen und permanente - weit mehr als der Job braucht. Fügt ein zweites, viel schmaleres Stipendium hinzu und legt beide hinter einem Resolver: - SupportSystemAccessResolver antwortet "kann dieses Mitglied in diese Organisation eintreten der Systembenutzer", durch die Decke rechts ODER durch ein offenes Ticket, das ihnen zugewiesen wurde und aus dieser Organisation hervorgebracht. MediaService betreibt es, um zu entscheiden, ob eine Button; SecurityService führt es wieder von Grund auf neu aus, bevor eine Sitzung prägen, so die Taste und die Aktion können nicht darüber streiten, wer sie drücken darf. Voraussetzungen beide Wege halten: ein aktives TEAM-Mitglied der Top-Level-Org, niemals das System Benutzer selbst, nie die Top-Level-Org als Ziel, nie Ihre eigene oder org. - Der Ticket-Zuschuss ist DERIVED, nie gespeichert, so endet es in dem Moment der letzten offenen zugewiesenes Ticket von dieser Organisation wird neu zugewiesen, aufgelöst, geschlossen oder ungültig. Nichts muss sich erinnern, um es wegzunehmen. - Eine Sitzung bereits in einem Browser fragt niemanden etwas, obwohl, so SupportSystemSessionRevoker indiziert diejenigen, die auf diese Weise geprägt und zerstört wenn das Stipendium ausläuft. Das Löschen der *** Taste ist der einzige universelle Kill-Schalter jeder Service liest Sitzungen von den gleichen Redis. Schlüsselnamen leben in Unterstützung SystemSessionKeys, weil zwei Dienste schreiben und lesen, und ein Tippfehler würde sich als Agent ruhig halten Zugang zu einem Kundengeschäft präsentieren. Kein @Service: Es braucht eine Redis-Template, und ein gemeinsames Stereotyp, das eine nimmt jeden Dienst, der keine Redis auf seiner nächsten Station hat. - ************ ist die eine Definition von "offen", hängt der Zuschuss auf. PRE_TICKET zählt (eine Chatanfrage ist die gleiche Arbeitseinheit); behoben nicht. Mit sich trägt auch requestorOrgName / requestorOrgIsPlattform auf SupportTicketDTO, und Status, Alter und Anfrageor org auf den Chats-Feed-Support-Reihen - eine Support-Warteschlange, die Antworten mehr als ein Mieter ist ohne sie unlesbar.

  8. · InitializerService

    Index Member rights applied on (member id, the right)

    Die Tabelle hatte überhaupt keine Indizes, während jeder deren Filter von MEMBER_ID hat. Bei 10.524 Zeilen war der Rechte-Lookup eines einzelnen Mitglieds ein vollständiger sequentieller Scan gemessen an der Produktion bei 368 ms zurück 192 Reihen, auf einer Tabelle, die mit wächst Mitglieder x Rechte. Rein additiv, idempotent, mit dem gleichen 40001 Retry wie die Lead Grid Indizes, da es mit Hibernate eigenen ddl-auto Pass im gleichen Boot kämpft.

  9. · InitializerService

    Composite-Blei-Indizes, und entsperren Sie den Lauf, der sie schafft

    Das /leads-Grid wird nun Filter und Seiten in der Datenbank statt Versand die gesamte Organisation zum Browser. Mit nur IX_LEADS_ORG_ID würde den Scan verlagern, anstatt ihn zu entfernen: der Planer liest immer noch jede Führung im Mieter und verwirft, was der Filter ablehnt. Vier Indizes, jeder führt mit ORG_ID so Yugabyte hält hash-partitioning auf dem Mieter und dann verengt: Zuordnung (der Filter hinter dem Original Bericht 801 von 827 Leads in der größten Org wurden nicht zugeordnet, und ein Mitglied Filterung zu ihrem eigenen Buch wollte sieben Reihen von 1.427), Markt und status (die Registerkarte, auf praktisch jede Ladung angewendet), und DatumCreated (die Standard-Sorte und der Datumsbereich-Filter). Hibernate's ddl-auto würde sie aus den @Index-Annotationen in der gleiches Boot, aber es emittiert CREATE INDEX ohne ZWEI EXISTS und Schwalben das Versagen, das 'hat es tatsächlich gelandet' aus dem Log unanrufbar macht. Explizit, idempotent und hier statt wieder vorgetauf. Rein additiv, so dass die Gate-the-DROP-Regel gilt nicht - aber die 40001 Retry tut es, da diese streitet mit dem gleichen ddl-auto Pass Momente früher. IX_LEADS_ORG_ID bleibt an Ort und Stelle, obwohl jetzt redundant: einen Index fallen lassen a Rennpass kann gerade nicht zu rekieren ist, wie ein Tisch endet mit weder. LeadContactPointSeedRunner musste sich ändern, damit irgendetwas davon überhaupt läuft. Es wurde mit findAll(Pageable) geblättert, das Spring Data als Inhalt ausführt SELECT plus ein COUNT in einer schreibgeschützten Transaktion - also ist das COUNT nie die erste Anweisung, und Yugabyte kann nur transparent versuchen, eine Lektüre Neustart auf der ersten Anweisung. Weil der Läufer Kontaktstellen schreibt zwischen den Seiten stellt sie ihren eigenen Neustart her. Latent, bis es gab genug ungesetzte führt zu Materie; bei 851 scheiterte es direkt: 40001 Neustart erforderlich ... Abfrageschicht Retry ist nicht möglich auf: count(l1_0.uid) aus Leads auswählen Das brach den gesamten Lauf bei der Bestellung 99 ab und nahm jede spätere Migration mit es, einschließlich dieses. Ersetzt durch einen Keyset-Scan (uid -nach:afterUid, eine Anweisung pro Charge, kein COUNT), die auch Einsätze Mid-Scan übersteht in einer Weise, die OFFSET paging nie getan hat.

  10. · kamo-internal

    Angebot Firmenname als kartographierbares Importfeld

    leadFields.ts ist die Liste, aus der die Mapping-Leinwand schöpft, und sie muss die Backend-Schalter in LeadImportController - ein Weg, der von beiden Seiten fehlt von der Benutzeroberfläche akzeptiert und dann still ignoriert. companyName fehlte von beides; der Backend-Fall landete daneben. Märkte konfiguriert mit includeCompany = true (B2B Farm Listen) zuvor hatte keine Spalte, auf die der Geschäftsnamen abgebildet ist.

  11. · SecurityService

    Karte UnternehmenName, so dass eine Tabellenkalkulation kann den Namen tragen

    setDirectFieldOnCreateRequest hatte keinen companyName-Fall, also war das Feld unerreichbar vom manuellen Importassistenten, obwohl CreateLeadRequest trägt es und LeadService.createLead beharrt bereits darauf (auf 50 Zeichen gesetzt). Auf einem Markt mit includeCompany = true, dass B2B-Importe ohne Zuhause für der Geschäftsname überhaupt. Paare mit dem passenden Gehäuse in DaemonService LeadIntakeProcessingJob und der neuer Feldeintrag in kamo-internal's leadFields.ts - ein Weg, der in beiden nicht vorhanden ist die Frontend-Liste und der Backend-Schalter werden stillschweigend ignoriert.

  12. · DaemonService

    Lassen Sie eine abgebildete Nutzlast tragen FirmaName und Quelle

    Der Direktfeld-Schalter des Antake-Job wurde beim AnbieterLeadID gestoppt, also ein Mapping auf companyName oder source wurde von der Benutzeroberfläche akzeptiert, auf dem Endpunkt gespeichert und dann stillschweigend fallen gelassen, wenn die Nutzlast wurde eine CreateLeadRequest. Beide Bereiche existiert bereits auf der DTO und werden bereits von LeadService.createLead geehrt Nur der Job-Wechsel fehlte ihnen. Dies ist wichtig für unternehmensförmige Märkte (einschließlich der Gesellschaft = wahr), wo die Business-Namen ist die Identität des Leads und es gab vorher nirgendwo, um es zu setzen.

  13. · kamo-marketing

    Legen Sie die Schlagzeile fegte Band zurück

    Gerestauriert genau wie es war - gleiche zwei-Schicht-Gradienten, gleiche 120deg Band, gleiche 9s/1.1s Timing und Lockerung - nach dem Entfernen im Compositing-Pass. Die Kosten sind präzise und es wert, zu sagen, anstatt zu verlassen, um wiederentdeckt zu werden: es ist die eine Animation auf dieser Seite, die nicht zusammengesetzt werden kann, weil text-clipped Sweep bewegt Farbe innerhalb von Glyphen-Formen und keine Transformation oder Undurchsichtigkeit drückt es aus. Gemessen mit getAnimations(): Desktop 2 -" 3 (die zusätzliche ist dies) mobile 1 - 1 (unverändert) Mobil ist unverändert, weil die =<767px Kill-Switch bereits setzt "Animation: keine" hier, und mobile ist, wo die Performance-Score gemessen wird. A Telefon macht die Ruhe füllen und nichts Schleifen. Die anderen 25 Elemente aus der Original Audit Aufenthalt auf dem Kompositor. Der Kommentar zu der Regel sagt nun all das, einschließlich, dass die maskierte-overlay Workaround wurde in dieser Codebasis ausprobiert und schlechter gemessen (34 - 41), so dass niemand Re-Derivate, dass der harte Weg. Verifiziert durch Schrubben der Animation auf den Rahmen, wo die Band kreuzt für sie statt zu raten, da die Lockerung ist front-loaded und eyeballed Timings landen nach dem Pass und Screenshotting bei 2x: das Olivenband ist an der Vorderkante der Überschrift, fehlt im geparkten Rahmen.

  14. · kamo-internal

    Retitle Modified to Converted und behebt zwei Tab Icons

    Beide Registerkarten trugen ein Symbol, das in diesem Raster schon etwas anderes bedeutet: Ändern Sie tabUUT verwendet GetApp, die Zeile-Level-Download-Taste, und Converted verwendet EditNote, die Zeilenebene Open-in-Editor-Taste. Sie tragen jetzt DesignServices und PublishedWithChanges. Die Panel-Überschrift innerhalb der Registerkarte Modify noch lesen "Vorbereiten Ausgewählt" in festcodiertes Englisch; es verwendet die Nachricht der Registerkarte, so dass die beiden nicht driften können.

  15. · kamo-internal

    Wählen Sie, auf welcher Seite ein Tracking-Link landet

    Ein Code ist nicht an eine Seite gebunden - die Marketing-Website erfasst es Website-weit - so dass die nur echte Frage, wenn eins teilen ist, wo der Besucher sollte landen. Das Produkt hatte keine Antwort darauf: das Mitglied bekam einen einzigen Link zur Homepage und musste Hand-edit eine URL, um jemanden zu Preisgestaltung zu senden, das ist genau dort, wo ein Tippfehler leise kostet eine Überweisung. TrackingLinkPicker bietet alle sechs Haustüren für einen Code, jeder einen Klick von die Zwischenablage: Haus, Preisgestaltung, Integrationen, das Early-Bird-Angebot, Kontakt und Buch eine Demo. Es öffnet den Moment, in dem ein Code geprägt wird - einen Link erzeugen und einen bekommen Sie können einfügen sind die gleichen Besorgungen und wieder aus dem Zeilenmenü, das jetzt liest "Get link" statt der URL der Homepage komplett zu kopieren. /Angebot ist absichtlich NICHT einer von ihnen. Es antwortet auf HTTP 200 und dient der "Nicht Gefunden" Seite, die die schlimmste Art von defekten Link ist: nichts berichtet es und die Besucher geht einfach. Die echte Seite ist /Preis/Angebot, und die Liste ist ein getippt Modul mit dieser Argumentation aufgeschrieben, so dass niemand fügt den schönen Pfad zurück. Die ganze Reihe ist die Taste - ein 24px Kopie-Symbol neben 400px von inert Text, der deutlich sieht anklickbar ist ein Ziel, das Menschen vermissen - und Bestätigung ist pro Zeile anstatt eines Toasts, denn ein Toast kann sechs nahezu unidentische Verbindungen nicht voneinander unterscheiden. Der Icon-Chip wechselt zu einem Check, eine Marke unterstreicht unter dem ?discount= Segment, und der Eingang Staffel ist gedeckelt, so dass die sechste Reihe ist nie spät genug um als langsamer Dialog zu lesen. Reduzierte Bewegung schaltet alles ab. Der eigene Erfolgszustand des erstellenden Dialogs ist damit verschwunden: Er zeigte einen Link und ist jetzt unerreichbar, so dass es und seine Importe entfernt werden, anstatt zu verrotten gelassen.

  16. · kamo-marketing

    Zeigen Sie ein Standing der Rolle statt eines grauen Pulses

    Fügt public/img/hero-still.webp hinzu, passend zur Blende 16/9 genau - und macht es, was der Held zeigt, bis jemand drückt spielen. Dies behebt auch einen Fehler, den die Tap-to-Play-Änderung eingeführt hat und ich verpasst habe. Die <video"-Element trug .opacity: reelWanted ? 1 : 0", das war richtig, während die Rolle von selbst gestartet: das Element erschien, sobald die Tore geöffnet, Plakat und alle. Mit der Wiedergabe jetzt auf einem Hahn gated, bleibt .reelWanted" für jeden falsch Besucher, der es nie presst - so war das Element, und damit sein Plakat unsichtbar für den gesamten Besuch und die Blende zeigte den Skelett Puls statt. Es Schlüssel auf dem Plakat ist jetzt bereit. Das Skelett ist dementsprechend reduziert auf das, was es immer sein sollte: die Lücke, bevor das Stillen kommt, anstatt etwas, das auf "Canplay" wartet, das nie unter feuert "preload="none""" bis zur Rolle gefragt wird. Drei kleinere Änderungen folgen aus dem Stillen Inhalt statt einer Platzhalter: · Lokal, nicht das Thema Eimer kommto13-poster.jpg. Für die meisten Besucher ist dies frame ist der Held für den ganzen Besuch, so dass es mit der App ausgeliefert. · Qualität 50, nicht 30. Dreißig wurde für etwas ausgewählt, das ein Video übermalt hat innerhalb einer Sekunde; Artefakte in diesem sind Artefakte in der Seite. Durch die Optimierer ist es 1.5-3.7 KB AVIF je nach Sprosse - die Quelle ist 22 KB von WebP. · Kein Leerlauf mehr. In-Blick verdient immer noch seinen Halt, weil auf einem schmalen viewport diese Blende befindet sich unterhalb der Falte unter der Kopie Spalte. Warten für den Hauptfaden, der darauf schweigen kann, war Vorsicht, die Multi-Megabyte-Video dahinter; so dass ein 2 KB Bild spät jetzt nur kommen bedeutet einen längeren Blick auf nichts. Verifiziert in Chrome: bevor das Plakat eingestellt ist, berechnet das Element Opacity 1, das Skelett ist abwesend und null Medienanfragen wurden gestellt; nach es, currentTime rückt 1.1 -" 3.6 - . 8.6s mit gedämpften falschen. Konsole und DevTools Probleme sauber, 22 Anfragen, alle Wachen passieren.

  17. · kamo-internal

    Bauen Sie den freigegebenen Link als ?discount=<uuid'

    buildTrackingLink sendet den neuen Parameter, und der Linkstreifen hebt die ?discount= Segment, das es verwendet, um als ?mrt= zu markieren. Das Token selbst ist jetzt ein opaque UUID geprägt Server-Seite, so dass nichts hier leitet oder formatiert es. Auch ein Keyframe und eine Schubladen-Titel-ID, die noch das alte Präfix trägt umbenennt.

  18. · kamo-register

    Lesen Sie die Rabatt-Cookies und senden Sie die Rabatt* Felder

    Folgt der Marketing-Seite: kdsc_vid / kdsc_src, mit ?discount= als query-param fallback für einen Besucher, der auf dem Registerformular mit dem Link landet noch in der Adressleiste. Die Körperfelder werden DiscounterVisitorGuid / DiscountCode; SecurityService liest beide Namen für eine Veröffentlichung, so dass die beiden Entfaltungen müssen nicht gleichzeitig sein.

  19. · kamo-marketing

    Der Empfehlungsparameter ist ?discount= und das Token ist eine UUID

    Der Link, den ein Mitglied teilt, ist **************** Es war ?mrt=<memberId?.<iteration, die eine echte Mitglieder-ID in jede freigegebene URL eingefügt hat und Lassen Sie jemanden die anderen Kampagnen dieses Mitglieds aufzählen, indem er von .1. Der Validator ändert mit ihm die Form - ein UUID-Muster anstelle von Ziffern-Punkt-Zahlungen und macht weiterhin die Arbeit, für die es hinzugefügt wurde: validieren, nie abkürzen, weil Das schneiden mit UTF-16 Code Unit kann ein Surrogat-Paar halbieren und encodeURICom-Komponente wirft URIError auf eine einsame Leihmutter innen Middleware(), die eine 500 auf der ist Seite. Hex und Bindestriche können keine Leihmutter ausdrücken. Cookies folgen dem Vokabular: kmrt_vid/kmrt_src werden kdsc_vid/kdsc_src, die Leuchtfeuer ist DiscountBeacon, der Sammler ist /api/discount und die Wache ist check-discount-cookie. Half-Renaming hätte einen ?discount= Parameter hinterlassen gespeichert in einem kmrt_ Cookie gelesen von MrtBeacon, die genau die Drift, die Kosten ist jemand eine Stunde später. Die Cookies vor Stunden verschickt, so dass fast keine in der Wild zu verwaist. Garde-Fixtures behaupten nun die neue Form und, speziell, dass die OLD memberId.iteration Form wird abgelehnt.

  20. · SecurityService

    Akzeptieren Sie die Rabatt* Anmeldefelder, halten Sie die mrt* am Laufen

    Die Register-Website sendet jetzt RabattVisitorGuid / DiscountCode. Beide Namen sind Lesen, neu zuerst, weil die beiden Dienste unabhängig einsetzen - für die Minuten zwischen Rollouts eine Seite spricht immer noch die vorherigen Wortschatz, und die Kosten zu bekommen, dass falsch ist eine Anmeldung, die still verdient seine Referrer nichts. Der mrt* Fallback kann gehen, sobald beide Seiten für eine Freigabe aus waren.

  21. · MediaService

    Mint ein opessige UUID Token, in einem Einsatz

    createCode erzeugt das Token selbst, so gibt es nichts zu lesen und nichts für zwei Tabs zu kollidieren. Das entfernt den ganzen Apparat der alte Sequentielles Token erforderlich: die max(iteration) + 1 lesen, die Kollisions-Erkennung versuchen, und die REQUIRES_NEW TransactionTemplate, die Retry benötigt, weil ein unique_violation bricht die Transaktion ab, bei der es auf YSQL passiert ist. One save, done. Eine UUID-Kollision ist kein Fall, für den es sich lohnt, Code zu schreiben; der einzigartige Index auf CODE bleibt als Backstop so ein unmöglicher scheitert laut statt leise die Zuordnung von zwei Mitgliedern Verkehr auf eine Reihe.

  22. · kamo-shared-library

    Machen Sie das gemeinsame Token zu einem undurchsichtigen UUID

    Das öffentliche Token war <memberId?.<iteration", was in zweierlei Hinsicht falsch war. Es veröffentlicht eine echte Mitglieds-ID in jedem Link, den Sie auf einer Visitenkarte haben, eine E-Mail-Signatur, im Posteingang von jemand anderem - und es hat den ganzen Raum gemacht begehbar: ein Link sagte Ihnen das Mitglied, und Zählen von .1 aufgezählt ihre andere Kampagnen. Ein Konkurrent konnte sehen, wie viele jemand läuft, und jeder könnte schmieden einen plausiblen Code für ein Mitglied, das sie nie getroffen hatten. CODE enthält jetzt eine zufällige UUID und der URL-Parameter ist ?discount=. Die Spalte, seine Länge und sein einzigartiger Index sind unverändert; nur das, was in ihm geht, bewegte sich. ITERATION und uq_mtc_org_member_iter sind damit verschwunden. Ihr einziger Job war Sequenzierung dieses Tokens, und Sequenzierung ist, was gezwungen max(iteration) + 1 . Lesen-then-schreiben zwei Registerkarten können beide gewinnen, die eine einzigartige Einschränkung benötigt, um zu fangen, ein erneuter Versuch, sich zu erholen, und dass in einer BRAND-NEW-Transaktion wieder versuchen, weil ein unique_violation bricht die Transaktion ab, bei der es auf YSQL passiert ist. Alles existierte eine Zahl zu verteidigen, die niemand braucht. Eine UUID hat nichts zu kollidieren; die einzigartige Index auf CODE bleibt der Backstop. Das Token ist absichtlich immer noch eine Spalte und nicht die primäre Schlüsselzeile, sogar obwohl beide UUIDs sind. Sie auseinander zu halten ist, was eine Verbindung wiederveröffentlichbar macht: ein Token die abgekratzt, gespammt oder auf dem falschen Flyer gedruckt wird, kann an Ort und Stelle ersetzt werden während die Besucher, Veranstaltungen und Konvertierungen bereits an der Reihe angebracht bleiben, wo sind sie und hält die id die authentifizierten API-Adressen aus öffentlichen URLs heraus.

  23. · InitializerService

    Ruhestand ************

    Tracking-Codes werden jetzt als ?discount=<uuid" geteilt. Der alte <memberId?. veröffentlichte eine reale Mitglieds-ID in jedem gemeinsamen Link und machte den Raum begehbar ein Link namens Mitglied, und Zählen von .1 aufgezählt ihre andere aufgezählt Kampagnen - so bewegte sich das öffentliche Token zu einer undurchsichtigen UUID im bestehenden CODE column und ITERATION hat keine verbleibende Aufgabe. Das kann nicht auf Hibernate warten: ddl-auto fügt Spalten hinzu und lässt sie nie fallen, und ITERATION ist NICHT NULL. Die Entität stoppt Mapping es in der gleichen Änderung, so von in dem Moment, in dem die neue gemeinsame Bibliothek jedes INSERT eine Spalte auslässt, die Tabelle noch Forderungen. Dropping ist es, was den Mint-Pfad überhaupt schreiben lässt. Die zusammengesetzte einzigartige Einschränkung geht mit ihm - es existierte nur, um zwei zu stoppen Gleichzeitige Minzen unter der gleichen iteration, und eine zufällige UUID hat nichts zu kollidieren. Bestell 0 aus dem üblichen Grund hier: jeder Läufer, der eine lädt Die Marketingeinheit sendet die abgebildeten Spalten in ihrem SELECT aus.

  24. · kamo-marketing

    Servieren Sie eine echte pro-Antfocht CSP nonce mit streng-dyna

    löscht beide verbleibenden High-Befunde auf Script-Src: die 'unsicher-inline' ein und "Host-Genehmzlisten können häufig umgangen werden". Nur ein Nonce mit 'streng-dynamisch' löscht diese, und Next kann nicht liefern ein auf Vorgeschriebene Seite - ein Nonce muss pro Antwort eindeutig sein, so dass Next emittiert eine nur während des Renderings, und eine vorgerenderte Route wird aus dem Vollstrecken-Cache serviert ohne Rendering. Der dokumentierte Workaround soll jede Route dynamisch machen, die die statische Darstellung rückgängig machen würde, von der diese Seite abhängt und zusammenbricht <Link&gt; Pre holen Sie sich zu einem kappen Route Baum. So wird die Nonce angewendet, wo die Bytes den Prozess verlassen. server-nonce.js beginnt der eigenständige Server auf Loopback, dient dem öffentlichen Port selbst und stempelt jeweils HTML-Antwort auf dem Weg nach draußen. Next hält prerendering und hält dienen von seiner eigener Cache; durch den Wrapper gemessen, /en/Preis noch Präfetches 77.521 Bytes mit 23 Stück Referenzen und Antworten x-nextjs-cache: HIT. Statisches Rendering und eine echte rotierende Nonce, beides. 'streng-dynamisch' ist, was die Genehmigungsliste finden zurückzieht: Browser ignorieren Host erlaubte Listen und vertrauen Skripte, die von bereits vertrauenswürdigen Skripten erstellt wurden. Die Chat Widget und der Analytics Tracker werden von Next/Script zur Laufzeit injiziert, so dass sie sind transitiv vertrauenswürdig und brauchen keine zulässige Eintragung überhaupt. 'unsicher-inline' und https: bleiben nur als der dokumentierte Fallback für Browser zu alt, um zu verstehen nonces, die weder ignorieren und vorher nichts bekommen haben. Drei Dinge, die sich herausstellten, von denen nichts von der config: · Die Weiterleitung der Anfrage CSP vor der Reihe ist eine Falle. Als nächstes liest ein Nonce daraus und stempelt seine eigenen Skripte - dann geht dieser Render in den Full-Route-Cache mit der Nonce eingebacken, so dass jeder spätere Besucher 96 Tags mit einem Toten bekommt nonce. Unter 'streng-dynamisch' verschleiert eine abgestandene Nonce nicht, sie blockiert: eine unbeschriebene Seite bis zum Ablauf des Eintrags. Der Antrag CSP wird stattdessen abgestreift, und jedes vorbestehende Nicht-Attribut wird vor dem Stempeln entfernt. · Rewriting der Upstream Host zu Loopback Pausen umgeleitet. Next Builds Absolute Umleitungs-URLs von Host, also beantwortet Lage: http://localhost:41337/de. Der Host wird unverändert weitergeleitet, und eine Umleitung, die auf unseren eigenen Loopback zeigt, ist auf einen Pfad als Versicherung zusammengebrochen. · Kompression musste sich bewegen. Upstream wird nach Identität gefragt, damit das HTML neu geschrieben, ohne eine dekomprimieren/rekompressive Rundreise, und die Verpackung re-komprimiert . brotli, wo der Kunde es nimmt, das ist 30.177 Bytes gegen den zuvor servierten 56.324 gzip. scripts/check-csp-nonce.mjs hält den Vertrag bis Ende auf jedem Build: Stiefel die gebaute App hinter dem Wrapper und behauptet, der Kopf trägt eine nonce und 'streng-dynamisch', dass JEDE Skript-Tag trägt eine Nonce, dass alle von ihnen sind dass die Antwort ist, und dass es zwischen Anfragen dreht. Es fing die zwischengespeicherte-Nonce Bug auf seiner ersten Lauf. Eine feste Nonce würde die Prüfung erfüllen und lesbar sein von jedermann, so dass die Rotationsprüfung ist der Punkt und nicht eine Formalität. Speicheranforderung 128Mi - 256Mi: HTML wird gepuffert, um gestempelt zu werden, also jetzt Peak-Speicher Skalen mit gleichzeitigen HTML-Anfragen statt flach sitzen.

  25. · kamo-marketing

    Beforce Trusted Types, Pfad-Skop die Script allowlist

    löscht die "No Content-Security-Policy Header mit Trusted Types Richtlinie finde" Befunde, indem man bedarfsvertrauenswürdige Typen in die erzwungene Politik einbewegt. Dies ist eher eine Beweis-unterstützt als eine zweite Vermutung. Es versendet Bericht-nur zuerst und die Konsole kam zurück mit ZERO Trusted Types Verletzungen, die ist genau der Beweis nötig: Nur Report-Logs eine Verletzung für jede Spüle erreicht ohne eine Richtlinie, so dass keine Verletzungen bedeutet, dass die Standard-Politik wurde im Voraus installiert von allen. Was machte das wahr war fallen nächste / Skript für eine einfache Inline <script' in <head&gt;. check-trusted-types-order.mjs hält die Platzierung. Auch verengt Script-Src von Hosts zu Pfaden, die die "host allowlists can can häufig umgangen werden" Befund wörtlich genommen. Auf theme.kamocrm.com, das war nicht hypothetisch: es ist die Org-Themen-Eimer, White-Label-Mieter laden ihre eigene Vermögenswerte in sie, und "script-src https://theme.kamocrm.com" daher lassen jede Die Pächter legen eine .js-Datei in ihren eigenen Eimer und lassen Sie diese Seite ausführen. Nur /public/widget/ ist jetzt ausführbar - der Lader und sein gehed Bündel sind beide live gibt und die Analytik wird auf die genaue Tracker-Datei gepinnt.

  26. · kamo-internal

    Zeigen, wann der Kredit eines Besuchers in einen anderen Link umgezogen ist

    Die Timeline erhält ATTRIBUTION_MOVED, im Warnton - keine Konvertierung und nicht ein Versagen, aber der Moment, in dem dieser Besucher aufhörte, dieses Mitglied zu verdienen, die es wert ist, bemerkt zu werden. Die Event-Typ-Gewerkschaft gewinnt den Wert, so dass das Label löst, anstatt sich auf die Seite-Ansicht-Wörter zu verfallen.

  27. · MediaService

    Bewegen Sie Kredit auf eine neuere Verbindung, und erfassen Sie den Moment, in dem es sich bewegt

    Der Eingenommene Arbeiter ruft jetzt reattributeWhileAnonymous nach den Verkehrsbeulen. Die Repository-Methode trägt die gesamte Regel, so gibt es nichts zu überprüfen hier und kein Fenster zum Durchrennen: eine Rückkehr von 1 bedeutet Kredit wirklich verschoben, um die Link dieser Besucher kam gerade auf, 0 bedeutet, sie kamen wieder auf der gleichen oder sie haben bereits ein Konto und ihr Sponsoring-Mitglied hält sie für immer. Nur der zugeschriebene Code bewegt sich. Die Besuchs- und Seitenanfrage-Beulen haben bereits gutgeschrieben der Code, der diese Seiteview serviert, die wahr bleibt jedoch Namensnennung landet. Ein Umzug schreibt eine ATTRIBUTION_MOVED-Reihe auf die Zeitleiste des Besuchers, nach der Seite Ansicht, so dass die beiden in der Reihenfolge lesen sie passiert. Es ist das einzige Ereignis in diesem Funktion, die ändert, was ein Mitglied geschuldet ist, ohne dass jemand etwas falsch macht, so lohnt es sich, direkt zu sagen, anstatt zu verlassen, um später gefolgert zu werden. Der Anmeldehandler löst den Code auf dem Umschlag und, wenn er einen Live-Namen nennt eins, stempelt das Konto und begleicht die Namensnennung in der gleichen Erklärung. Das ist der Fall, den das Leuchtfeuer völlig verpassen kann - untätig-aufgeschoben, höchstens einmal pro Seitenansicht, und ein Besucher kann einem Link folgen und direkt zum Anmeldeformular gehen. Ruhestand Codes lösen zu Null und lassen Sie die Zuordnung in Ruhe, so dass ein Link, der aufgehört zu verdienen Kredit durch die Leuchtfeuer kann nicht beginnen, es wieder durch die Anmeldetür zu verdienen.

  28. · kamo-shared-library

    Gutschriften Sie den neuesten Link, bis ein Konto existiert, dann einfrieren

    Attribution wurde auf den ersten Blick eingefroren, was den gemeinsamen Fall falsch bekommt: jemand wer folgt Mitglied A Link im März und Mitglied B's im Juni, und nur dann unterschreibt up, wurde von B gebracht. First-Touch zahlt A für einen Besuch, der nirgendwo geführt und zahlt B nichts für die, die umgewandelt, und keine nachgelagerte Arithmetik kann eine Eine Zuschreibung, die einfach falsch ist. So folgt Kredit jetzt dem neuesten Link der Besucher kommt auf - für genau wie solange sie anonym sind. Sobald ein Konto existiert, hört es auf, sich dauerhaft zu bewegen. Das ist die Hälfte genauso wichtig: das Sponsoring-Mitglied hat es verdient, und wenn ein später Link könnte immer noch Kredit bewegen, dann könnte jedes Mitglied eines anderen Kunden nehmen indem sie einmal klicken, während org-created und wurde-bezahlt - welche Land Wochen nach der Anmeldung würde zu wem auch immer, der zuletzt eher angeklickt wurde als wer auch immer tatsächlich den Kunden hereingebracht hat. reattributeWhileAnonymous trägt die ganze Regel in einem bedingten UPDATE (verschiedener Code UND signiertUpAt IS NULL UND userId IS NULL), so gibt es keine Lese-thunn-Schreibfenster für zwei Leuchtfeuer, oder ein Leuchtfeuer und die Anmeldung selbst, um Rennen durch. Die "<" auf der Code-ID hält sie für echte Züge, die die Caller behandeln eine Rückkehr von 1 als "Kredit tatsächlich den Besitzer gewechselt" und notieren Sie es. markSignedUpAttributedTo begleicht das Konto und den Kredit in einem einzigen Aussage, Schließen des einen Fensters, das der Einnahmepfad nicht kann: das Leuchtfeuer wird aufgeschoben im Leerlauf, so dass ein Besucher, der einem zweiten Mitgliedslink folgt und geht direkt auf die Anmeldeformular kann sich anmelden, bevor eine Beacon-Berichte, die besuchen. Die Zähler bleiben sicher, weil der Freeze und der erste Umbau gleich sind Moment - bis eine *_AT-Spalte gestempelt werden kann, ist die Zuordnung bereits festgelegt für das Leben des Besuchers. Verkehr ist so oder so unberührt: Besuche und Seite Anfragen gehören zu dem Code, der ihnen gedient hat. EVENT_TYPE gewinnt ATTRIBUTION_MOVED so ein Mitglied, dessen Besucher zu jemandem gewechselt ist Die Verbindung der anderen kann genau sehen, wann es passiert ist, anstatt es von einem zu schlussfolgeren Code-ID, die leise unterscheidet.

  29. · kamo-internal

    Windows Desktop und Master-Maschine in Platform Admins verschieben

    Beide sind Guacamole Ziele, die einen Ausweis zwischen allen teilen, die macht sie Operator-Tooling statt eines Mitglieds eigenen Arbeitsbereich. Sie waren Top-Bar Navi-Optionen gated on ctx.isGod, so dass jeder Gott trug zwei Symbole für Maschinen, die sie selten berühren, beide schleppbar, unpinnierbar und durchsuchbar in die Befehlspalette wie eine gewöhnliche Funktion. Sie machen nun zwei Tasten links von "Plattform Admin hinzufügen" auf Einstellungen -" Platform Administration -- Plattform-Admins, neben der dev-machine kontrolliert, dass bereits das dritte KamoDesktop-Ziel verwaltet wird. Das Tor ist "caller.isGod" aus der eigenen Nutzlast des Tabs - die Anzeige des Servers von "users.is_god", nie eine Client-seitige Ableitung - und DesktopSsoController noch erfordert Gott für sich, so dass die Tasten nur eine Antwort spiegeln, die der Endpunkt gibt unabhängig. DesktopLinux bleibt im Navi: Es ist pro Person und persönlich. Entfernen der beiden Registry-Einträge entfernt ihre Navi-Platzierung, ihre Startrampe Karten, ihre Paletteneinträge und ihre Aktionstasten; lösenNavLayout bereits Tropfen gespeicherte IDs, die nicht mehr existieren, so dass ein Mitglied, das sie angeordnet hatte, hält eine gültiges Layout ohne Migration. Der devMachineGate Test behauptet jetzt, dass sie abwesend statt gottgefällig.

  30. · kamo-marketing

    CSP und COOP durchgesetzt; Trusted Types Bericht-only

    Re-lands die Security Headers, nachdem ich nahm die Website mit ihnen, abzüglich der eine Direktive, die es getan hat, plus eine Build Wache, so dass es nicht wieder passieren kann. WAS BROKE. "Vertrauenswürdige-Typen-für "Script" ist nur überlebensfähig, wenn eine Politik Der Name "default" existiert vor dem ersten DOM-Sinkfeuer. Meine lief nie. Die die Richtlinien wurden von app/[locale]/layout.tsx, die wie ein Root-Layout aussieht und ist nicht - es gibt eine App/layout.tsx darüber - und "next/script" strategy="beforeInteractive"" - wird nur in der wahren Wurzel geehrt. Nächste Downgrades es woanders ohne Vorwarnung. So die Seite geladen, Hydratation gestartet, und jeder sinke: Reagieren-Dom auf "innerHTML", Turbopacks Stückladeer auf "script.src", neun TrustedScriptURL Ablehnungen, dann Nexts Client-seitiger Fehlerbildschirm. Meine Argumentation war, dass kein Waschbecken konnte vor der Politik feuern, weil alle 78 Flugdaten-Schuss sind im Körper. Das war die falsche Frage. Der Rahmen ist eigene Tags werden in <head" gehievt und ausgeführt, sobald sie Download - sie warten nicht auf den Körper, und sie sind diejenigen, die geworfen. MOVING IT zu den REAL ROOT DID NOT FIX IT. Gemessen, nicht angenommen: app/[locale]/layout.tsx policy @ 12,678 first async script @ 1.593 app/layout.tsx (root) policy @ 12.678 first async script @ 1.730 React Hebt "<script async src" über alles, was ein Layout gibt, so gibt es keine Position im Baum, der gewinnt. Die verbleibenden Optionen sind schlimmer als die Problem: Das Umschreiben des HTML-Streams in Middleware setzt eine pro Anfrage transform in Vorderseite jeder vorgerenderten Seite und bricht Streaming, und eine nicht-ce-bearing CSP benötigt Header(), die ca. 200 Routen von statischen Renderings abwirft und die Die Vorabentscheidung dieser Seite hängt davon ab. So Trusted Types Schiffe als ************ Die Direktive ist eingesetzt und Verstöße sind sichtbar; ein Report-only-Header kann nichts blockieren. Der Leuchtturm-Artikel bleibt rot, und das ist der ehrliche Zustand eher als ein Pass-Through-Politik, die es grün machen würde, während nichts zu schützen. Die Wache ist die echte Lieferung. **************** versagt die Build, wenn die Richtlinie durchgesetzt wird, während die Politik nach der emittiert wird zuerst async Framework-Skript und druckt die beiden Offsets und den Fix. Es läuft weiter Vorbau und im npm Test. Nichts an diesem Versagen ist sichtbar für Typen, lint oder der Build - nur die kabellose Reihenfolge des ausgestrahlten HTML-Datensatzes - weshalb es einen überprüfen Sie eher einen Kommentar. Erzwungen und verifiziert gegen den realen Standalone-Server: CSP ohne Trusted-Typen-Richtlinie, COOP gleicher Herkunft, Referrer-Politik, X-Content-Typ-Optionen. Geprüft die servierte Seite Ressource durch Ressource gegen die fertige Richtlinie: Null blockiert, und 'unsafe-inline' umfasst alle 86 Inline-Skripte.

Euer Universum wartet.

Fügen Sie Produkte hinzu, wann immer Sie möchten – keine Migration, keine neuen Anmeldungen.

Für immer kostenlos – keine Kreditkarte erforderlich