Changelog
Was ist neu?
Jede Verbesserung an der Plattform, wie sie geliefert wird.
· kamo-internal
Ein "Warum kann ich nicht akzeptieren?"-Rede auf der Filterleiste
Rechtsgerichtet auf der /leads Filterleiste, mit dem Leads nist icon mit dem gleichen Verbot Emblem - so die Sache auf dem nive, dass sagt "Sie sind blockiert" und die Sache hier, die "hier ist der Grund" sagt, sind sichtbar eine Aussage. Nur gerendert, während das Mitglied tatsächlich blockiert wird. Es ist kein Filter, der passiert, leer zu sein, ist es ein Zustand, der entweder existiert oder nicht, so dass, wenn die Verbot klärt - eine Echtzeit-Akzept-Gate-Veranstaltung, oder eine Auffrischung nach dem letzten Notiz wurde geschrieben - die Steuerung verschwindet und die Filter kommen wieder auf ihre eigenem. Ein Effekt lässt den Override fallen, wenn das passiert: es verriegelt lassen würde das Gitter auf einem "uid IN", das nichts passt, mit den Filtern noch ergraut und keine sichtbare Kontrolle links, um sie wieder einzuschalten. Gedrückt, es OVERRIDES anstatt schmal. buildLeadGridQuery kehrt früh zurück blockingLeadUids, also keine Marktkarte, Status-Registerkarte, Agent, Datum oder Suchbegriff gilt. Das ist absichtlich: Die blockierenden Leitungen sind über was auch immer verstreut Märkte und Status, in denen sie sich zufällig befinden, und sich mit der Bar würde sich kreuzen zeigen Sie eine Teilmenge beim Lesen als die ganze Liste - genau das Falsche zu sagen Jemand versucht, sich zu lösen. Ein leeres Set fragt nach "uid=0" statt fallenlassen die Beschränkung, so kann es nie auf die Organisation zu erweitern. Die Status-Tabs und jede Kontrolle auf der Bar sind ergraut und inert gemacht, während es ist auf, weil eine Bar, die noch live aussah, darüber lügen würde, was die gewählt hat Reihen. Das Klinken selbst wird durch Attribut ausgeschlossen, so dass es druckbar bleibt, und die Aktionstasten neben den Tabs sind keine Filter, so dass sie live bleiben. Paging-Resets auf jedem Umschalten - der Ergebnissatz ist ein anderer und die alte Seitenzahl bedeutet nichts dagegen. Aus, die Taste pulsiert: Es ist die eine Sache auf der Leiste, die ein blockiertes Mitglied hat Hinweis, denn es ist, warum ihre Leitungen haben aufgehört zu kommen. Auf, das Netz selbst ist das Signal und die Animation wäre Rauschen. Ehrungen bevorzugt-reduzierte-Bewegung.
· SecurityService
Liste, Umbenennen und Enden der Terminals eines Mitglieds
GET ************ DELETE und PATCH on /terminals/{id'. Jeder von ihnen löst das Linux-Konto von der CALLER'S OWN SESSION und gibt keinen Kontonamen an den Agenten weiter, der von der Anfrage stammt. Ein Mitglied kann also immer nur ihre eigenen Terminals sehen, umbenennen oder beenden - es gibt keine ID könnte liefern, die jemand anderes erreichen würde, weil das Konto nicht Teil von was sie liefern. Eine unerreichbare Maschine beantwortet 200 mit einer leeren Liste und "unerreichbar: wahr". eher als ein Fehler: "die dev-Maschine ist unten" ist eine Tatsache über die Maschine, nicht ein Ausfall der Frage, und die Konsole kann so sagen, wo eine Fehlerseite könnte Nur nichts sagen. Das ist die gleiche Regel, die DesktopSsoController folgt. Die Umbenennung einer Sitzung, die beendet ist, ist ein 404 mit einem Satz - der ehrliche Status für "Sie umbenannt etwas, das nicht mehr da ist", die nach einem Neustart ist jedes Terminal, das das Mitglied hatte.
· KlusterServices
Liste, Umbenennen und Enden der Terminals eines Mitglieds
GET /terminals?user=X, POST /terminals/<id'/kill, POST /terminals/<id'/title. THERE IS NO DATABASE BEHIND THIS, und das ist das Design und nicht eine Abkürzung. Der tmux-Server auf der Maschine IST die Registrierung: Die Terminals eines Mitglieds sind genau die Sitzungen, die existieren, so dass eine, die endet, wird nicht mit nichts zu aufgeführt Versöhnen und ein Neustart, der den tmux-Server damit nimmt, leert die Liste von selbst. Ein Tisch müsste all das gesagt werden, und wäre falsch jeder Zeit war es nicht. Individuelle Titel leben in einer tmux Benutzeroption auf der Sitzung, so dass ein Titel die gleiche hat Lebensdauer wie die Schale, die es nennt. Steuerzeichen werden vor der Lagerung abgestreift: ein Titel wird in einer Liste wiedergegeben, und eine Escape-Sequenz in einem würde die Bildschirm um ihn herum - Strippen ist auch, was hält die Feldtrennung aus der Wert, das ist, was macht die Auflistung parseable durch Aufspaltung auf sie. Titel sind übergeben als ein einzelnes Arv-Element, nie durch eine Shell. "No tmux server" ist eine leere Liste, kein Fehler. Das ist der Zustand der Maschine nach einem Neustart, das ist genau, wenn das Mitglied die Liste benötigt, um zu sagen "nichts hier" und nicht zu versagen. 20 Tests: die Auflistung Form und seine Reihenfolge, unbetitelte Sitzungen Berichterstattung null anstatt "", Sitzungen dieser Agent nicht schaffen, unsichtbar zu bleiben, missgebildet und nicht-numerische Reihen übersprungen, anstatt tödlich, töten, ob idempotent, Titel werden abgestreift/truncated/unset und ein Titel mit Shell-Metafiguren als ein Arv-Element ankommen. Auch schützt Pumpe wählen gegen einen Deskriptor unter ihm geschlossen - der gleiche gewöhnliche Aufhänge-Ende der recv Pfad bereits behandelt. 131 Tests.
· kamo-internal
Eine Passwort-Shortcut in der Held, und ein schmaleres Tor
Zwei Hälften des gleichen Themas. Die Abkürzung. Ändern Sie Ihr Passwort war drei Zimmer tief hinter der Schiene die eine Sache, die die Raumaufteilung wirklich schwerer zu erreichen als die alte scrollen, und es ist die folgenreichste Kontrolle des Kontos. Der Held jetzt trägt es, absichtlich NICHT als dritte Glaspille: die beiden daneben sind Reiseziele, das ist eine Aktion, also ist es solide. Wenn Multi-Faktor ausgeschaltet ist es wird Bernstein und sagt so, denn das ist der Moment, in dem die Aufforderung wert ist machen. Es leitet durch den gleichen Fokuspfad, den die Befehlspalette verwendet, so dass es sich öffnet Der Zugangsraum UND scrollt die Passwortkarte ins Blickfeld. Dieser Weg ist jetzt eine Funktion, die von der Palette, dem Kraftring und dieser Verknüpfung geteilt wird, anstatt drei, die driften könnten; die Segmente des Ringes bereits benannt Feld, das sie behebt und jetzt tatsächlich verwenden. PasswordSecurityCard ist kein ProfileCard, so dass sein Wrapper den Scroll-Anker trägt. Das Tor. MANAGE_MEMBER_SECURITY zeigt die Passwortkarte nicht mehr an die Aufzeichnung von jemand anderem - nur das Mitglied selbst oder ein Gott-Berechtigter Zuschauer. Dies ist die DISPLAY Hälfte; die Hälfte, die Angelegenheiten in geliefert SecurityService 197b591, der 403 für die gleiche Bedingung zurückgibt. Ein Recht von einem Bildschirm entfernt ist ein aufgeräumterer Bildschirm, keine Sicherheitskontrolle. Wörterbuch-Schlüssel landeten zuerst in kamo-translation-dictionary 982c1f62. Verifiziert: npm Test (14 Wachen + 5.139 Tests), tsc --noEmit, next build.
· kamo-internal
Verbotene nist Emblem, Zuweisen zu mir selbst, und verschleierte Kontaktmaske
**Das Leads nist icon sagt, wann Sie nicht akzeptieren können.** Ein Mitglied, das Leads hält sie haben nicht gearbeitet hat einen roten Block Emblem über dem Leads Symbol und eine Tooltip Benennen, was blockiert ist, warum und was zu löschen. Fed by /leads/ availablesummary und live gehalten durch eine neue Akzept-Gate-Ereignis auf dem Kredit-/Zugabe-Sockel Nutzlast trägt nur eine Mitglieds-ID, so dass jeder Browser ignoriert jeder andere und . Gezeigt jedem Mitglied, das Leads sehen kann, nicht nur Kreditinhaber: seit Free-for-all-Leitung kann jetzt selbst beansprucht werden, das Tor regiert sie auch. Die Verfügbarkeit dot bleibt Kredit-nur, so dass die beiden Aussagen trennbar bleiben Sie können von der Annahme blockiert werden, während Leads sitzen dort verfügbar, und die sind verschiedene Dinge zu sagen. **Jeder Status wird so genannt, wie DIES oder Weise ihn benennt.** Der Tooltip, der /leads/verfügbare Ankündigung und die Detail-Seite Kopie lösen New Lead / Farm Fresh durch VerwendungStatusLabels: Etiketten sind auf /settings/features/crm austauschbar und Ein Mitglied zu sagen, eine Führung von "New Lead" zu bewegen, wenn ihre Org es etwas nennt Einen Status nennen sie im Picker nicht. **/Leads/Verfügung von Mitteilung teilt sich in zwei Gründe** . Leads oweded a note, Leads schuldeten eine Statusänderung, weil sie zu einer Liste verschmolzen, die sie als undifferenzierter Stapel und das Mitglied muss jede Führung öffnen, um zu lernen, was es will. Ein Bleiversagen beides wird einmal aufgelistet, betitelt. **Assign zu Myself** sitzt unter Hot Reassign auf einer nicht zugewiesenen Leerführung. Angebot auf einem free-for-all führen zu jedermann nicht derzeit gesperrt, und auf jede nicht zugeordnete führen, ein Inhaber von ASSIGN_LEADS. Die Antwort trägt die Führung zurück entlarvt, so Einstellung in Zustand Flips zugewiesenToMe, recomputiert die Maske Entscheidung zu UNMASKED, und zeigt die Kontaktinformationen ohne Reload. **Die Statuskontrolle pulsiert**, während die Führung ab mir ist und noch bei New Lead oder Farm Fresh - das ist die Kontrolle, die es repariert, und die Kopfzeile ist lange gelesen vor einer niv-Tooltip. Ehrungen bevorzugt-reduziert-Bewegung. **Masked Kontaktinfo ist verschleiert, nicht ausgeblendet.** contactObfuscator.ts spiegelt der KontaktObfuscator des Servers genau, der die gleichen Zeichensätze geltend macht, weil Echtzeit-Lead-Relais liefert eine voll unmaskierte DTO an jeden Teilnehmer in der Org und der Browser ist das einzige, was davor steht. Ein leeres Feld liest als "dieser Leist hat keine E-Mail", was eine andere und falsche Aussage ist. **Der /leads Unassigned Filter wird für jedermann angeboten.** Ohne VIEW_UNASSIGNED_LEADS es gibt die nicht zugewiesenen free-for-all führt dieses Mitglied zurück kann behaupten, und das Etikett sagt so eher als die Option leise bedeutet zwei verschiedene Dinge. Der Client zwingt nicht mehr zugewiesen=ASSIGNED für diese Mitglieder - die Server-Etage ist breiter als das jetzt, und senden würde ASSIGNED senden würde Clip genau die Zeilen diese Änderung zu zeigen existiert.
· SecurityService
Servieren Sie das erweiterte Akzeptor, fügen Sie Selbstverfügung hinzu und schließen Sie zwei Kontaktmasken-bypass
**Endpunkte für das neue Gate.** /bles/verfügbare-summary und /leads/verfügbar jetzt berichten beide Gründe ein Mitglied blockiert ist - Leads schuldete eine Notiz, da sie waren zugeordnet, und führt noch an ihrem Aufnahmestatus - mit den Leads selbst und die SYSTEM Status-Wiedergabe plus Iden, damit der Browser die eigene org auflösen kann eigene Etiketten, bevor jemanden den Grund, warum sie stecken. blockedByComments wird als Alias für das neue "verboten" gehalten, so dass ein Browser noch mit der vorheriges Bündel arbeitet weiter durch den Einsatz. Das Tor wird für jeden ausgewertet, der Leads sehen kann, nicht nur Mitglieder, die halten SPEND_RECEIVE_LEAD_CREDIT: Ein Mitglied, das nur einen Free-for-all-Lead beanspruchen kann, ist unterliegen der gleichen Disziplin und ihr nist muss in der Lage sein, dies zu sagen. Die Credit-Pool-Scan darunter erfordert noch das Kreditrecht. **POST /leads/{id'/assign-to-me** behauptet eine nicht zugeordnete Leine. Es gibt den Vorsprung zurück UNMASKED - der Anrufer ist sein Bevollmächtigter, wenn der Server antwortet - das ist was lässt die Detail-Seite zeigen die Kontaktinformationen ohne eine erneute laden. **Ein neues NATS-Thema, ************ veröffentlicht, wenn eine Notiz landet an der Leine, wenn sich der Status ändert, und auf beiden Seiten jeder Aufgabe Veränderung. Das Relais von MediaService abonnt bereits security.leads. Themen allgemein, so dass es keine Änderung braucht. Die Nutzlast trägt nur eine Mitglieder-ID: die Antwort des Gates hängt vom ganzen Buch dieses Mitglieds ab, also gibt es nichts Nützliches, um ein org-weites Thema aufzusetzen, und ein Thema, das jedes Mitglied erhält ist der falsche Ort für alles, was es wert ist, zurückgehalten zu werden. **Zwei Kontaktmasken-Bypasses, beides gefundene Auditing, bei denen die Angaben eines Leads die Angaben machen können einen Browser erreichen:** - GET /leads/{id'/History hatte überhaupt keine Zuordnung oder Kontakttor. Ein Feldwechsel Log ist eine vollständige Aufzeichnung von jedem Wert ein Feld jemals gehalten hat, so dass es zurückgegeben die E-Mail- und Telefonnummern, die die eigene Maske des Leads herausnimmt und nicht nur die Aktuelle, jeder vorherige auch. Es trägt jetzt die gleichen zwei Entscheidungen wie getLeadById, und LeadHistoryContactMask verschleiert die Kontakt-Bär-Reihen. Status, Zuordnung und Leihbau-Geschichte sind unberührt: Dies hält sie zurück Kontaktinformationen, nicht der Audit-Trail. - GET /leads/callback-context/{id' hat eine E-Mail-Adresse und zwei Telefone verschickt Zahlen für jeden Rückruf in der Org, ungeeignet. Eine Rückruf-ID war eine Möglichkeit zu lesen die Kontaktdaten der Führung eines Kollegen. **Ein Rele-Back-Wericht auf updateLead.** Die Lesemaske nicht mehr leere Kontakt Felder, es verschleiert sie - so hält ein maskierter Anrufer jetzt real aussehende Strings das würde vollkommen glücklich fortbestehen. Die richtige Hierarchie macht dies schwer zu erreichen, aber "schwer zu erreichen" ist keine Garantie und der Ausfallmodus ist geräuschlos Verfälschung der Telefonnummer eines Kunden. **Grid Sicht.** Ohne VIEW_UNASSIGNED_LEADS wird der /leads Boden zu "meinem Leads plus ungezeichnete Free-for-all-Leitungen" statt "meine Leads", und ein unssignierte Free-for-all-Lead kann geöffnet werden und seine Geschichte gelesen werden - eine Zeile, die Sie können sehen, aber nicht öffnen ist ein Fehler. Die CORRESPONDENCE zu lesen ist ein anderes Frage und LeadCommsReadGate beantwortet es immer noch mit VIEW_LEAD_CONTACT_INFO_OTHERS; der Grid-comms-Anwendungsbereich hält bewusst den schmaleren Boden, mit einem Kommentar sagen warum sich die beiden jetzt unterscheiden.
· kamo-shared-library
Verbreitern Sie das Akzept-Gate, verschleiern Sie maskierte Kontaktinformationen, lassen Sie Free-for-all-Lets geltend gemacht werden
Drei verwandte Änderungen an der Blei-Auftrag-Kern. **Das Akzept-Gate stellt nun zwei Fragen, über jede zugewiesene Führung.** LeadAcceptEligibilityService ersetzt das Kommentartor, das im Inneren lebte CreditLeadAssignmentService. Eine Blei blockiert seinen Halter von der Einnahme einer anderen, wenn entweder hat es keine Notiz von ihnen geschrieben SINCE es ihnen zugewiesen wurde, oder es ist noch sitzen bei Fresh - New Lead / Farm - Farm Fresh. Beide Hälften schließen ein Loch. Die alte Regel zählte jede Note, die jemals geschrieben wurde, also eine Leite die an ein Mitglied zurückkam, die eine Notiz von ihrem vorherigen Aufenthalt mit ihm weitergab. Und es sah nur auf Leads durch die Auto-Zuteilungssystem erworben, die links jede andere Route - Hand-Aufgabe eines Managers, ein Import, ein Selbstanspruch . als eine Möglichkeit, unberührte Leitungen mit dem Pool noch offen zu sammeln. Die Regel ist zwei Set-basierte Abfragen, unabhängig von der Größe des Buches: die Aktuelle Zuordnungen, dann ein gruppiertes MediaObj-Aggregat über ihren Strom guids. Die Erweiterung des Umfangs für jede Aufgabe machte die alte Abfrage-per-Lead-Schleife unerschwinglich - es ist die Form, die die / Leads Gitter langsam gemacht, und dies läuft auf jedes Render des Leads nav für jedes angemeldete Mitglied. Die Blocking-Status werden in LeadStatusType explizit und nicht abgeleitet genannt von isAllowSwitchBack. Diese beiden sind zufällig die einzigen Zustände, die diese flag, aber es beantwortet eine andere Frage, und ein zukünftiger Status markiert die gleiche Weise darf nicht still anfangen zu blockieren akzeptiert. Passen ist auf dem gespeicherten System Beschreibungen, so dass die benutzerdefinierten Status-Etiketten eines org niemals die Regel beeinflussen. **Maskierte Kontaktinfo wird eher verschleiert als ausgeblendet.** KontaktObfuscator verwandelt (555) 555-5555 in (555) 555-**55, snadjafinia@gmail.com s**********@gmail.com, und 123 Main St in *** Main St. Ein leeres Feld ist ununterscheidbar von einem, das niemand ausgefüllt, so dass ein eingeschränkter Zuschauer nicht sagen "es gibt eine Zahl hier, die Sie vielleicht nicht lesen" von "diese Leine hat keine Zahl" und das Personal verfolgte die zweite Lesung. Stadt, Postleitzahl und Land überleben auf der gleichen Grundlage der Staat immer tat: grob genug, um ein Duplikat zu identifizieren, Unnutznlos für jemanden zu erreichen, sobald die Straßennummer weg ist. Geburtsdatum bleibt abwesend; keine partielle Form davon ist erkennbar und sicher. Der Browser spiegelt genau ****************, weil LeadRealTimePublisher-Fans eine vollständige unmasked DTO aus jedem Abonnenten in der org ohne pro-empfangene Projektion möglich. Die Java und vitest Suiten behaupten die gleichen Saiten, so dass die beiden nicht auseinander driften unbemerkt. **Unzuunterwiesene Free-for-all-Leitungen sind sichtbar und zuwiderrecht.** ************ behauptet eine bestimmte nicht zugewiesene Leerführung. Free-for-all ist die offene Tür und trägt das Akzept-Gatter mit ihm - sonst ist es wäre der Weg um die Disziplin, die es neben - und Mints / Ausgaben existiert seine eigene Kredit genau wie akzeptierenNextLead tut, so Max Daily Spend immer noch Kappen. ASSIGN_LEADS ist die erhöhte Tür: keine nicht zugeordnete Blei, kein Tor, kein Guthaben. Die Lizenzierung ist eine gesetzliche Einschränkung, und keine der beiden Türen verzichtet darauf. LeadGridQuery gewinnt ************ Drehen Erlaubnis-Fräle von "führt mir zugeordnet" in "Leads zugeordnet mir, plus alles, was wirklich zu gewinnen ist". Verstecken von nicht beanspruchten free-for-all führt aus Jeder ohne VIEW_UNASSIGNED_LEADS ließ sie in der Theorie und unerreichbar in der Praxis.
· kamo-internal
Flaggen auf Sprachen, und stoppen Kopieren Plattform-Listen
Erschließt c20bac57. Sprachen tragen jetzt ihre Fahne, die gleiche, die der NavTop Switcher zeigt und aus der gleichen Quelle - dem geschlossenen Wert sowie jeder Zeile im Menü. Anreise aufgedeckt das eigentliche Problem: options.ts hatte private Kopien angebaut von vier Listen, die die Plattform bereits besitzt, das ist, wie die Seite ersetzt arbeitete auch. • Sprachen waren eine neu eingeschickte Kopie ohne Ländercodes, so dass eine Flagge nicht auch möglich. Jetzt app/lib/languages.ts, welche der NavTop-Switcher und der Chat-Übersetzer bereits teilt. • Währungen waren ein 34-Eintritt Samen gegen die Plattform 160-ungerade, so ein Mitglied bezahlt in Naira oder Schekel lesen ihre eigene Währung als nackten Code ohne Symbol und ohne Namen. Jetzt app/Konstanten/währungs.ts. • Zeitzonen wurden von den gleichen 27 Namen neu geschrieben. Jetzt abgeleitet von TIMEZONE_ENUM_TO_IANA, die eine komplette Karte, so dass der Picker nicht bieten eine Zone nichts lösen kann. • Arbeitslage behält seine Werte, aber sie sind jetzt gegen die Java enum per Test. Team-Mitgliedsstatus bleibt eine explizite Liste absichtlich: die generierte TypeScript-Spiegel ist STALE und fehlt CONTRACTS_SENT, so dass es von es würde stillschweigend einen Status fallen lassen, auf den Mitglieder wirklich eingestellt sind. Das Java enum hat neun; ein Testpins alle neun. Zeitzonenreihen zeigen jetzt, wie spät es dort ist. 27 Enum-Namen mit die entfernten Unterstreichen ist eine Liste, auf die Sie bereits die Antwort kennen müssen Lesen Sie; die Zeit ist die Sache gewählt, so ist es die Sache gezeigt. Behebt auch eine Behauptung, die erste Commit nicht liefern: Framer-Motion nicht konsultieren bevorzugt-reduziert-Bewegung von selbst, so dass der Raum übergeht und die speichern bar animiert unabhängig von der Einstellung. MotionConfigreduzierung="user" Die CSS-gesteuerten Stücke haben nun beides abgelöst; die CSS-gesteuerten Stücke haben bereits ihre eigenen Abfragen. Und das Landfeld gibt seine Flagge in der Leseansicht wieder, passend zum Picker das hat es produziert. Verifiziert: npm Test (14 Wachen + 5.121 Tests, 70 von ihnen über app/lib/memberProfile), tsc --noEmit, next build.
· kamo-internal
Mein Profil als Held und fünf Zimmer neu aufbauen
**************** war ein 1,999-Zeilen-Komponente-Rendering dreizehn identische Karten auf einer einzigen Spalte. Ein SectionCard-Helfer gab alle von ihnen der gleiche Radius, der gleiche Schatten, der gleiche Symbol-Chip und die gleiche Bearbeiten / Speichern / Abbrechent Trio, also "Account Information" - zwei Termine niemand kann bearbeiten - genau das Gewicht von "Passwort & MFA" getragen. Das Layout war Die Wahrheit über eine Hierarchie zu sagen, die die Seite nicht hatte. Der Wiederaufbau: • Ein Held, der die Tapetenauflösung von MemberHeader wörtlich, Narbe hält Kommentare enthalten, und fügt die Identität, die es nur Dekoration war: die Name als ein Stück von großem Schriftstück, die lokale Zeit des Mitglieds Ticken in THEIR Zone, MFA-Staat, letzte Anmeldung, und ein Kraftring. • Fünf Zimmer hinter einer Schiene - Identität, Erscheinung, Arbeit, Zugang, Regional • einer nach dem anderen geöffnet, in der URL als &room= durchgeführt. Ein Raum, dessen jeder Karte ist abgesperrt für den Betrachter macht keinen Schienengegenstand überhaupt. • Click-to-edit-Felder und eine Raum-Level-Save-Leiste, die 39 Tasten ersetzt. Speichert Fan out by endpoint under allSettled: eine Gruppe, die erfolgreich ist begeht, während eine Gruppe, die scheitert, ihre Felder mit einem Grund schmutzig hält. • Cmd+K über jedes Feld, so Zimmer verstecken Dinge, ohne sie zu verstecken. • Kartenförmige versetzte Skelette anstelle eines Full-Tab-Spinners. Zwei Fehler beim Lesen gefunden, hier behoben: • Die Adresse hat nie in THER Richtung gearbeitet. Der Lader hardcoded five Leerzeichen und lesen Sie niemals data.address, was SecurityService tut senden; und der Kunde {street, Stadt, Staat, Reißverschluss, Land? wire Form . Member.address ist eine EmbAddress von {Adresse, AdresseDetails, Ort, Unterteilung, Postleitzahl, Land. So machte es leer für alle und gespeicherte Schlüssel der Entität nicht tragen. Jetzt nutzt die Form der Rest der Plattform sendet bereits, mit Hin- und Rückreisetests. • "Rechtlicher Name:" und "Born" waren englische Literale in MemberHeader, und die Work-Location- und Beschäftigungsstatus-Etiketten waren englische Literale in der Komponente. Alle Schlüssel. Struktur. Die Regeln verschoben auf App/lib/memberProfile, wo vitest tatsächlich sammelt sie - app/settings/** ist nicht in der enthaltenen erlaubende Liste, also ein Test geschrieben neben der Seite hätte durch nie ausgeführt. fields.ts ist der Schlussstein: jedes Feld einmal erklärt mit seinem Zimmer, Karte, Label, Gate und Endpunkt. Die Palette, der Kraftring, der Save-Flaus und das Rechte-Gating alle lesen, anstatt es neu zu setzen, und 57 Tests Pin die Tore nach unten einschließlich, dass kein Feld ist immer sichtbarer als seine Karte, und dass die Bearbeitung ist nie breiter als zu sehen. Schnelle Tipps wird nur für diese Registerkarte gelöscht, indem Hilfe-Tips ausgelassen; Einstellungen Lässt die Schiene aus dem aktiven Tab, so dass die anderen neun ihre behalten. Impersonate bewegt sich von der Einstellung Kopf in den Helden. Löstet auch ProfileTab.tsx (2.650 Zeilen), LoginSecurityTab.tsx (787) und MembershipPermissionsTab.tsx (2.136), die keine Importeure hatte. Wörterbuch-Schlüssel landete zuerst in kamo-translation-dictionary 4bb91245. Verifiziert: npm Test (14 Wachen + 5.106 Tests), tsc --noEmit, next build, and next build, and next build, and check-i18n-keys --require-messages gegen einen frischen Klon des Wörterbuchs.
· kamo-internal
Ein echtes Linux-Terminal in einem Werkzeugfenster und ein Untermenü, um es zu erreichen
Die Linux Desktop-Navi-Option wird zu einem Menü statt eines Launchs . Remote Desktop mit seinen Größen, Remote Terminal - genau wie das Softphone Anruf besitzt, Voicemail und Text. Eine Registrierungsänderung tut es: "Art: 'Action'" wird zu "Art: 'tool', und NavToolButton gibt bereits in allen drei Platzierungen ein Untermenü wieder toolSections ist bereits die gemeinsame Quelle für das Navi und die Home Launchpad, so die beiden können nicht driften. THE TERMINAL. xterm.js gegen eine echte PTY auf der eigenen dev Maschine des Mitglieds, so dass es ist ein Terminal und kein Befehlsrunner: Alt-Screen-Apps (vim, htop, weniger), 24-Bit Farbe, Mausreporting, Klammerpaste, breit und die Kombination von Glyphen, anklickbar OSC 8 Links. Nichts wird auf dem Weg durch interpretiert - Tastenanschläge sind Bytes zu die PTY und Ausgabe ist Bytes zurück - das ist der einzige Weg, ein Terminal ist jemals eigentlich kompatibel mit dem, was Menschen in einem laufen. Auf dem Emulator: ein Status Chip, der pulsiert, anstatt sich auf Farbe allein zu verlassen, ein Titel, der dem Shells eigene OSC-Sequenz, also verfolgt sie cd und den laufenden Befehl, copy-on-select mit Strg+Shift+C/V, Strg+Umstellung +F Suche, Strg +/-/0 Zoom und einer Palette, die folgt dem Thema des Betrachters. Die Schale überdauert das Fenster. Es läuft unter tmux auf der Fenster-ID-Taste, so ein refresh, eine abgebrochene Verbindung oder ein Werkzeug-Fenster-Reattaches wieder auf die gleiche Sitzung mit seinem Scrollback und seinem laufenden Befehl - was auch der Grund ist, warum fallengelassene Steckdose wieder mit Backoff verbunden, anstatt einen Ausfall zu melden. Die Transport lebt in ************ frei von React und von xterm, so dass Backoff und der Frame Split ohne DOM testbar sind. THE STORED DESKTOP SIZE IS GONE, und mit ihm DesktopResolutionPicker. Es wurde eingestellt auf einer Einstellungsseite vier Bildschirme von jedem Start und lesen Sie aus localStorage, so "warum hat es sich klein geöffnet?" hatte keine Antwort irgendwo in der Nähe der Sache, die geöffnet klein. Die Größe wird nun mit dem gleichen Klick gewählt, der den Desktop öffnet; openKamoDesktop nimmt es explizit und ein Anrufer ohne Meinung geht an, das ist, was die Standardeinstellung immer war. Drei Defekte in Selbstbetrachtung gefunden und behoben, alle still: der Shortcut-Handler wurde durch einen Effekt, der feuert, bevor die async-Emulator existiert angebracht, so dass es nie gebunden; Schließen eines Fensters, während seine Ticket-Anfrage war im Flug noch öffnete eine Steckdose danach, so dass eine Schale an nichts, dass die pro-Mitglied Kappe ging auf Zählung; und die Suchdekorationen weggelassen Die beiden REQUIRED Übersichtsrolerfarben von ISearchOptions. Typisierung der xterm refs Statt "any" ist das, was das letzte gefangen hat. 405 Testdateien / 5049 Test bestanden, die 14 Wachen sind sauber, tsc ist sauber, und die echte Produktion Build gelingt - ein grüner Tsc allein beweist hier nichts. Wörterbuch zuerst geschoben (115c267f); verifiziert gegen einen frischen Klon, wie CI tut es, da lokale Nachrichten/ gitignored ist.
· kamo-internal
Ein viertes Fenster Zustand - schweben, ziehen zu lösen, ziehen, um neu zu bestellen
Ein Popup-Tool-Fenster hatte drei Zustände: in der Reihe entlang der angedockt unten, über den Blickport maximiert, oder zu einem Chat-Kopf minimiert. Dies fügt FLOATING - losgelöst von der Zeile, irgendwo auf dem Bildschirm fallen gelassen, und von jeder Kante verkleinert und erreicht es auf zwei Arten. DIE BUTTON. Eine Kontrolle in der Titelleiste, trägt das gleiche Symbol, dass löst einen Zettel, hebt das Fenster vom Schlitz ab und kaskaskadiert es frei von der Anklagebank, damit das Auge ihm folgen kann. Wieder gepresst geht es zurück zu die Zeile. Ein maximiertes Fenster ist un-maximiert und zentriert statt, da es hat keinen Slot zu kommen. DIE DRAG, das ist die interessante Hälfte. Pressen der Titelleiste und Ziehen ist EINE Geste mit drei Ergebnissen, und wo das Fenster ist gelassen gehen entscheidet, welche: - mit seiner unteren Kante innerhalb von 96px des unteren Bildports freigesetzt, es nimmt einen Schlitz in der Zeile - so ziehen ein angedocktes Fenster seitlich ERBÄLT das Dock, das vorher überhaupt nicht möglich war; - veröffentlicht irgendwo sonst schwimmt es dort, die für ein angedocktes Fenster ist der Moment, in dem es sich löst. Es löst sich von genau dort, wo es war, so nichts springt; - und ein schwimmendes Fenster zog zurück nach unten Schnappschüsse in die Reihe, wie es Ansätze, bei seiner Standardgröße und in der Reihenfolge mit seinen Nachbarn. Der untere EDGE wird gemessen, nicht der Etikett: Ziehen eines 650px-Fensters durch seine Titelleiste setzt den Zecken 600px über dem Dock auf dem ersten Frame, und ein Fingerzeiger-Test würde jeden Versuch einer Neuordnung ablösen. Nichts ist verpflichtet, bis der Bezugspunkt auftaucht. Das getragene Fenster, die Nachbarn schlurfen, um Platz zu machen (oder Reihen dahinter zu schließen), der Tropfen Bahnaufhellung, wie das Dock nähert und der Halo um den Schlitz wird es landen alle eine Vorschau von der Live-Box jedes Frame gelöst ist es, was Escape macht, und ändern Sie Ihre Meinung auf halbem Weg, kostet nichts. Zwei kleinere Entscheidungen, die es wert sind, benennt zu werden. Docked Fenster sind jetzt positioniert von ihrer TOP-Kante anstatt mit "bottom: 0" angeheftet; oben und unten sind unterschiedliche Eigenschaften und kein Übergang trägt ein Element zwischen sie, so dass der Snap gesprungen wäre, aber es war zeitlich. Und "reizable: false" wird ein FLOOR, sobald ein Fenster aus der Reihe ist als ein Veto - der E-Mail-Komponist ist eines der Fixed-Size-Tools, und es ist das Fenster Mitglieder wollen am meisten mehr Raum für. Die Reihenreihenfolge und die Schwimmgeometrie überstehen beide eine Nachladung: der Schnappschuss trägt die Float-Box, die Dock-Größe zurück zu, und die Array-Reihenfolge, die die eigene Rechts-Links-zu-Rechts-Vereinbarung des Mitglieds ist. Benötigt @kamo/tool-core 0.1.6 (setFloating / setFloatGeometry / setWindowOrder), hier gestoßen.
· SecurityService
Servieren Remote Terminal - eine echte Schale über eine WebSocket
Überbrückt einen Browser auf der eigenen dev-Maschine des Mitglieds. Binäre Rahmen sind das Terminal, Textrahmen sind die Kontrolle; auf der weite Hop ein HTTP 101 auf eine Länge-vorhergesetzte Stream erreicht den Agenten auf dem Port die Netzwerk-Politik bereits Genehmigungen, so dass kein Cilium-Wechsel erforderlich ist. Die erste WebSocket in diesem Service, und absichtlich eine rohe. STOMP ist ein Nachrichten-Broker über eine Steckdose und was hier reist, ist ein Byte-Stream zwischen einem Browser und eine Shell - ein Umschlag um jeden Tastendruck kauft nichts. AUTHORIZATION HAPPENS VOR DER SOCKET. Ein Browser kann nicht eine Kopfzeile auf eine WebSocket Konstruktor, so anstatt lehren den Handschlag zu parsen ***, ein gewöhnliche authentifizierte Endpunkt macht die ganze Entscheidung mit der Sitzung in Hand und reicht es nach vorne als Einweg-Ticket, das wertlos ist 30 Sekunden später und wieder nach einem Gebrauch. Das spiegelt die KamoDesktop-Verbindung, die aus genau diesem Grund: ein wiederspielbares Token sitzt in der Geschichte und in Strg+Shift+T, und eine Shell ist in dieser Hinsicht schlechter als ein Desktop, nicht besser. Der Handshake liest nichts anderes vom Client - kein Benutzername, nicht ein Konto, nur eine Größe Hinweis der Agent klammert sowieso. Das Linux-Konto kommt von ZugangsdatenFür(< die eigene Mitglieds-ID des Anrufers), so dass eine Anfrage keinen Namen nennen kann Die Shell der anderen, und Origin ist an den Host gepinnt, der angesprochen wird. Kein Passwort ist überhaupt lesen: der Agent ist root und fällt in das Konto, so dass die reversible Beglaubigung Guacamole braucht wird nie auf diesem Weg berührt. Vor der Tatsache, synchron, in das gleiche Access Log geprüft, das bereits antwortet "wer von wo aus eingeloggt hat" mit IP, Geo und User-Agent, bei HIGH Schwere. Ein Streit, der nur auf Erfolg erschien, würde genau die Fälle fehlen das ist wichtig. Acht Terminals pro Mitglied, weil jedes eine PTY und ein Faden auf einem ist geteilte VM, die durch Gedächtnisdruck vor genommen wurde. Das Schließen der Buchse tötet die Shell nicht; der Agent läuft es unter tmux so ein refresh oder eine abgebrochene Verbindung wieder an die Arbeit noch läuft. 21 Tests: Einweg, Ablauf auf beiden Seiten der Grenze, Unbekannte Stille, pro Mitglieds-Cap und seine Freigabe, nicht-sequenzielle Token und der Frame-Codec einschließlich einer Ein-Byte-um-einer-Zeit-Lieferung, eine absurde angegebene Länge und Lesen die Statuszeile des Upgrades, ohne den Strom dahinter zu schlucken.
· KlusterServices
Geben Sie dem Agenten einen PTY-Endpunkt für Remote Terminal
GET /pty aktualisiert die Verbindung zu "kamo-pty" und wird zur Shell: ein PTY pro Browser-Tool-Fenster, "su - <Benutzer" in -tmux new-session -A", Frames gepumpt beide Wege über die rohe Steckdose. Eine 101 statt einer WebSocket. Der Anrufer ist SecurityService, der den Träger hält Token, nicht ein Browser, so gibt es keinen Grund, Hand-Roll RFC 6455 Rahmung zu bleiben stdlib-only. Nach der Statuszeile ist es suint32 Länge | uint8 type | Nutzlast, und ThreadingHTTPServer Thread-per-Verbindung ist genau die Form Das ist notwendig. tmux, nicht eine nackte Schale, und das ist der ganze Grund, es ist hier. Eine rohe PTY stirbt mit seiner Steckdose, so dass eine Seite aktualisieren, ein geschlossener Laptop oder ein wifi blip würde ein töten laufende Build - und kamo-interne stellt Werkzeugfenster auf Last wieder her, also ein restauriertes Terminal würde zurückkommen und eine Leiche halten. "Neue-Sitzung -A" macht erste Verbindung und den gleichen Befehl wieder verbinden. Sicherheit folgt der bestehenden Regel der Datei: der Benutzername kommt bereits gelöst aus der eigenen Sitzung des Mitglieds und wird gegen USERNAME_RE und die reservierte Liste vor Beginn eines Prozesses, Session-IDs werden überprüft, weil tmux liest - und -:" als Adresssyntax, werden die Größen gefestigt, weil sie eine zuweisen Framebuffer auf einem gemeinsamen Rechner, und ein deaktiviertes Konto wird abgelehnt, obwohl Für sie würde das "su" noch funktionieren. Es wird überhaupt kein Passwort gelesen - der Agent ist root und Drops auf das Konto, so im Gegensatz zu den Guacamole Pfad die gespeicherte Anmeldeinformationen nie verlässt die Datenbank. TERM wird durch "env" gezwungen, weil "su -" die Umwelt wieder aufbaut Kratzer, und ein Terminal, das kommt als "dumb" hat keine vim, htop oder weniger. Verlassene tmux Sitzungen werden beschnitten, wenn das Mitglied als nächstes verbindet, was benötigt wird weder einen Zeitpunkt noch eine Liste von jedem Konto auf der Maschine. 24 Tests: argv-Form, reservierte/ungültige Ablehnungen, Größenklemmen, Frame Codec einschließlich eines Rahmens geteilt über liest und eine absurde deklarierte Länge, Kontrolle Rahmen Handhabung, und der Reaper vier Fälle. 107 passieren.
· kamo-shared-library
Nehmen Sie ein dev-Maschine-Terminal im Zugriffsprotokoll auf
Ein Mitglied, das eine Shell auf Desktop-1 öffnet, hat jetzt einen eigenen Event-Typ. Das Maschine hält eine Cluster-Admin kubeconfig und seine Konten haben passwortlos Paketverwaltung, die root-äquivalent ist - "wer hatte eine Schale dort, von welche Adresse und wann" muss aus dem gleichen Access Log, dass beantwortet es bereits für Logins. Sicher anhängen: system_access_logs trägt keine CHECK-Beschränkung (verifiziert in Produktion heute) und event_type ist varchar(30). Kontrast PhiResourceType, deren Hibernate-emitted value whitelist ddl-auto: update wird nie erweitert.
· SecurityService
Senden Sie das Unternehmen neben dem Kontakt, wo eine Platte beschriftet ist
Ein Rekord, der sowohl eine Organisation und eine Person heißt "Harmony Home Loans (Nickolas McGarry)" - das Unternehmen führt, der Kontakt qualifiziert. Diese Regel lebt in der EntityLabel() des Browsers, so dass diese Endpunkte aufhören Kommissionierung eine Hälfte und senden beides. - Die /bles Grid Timeline hat jeden Eintrag mit dem Kontakt abgestempelt und fiel zurück auf das Unternehmen. Gleiches Blei, daher lesen Sie als eine Person auf seiner Timeline und als ein Unternehmen auf dem Netz, das es produziert. - Die Lead Credit/Asignment-Historie löste nur den Kontakt auf. Hier aufgelöst anstatt in der gemeinsamen Geschichte Service, weil dies seine einzige Renderer, und ein finde AllById über die eindeutigen Leads der Seite ist eine einzige Abfrage. - Ein Konto Leads Registerkarte gesendet {uid, organisationId] und nichts anderes, so jede Spalte lautet "---" und jede Zeile, die mit /leads/view/undefined verlinkt ist. Es jetzt sendet ID (das ist, was die Tabelle Schlüssel und Links auf), die beiden Namen Hälften, status und dateCreated. Die E-Mail der Leitung ist die Art und Weise führen Kontakt Detail gated ist überall sonst: Ihre eigene Führung immer, jeder andere ist nur mit VIEW_LEAD_CONTACT_INFO_OTHERS.
· kamo-shared-library
Senden Sie die Firma eines Kontos neben seinem Kontakt für Kunden-Picker
Sechs Kunden-Picker lesen AccountSummaryDTO - den Besteller, den Service-Job - das Abo-Detail und der Assistent, sowie die Pipeline-Anmelder-Tab - und jeder von ihnen nannte einen Kunden von wem auch immer der Ansprechpartner war. Jemand die Wahl, zu welchem Kunden ein Job oder eine Bestellung gehört, ist die Suche nach der Organisation. displayName ist nun der Kontakt ALONE. Früher trug es ein "(#123)"-Suffix, das machte Sinn, während es das ganze Etikett war und produzierte verschachtelte Halterungen in der Zeit das Unternehmen führte es "Harmony Home Loans (Nickolas McGarry (#123)) " Die uid ist bereits ein eigenes Feld für jeden Picker, der zwei Kunden trennen muss mit dem gleichen Namen, und der Browser komponiert die Hälften durch eine EntitätLabel() dass auch jeder andere kundenorientierte Bildschirm durchläuft.
· kamo-internal
Kommunikationsansicht - das ganze gefilterte Buch als eine Timeline
Drei Änderungen an /leads. Schnellsuche bewegt sich in den Helden, über den CRM-Einstellungen. Im Filter Reihe war es die letzte Kontrolle auf einer Linie von elf Dropdowns, nur auffindbar von Scanning vorbei an allen von ihnen. LeadManager besitzt immer noch die Reise des Wertes in die Abfrage und in den Sitzungsspeicher, der die Filterleiste auf dem Rückweg wiederherstellt von einer Leine - die Box bewegte sich, nichts anderes tat. Ein Flip-Schalter, zentriert in der Paginierungszeile: Lead View / Communication View. Zwei benannte Positionen statt einer Switch, weil keines von diesen ist "off" sie sind zwei Arten, auf den gleichen gefilterten Satz zu schauen, und eine Steuerung nur Eines würde den Leser raten lassen, was die andere Position tut. Communication View ersetzt das Netz mit der gleichen Timeline ein Lead Kommunikations-Tab zeichnet - gleiche Komponente, gleiche sechs Sub-Tabs, gleiche Eintrag Renderer - geweitet, was auch immer die Filterleiste derzeit entspricht. Jeder Eintrag trägt einen Chip, der seinen Vorsprung benennt und in ihn verlinkt: Cross-Lead, eine Reihe, die es tut nicht sagen, wessen Anruf es war unlesbar, und finden Sie die eine Gespräch wert Öffnen ist der ganze Grund, die Liste zu scannen. No Note Komponist, bewusst: ein Note muss etwa eine Leine sein, und eine Box, die nicht sagen konnte, welche eine Falle ist anstatt eine Bequemlichkeit. Details, die eher als beiläufig sind: - Die Seite des Grids ist SUSPENDED in Communication View. GET /api/security/leads schreibt eine PHI-Zugangszeile pro Lead, die sie zurückgibt, und holt eine Seite, um einen Bildschirm zu machen, der keine von ihnen würde lesen in der Prüfung setzen Spur, die niemand gemacht hat. - Der Filterstring, der an die Zeitleiste übergeben wird, wird auf die eigene Verzögerung des Gitters abgeprallt. Das Gitter debounces seine Anfrage; die Zeitleiste kann es nicht nachweckt, wenn die String-Änderungen und feuert zwei Anfragen pro Änderung, so tippen "Schmied" war zehn Rundreisen, jeder schreibt einen PHI-Suchaufsatz, keiner von ihnen abgebrochen. - Seite/Größe/Sort werden von ihr abgestreift. Größe aktiv kollidiert, weil die Timeline setzt sich für sich. - Die beiden Tracks des Pagers bleiben MOUNTED, wenn sie leer sind. Ein Display: kein Kind ist gar kein Gittergegenstand, also hätte das Verstecken den Schalter als erster verlassen Punkt und schlüpfte es in die linke Spur, aus der Mitte.
· kamo-internal
JustCall als Telefonserver-Typ hinzufügen
Fügt JustCall zum Picker bei ************ mit seiner API hinzu Schlüssel und geheim, ein Kontakte-Import-Kipp, Anmeldestatus bei den Anbietern Registerkarte und das Logo. Der interessante Teil ist die Wahl. JustCall veröffentlicht keinen SIP-Registrar und keine WebRTC-Anmeldepflicht für Anwendungen von Drittanbietern und der einzige Outbound-Call Endpunkt fährt einen KI-Sprachagenten und nicht eine Person - so berichtet das Backend voiceCalls=false, die verwendenSoftphone bereits Gates Registrierung auf, und keine Softphone ist gebaut. Aber ein Mitglied auf JustCall kann einen Anruf perfekt platzieren, nur nicht hier, und "Sprachanrufe nicht mit aktuellen Anbieter verfügbar" wäre ein lie. dial() gibt also die Nummer an JustCalls eigenen Web-Dialler. Dieses Handoff ist sein eigenes Modul und nicht ein Zweig innerhalb des Hakens: es ist ein lib concern, und es dort zu setzen macht es prüfbar. Es nutzt den Web dialler anstatt der justablell: Protokoll der Desktop-App registriert, weil ein Browser nicht sagen, ob diese App installiert ist und eine unhandle Protokoll-Navigation tut gar nichts - ein Mitglied ohne App würde wählen und ansehen Es passiert nichts. ProviderCapabilities gewonnen providerType, so dass ein falscher VoiceCalls kann gehandelt werden anstatt nur berichtet: für die meisten Anbieter bedeutet es "keine Wahl", für diese eins bedeutet es "Dial over there". Mirrors SipCredentialsResult.provider, die existiert aus dem gleichen Grund. Der neue Deckungstest ist das Frontend-Zwilling von PbxProviderBillingCoverageTest ein Anbieter niemand erinnert, zu beschriften nicht laut scheitern, es macht als eine die Karte in einem Bildschirm, die ein Admin benutzt, um sie auszuwählen. Verifiziert: tsc clean, alle 14 Wachen einschließlich check-i18n-Tasten --require-Nachrichten, 4.938 vitest Tests. "next build" wurde NICHT gegen diese Änderungen ausgeführt: ein weiteres Sitzung hielt dieses Arbeitsverzeichnis mit seinen eigenen gleichzeitigen Builds durch.
· SecurityService
Eine Kommunikations-Zeitleiste über den gesamten /bles Filter, nicht eine Leitung
GET ************ nimmt die SAME Abfragestring GET die Lead-Detail-Seite zeichnet sich über jede Führung der Filterleiste. "Was hat zu den Leads gesagt, die ich arbeite" ist eine Frage über ein Set, und bis jetzt die einzige Möglichkeit, sie zu bitten, war, sie einzeln zu öffnen. Die Filterübersetzung bewegt sich zu LeadGridFilters, so dass beide Endpunkte eine query string identisch; eine zweite Kopie würde driften, und die Art, wie es driftet ist ein die Zeitleiste, die verschiedene Leitungen aus dem Raster abdeckt, das sie erzeugt hat. Zwei unterschiedliche Grenzen, aus zwei unterschiedlichen Gründen. Anrufe, Voicemails, Texte und E-Mails sind grenzenlos: LEAD_COMMUNICATIONS trägt ORG_ID und ist indiziert auf (ORG_ID, OCCURRED_AT), so dass eine Keyset-Abfrage die Korrespondenz der Org-Korrespondenz führt Neuestes Erstes und testet jede Zeile gegen das Gitter-Prädikat als korreliert EXISTS - die gleichen Kosten, ob sieben Leads abgestimmt oder siebzigtausend. Anmerkungen und Chat kann nicht sein: sie leben in MEDIA_OBJS, die keine Org und keine Leine trägt, und der einzige Join-back ist LEADS.STREAM_GUID, der nicht indiziert ist. Diese zwei lösen Sie die Abgleich führt zuerst, gedeckelt bei 1000, und die Antwort sagt, wenn es gedeckelt, anstatt leise fallen Geschichte. Die Autorisierung ist die führende Zeitleiste, die in SQL angewendet wird. Ein Eintrag trägt eine Blei eigene Nummer oder Adresse plus Nachrichteninhalt, so gibt LeadCommsReadGate jetzt auch seine Herrschaft über die drei Formen, die ein Blei haben kann und sendet das passende Prädikat aus. Schreiben Sie es ein zweites Mal ist, wo der Fehler war: der erste Entwurf lesen "unassigniert benötigt VIEW_UNASSIGNED_LEADS" und verpasst, dass die Ablehnung() fällt DURCH an die Kontakt-Info, die die Korrespondenz jedes gepoolten Leads gestellt hätte vor einem Mitglied, das nur den Pool rechts hält. Die beiden Formen sind nun an sich gegenseitig erschöpfend - jede richtige Kombination gegen jede Form. Im Gegensatz zu einem Konto Rollup kollabiert dies NICHT ein Ereignis, das zwei erreicht Matched Leads. Zwei Gründe, die auf die gleiche Weise zeigen: Jede Reihe benennt die Lead it gehört zu und "dieser Anruf erreichte beides" ist eine Tatsache über das Buch gearbeitet wird, und zusammenbrechende Zeilen aus einer einzigen festen Größe Seite können den Überlebenden zuletzt verlassen twin als frischer Eintrag kann sich der Kunde nicht entduzieren. Die Kriterien Abfragen werden in LeadGridCommsQueries als reine Funktionen so gezogen LeadGridCommunicationsSqlTest kann sie gegen echte Hibernate-Metadaten darstellen. Das ist hier wichtiger als sonst: Die eigene Spezifikation des Netzes wird bereits ausgesendet EXISTS Unterabfragen, und diese nest es in einem anderen - das ist genau, wo Das Hibernate 6.2.13 dieses Dienstes und die gemeinsame Bibliothek von 6.5 unterscheiden sich.
· VOIPService
Wire JustCall in durch die Telefonanbieter Abstraktion
JustCall (api.justcall.io/v2.1) als vollständiger PhoneProvider: Anrufhistorie, Texte, Voicemail, Aufnahmen, das Agentenverzeichnis und Verfügbarkeit, sowie signiert Konto webhooks und eine optionale Kontakte importieren. Auth ist ein Konto-weit Schlüssel/geheimes Paar als roher "Schlüssel:secret" Autorisierungswert gesendet - kein Träger Token, die nichts authentifiziert und gibt einen 401 zurück, der sich wie ein schlechtes liest Beglaubigung. Drei Formen von JustCalls API treiben das Design voran: * Voicemail ist keine Ressource. Es ist ein Aufruf, dessen call_info.type ist "Voicemail", mit seiner Transkription inline und seine Audio hinter dem gleichen Aufnahme Endpoint wie jeder andere Anruf - so getVoicemails ist getCallHistory mit einem Filter, und es gibt keinen Lesezustand zu markieren. * Es gibt keine Softphone-Anmeldepflicht. JustCall veröffentlicht keinen SIP-Registrar und keine WebRTC Token an Dritte, und seine einzige Outbound-Call-Endpunkt treibt eine AI Voice Agent eher als eine Person. voiceCalls ist daher falsch, das ist was verwendenSoftphone bereits Gates Registrierung auf, und getSipCredentials lehnt sich mit einer Erklärung ab, anstatt sich halb registrieren zu lassen. * Das Verzeichnis ist nur lesbar, und es gibt kein Gerätekonzept, so dass diese halten Das Wurfgerät der Schnittstelle ist standardmäßig vorhanden, anstatt vorzutäuschen. Webhooks werden pro Instanz bei ************ registriert Abonnement pro Veranstaltungstyp. JustCalls HMAC-SHA256 umfasst die registrierte URL, damit sich der Abfragestring innerhalb des signierten Materials befindet und nicht umgeschrieben werden kann landen die Ereignisse eines org auf dem Telefonserver eines anderen. Die URL ist aufgenommen in config_json bei der Bereitstellung, weil die Überprüfung den gleichen String unterschreiben muss JustCall hat - Wiederaufbau es von der Konfiguration würde beginnen still zu scheitern die Moment, in dem sich die Basis-URL geändert hat. Eingebundene Texte und Call-Events erreichen die Wege, die RingCentral bereits nutzt. Der Handler von VoipMessageService war durchgehend RingCentral-förmig, so dass sein Parsing ist von seiner Ingeste abgespalten: beide Schienen teilen sich jetzt die Entstaubung, Stichwort Abfangen, Konversation upsert und Lead Linking. Dieses Teilen ist bewusst - das Stichwort Schritt ist, was zeichnet eine Opt-out, und eine zweite Schiene wächst seine eigene Kopie der Sequenz ist, wie man endet nicht zu ehren STOP. Antwort-Schalter von SmsKeywordService gewann die neue Schiene aus dem gleichen Grund: es ist eine Anweisungsschalter, so ein unlisted constant hätte niemand geantwortet. MMS ist nur über eine öffentliche URL. JustCall akzeptiert keine hochgeladenen Bytes . Anlage ist hinter einer kurzlebigen unvorstellbaren URL auf diesem Dienst geparkt und diese Verbindung wird übergeben. Bewusst kein vorsignierte Objekt-Store URL: MinIO hier ist **************** eine vorsignierte URL ist signiert für der Host, den es benennt, und JustCalls Abrufer kann eine In-Cluster-Adresse nicht lösen es würde 404 für sie, während die Arbeit perfekt aus dem Inneren des Clusters. Das Service ist bereits öffentlich erreichbar, weil er ihre Webhooks erhält. Kontakt Import ist aus, sofern nicht eingeschaltet: Das Adressbuch eines Kunden ist Pro-Mitglied-Zugang kontrolliert, und importieren es in dem Moment, ein Schlüssel eingefügt wird eine Überraschung sein. Kontakte werden über den JustCall agent_id die Erweiterung Sync besessen bereits aufgenommen, und alle, deren Agent Karten zu keinem Kamo-Mitglied wird eher übersprungen als irgendwo geparkt geteilt. Aushunger geht an EmailService, dem die Kontakttabellen. JustCall's AI Call Zusammenfassung, Stimmung und Gästefahrt auf dem gleichen Anruf gelesen und sind auf CallLogEntry aufgetaucht. Nicht beharrlich: PHONE_CALL_LOG hat keine solchen Spalten, der Anbieter gibt sie auf jeder Lektüre zurück, und das Hinzufügen von Spalten würde eine DDL kosten Fenster für ein Duplikat ihres Ladens. Keine DDL in dieser Änderung.
· EmailService
Interner Endpunkt für den Import von Kontakten aus einem externen System
Die JustCall-Integration von VOIPService muss die Kontakte eines Kunden in der das Adressbuch des rechten Mitglieds, und hier werden Kontakte geschrieben: ein Kontakt Karten nur Skalare, mit seinen E-Mails, Telefone, Adressen, orgs, URLs, IMs und Beziehungen in sieben Tischen ohne Kaskade, erreichbar nur durch KontaktDetailStore. Ein Anrufer, der diese Tabellen von einem anderen Dienst schreibt, würde leise jede Telefonnummer fallen lassen - das eine Feld, in dem eine Telefon-Integration existiert liefern - so bleibt die Beharrlichkeit hier und der Anrufer postet es. Eigentum ist das tragende Teil. CONTACT.OWNER_ID ist NICHT NULL und weist auf Benutzer, und ein ContactBook-Besitzer IS seine Zugriffskontrolle (ein besitzloses Buch gehört niemandem und 404s für jedermann, also muss ein Stapel das Mitglied nennen Kontakte gehören zu ihnen und werden komplett abgelehnt, wenn dies nicht der Fall ist. Jede Quelle bekommt sein eigenes Buch hinter einer ContactIntegration Reihe statt in gemischt in "Meine Kontakte": Synchronisierte Reihen und handgeschriebene Zeilen haben unterschiedliche Lebenszyklen, und die Mitglied kann die importierten verstecken oder fallen lassen, ohne ihre eigenen zu berühren. Upserts passen auf uid, das der Anrufer namespace zu seinem System gibt. UID ist einzigartig pro Buch, also ist es auch, was ein Re-Sync ein Update anstelle eines zweiten macht Kopie von allem. Montiert unter /api/internal, bewacht ganz von InternalAuthFilter Mitgliedssitzung hinter diesen Aufrufen, so ohne dass Filter wäre dies ein Endpunkt für das Schreiben beliebiger Kontakte in Bücher beliebiger Mitglieder.
· kamo-shared-library
JUST_CALL als Handy-Provider-Typ hinzufügen
Beigeordnet bei ordinal 5. ************ ist EnumType.ORDINAL und trägt keine CHECK Einschränkung, so dass das Anhängen sicher ist und überall einlegen sonst würde still neu-Point bestehenden Reihen bei einem anderen Anbieter PbxProviderBillingCoverageTest pinet die Reihenfolge von der anderen Seite. Billed THIRD_PARTY: Die Organisation hält ihr eigenes JustCall-Abonnement (ihre API braucht mindestens einen Teamplan) und JustCall trägt die Anrufe, so ist dies ein Integrationsgebühr, nicht Hosting. PbxBillingClass.of hat keinen Standard-Arm, der was die Entscheidung erzwang, anstatt einen neuen Anbieter nichts abrechnen zu lassen für immer.
· kamo-internal
Eine Papierfarbe pro Block und Blöcke, die zu ihrem Text passen
BLOCKS JETZT FIT THEIR CONTENT. Die Blöcke des Lesers waren alle 200px hoch, was auch immer sie gehalten, weil richTextExtension konfiguriert den Editor mit minHalbe: 200px - der Artikel Komponist die Form, wo der Herausgeber die Seite IST. Das Umschalten des Lesegeräts auf RichTextView entfernt; nichts in der Scheibe klemmt ein Block ist jetzt die Höhe, also ist er genau so hoch wie seine Worte. THE COMPOSER'S EDITORS GROW INSTEAD OF SCROLLING. Same 200px, plus Überlauf: Auto auf dem Container, bedeutete, dass jeder Block drei Linien zu hoch geöffnet und dann reichte sich eine Scrollleiste statt zu wachsen. Blockieren Sie innerhalb des scrollers der Seite. KbArticleEditor gewinnt "autoGrow": die Container stoppt das Scrollen, der Schreibbereich beginnt bei einer Linie und die Root-Größen zu Inhalt statt der Befüllung seines Hosts. Opt-in, so der Artikel Komponist behält die Form, die für ein seitengroßes Dokument richtig ist. PAPER COLOUR. Jeder Block trägt einen, ausgewählt von NoteColorMenu - das gleiche Menü und die gleiche Palette die Noten und die Startrampe die Scheine verwenden, so dass eine swatch bedeutet eine Sache über das Produkt und nicht drei. Die Farbe wird als die palette ID und gelöst durch resolveStickyColor am Render, so dass beide Komponist und das Interaction Center malen aus einer Quelle und einer späteren Palette Korrektur erreicht die heute geschriebenen Skripte. Im Lesegerät behält ein farbiger Block seine Farbe, ob es sich um Aktuelle. "Wo bin ich" wird bereits an der Grenze, dem Lift und der Wirbelsäule; Dimmen des Papiers als auch würde die Wahl des Autors aussehen wie ein Rendering-Fehler.
· kamo-internal
Fügen Sie das JustCall Anbieter Logo
Der VOIP-Logo-Ordner hatte FreePBX, Microsoft und RingCentral, aber keine JustCall-Marke, so dass jede Oberfläche Auflistung JustCall als Anbieter hatte nichts zu machen.
· kamo-shared-library
Eine Papierfarbe pro Block
************ mit einer Paletten-ID - "Zitrone", "Glas" - und nie ein Hex-Wert. Stored die Art und Weise Notizen und Launchpad Scheiben speichern ihre, aus dem Grund, dass Angelegenheiten und nicht um der Konsistenz willen: die Palette wird einmal auf der definiert Client (STICKY_PALETTE) und jede Oberfläche löst eine ID durch resolveStickyColor. Beharrliche Hex würde den heutigen Schatten in die Reihe einfrieren, so eine spätere Korrektur der Palette würde die Noten beheben und leise die Skripte auf die alte Farbe - und die gleiche Uhr würde dann bedeuten, zwei verschiedene Dinge, je nachdem, von welchem Bildschirm es ausgewählt wurde. Null ist keine Farbe: Der Block trägt jede Oberfläche, auf der er sitzt. Eine Leerstelle oder Whitespace-Wert wird normalisiert, um auf dem Weg in Null, weil "" ist nicht "nein Farbe" zu lösenStickyColor - es gibt die erste swatch der Palette zurück, also Autor, der die Farbe gerodet hätte Zitrone bekommen. Durch den vollen Block getragen ersetzen wie jedes andere Feld, und abgedeckt dort: die Farbe überlebt eine Bearbeitung, und eine gelöschte kommt wieder null.
· EmailService
Lassen Sie eine gesendete Botschaft Bilder in seinem Körper tragen
Der Körper hatte vier mögliche Formen und send() konnte nur drei bauen. Die multipart/related branch - der, der ein Bild setzt, wo der HTML-Zikus ist: zeigt darauf - saß hinter dem Befestigungszweig, also eine Nachricht mit beiden ein geklebtes Bild und eine Datei verloren das Bild auf dem Weg nach draußen: der Körper hielt einen cid: Verweis auf ein Teil, der nicht mehr in der Botschaft war, und nichts sagte so. Es war auch in der Praxis unerreichbar, weil nur der transaktionale Weg jemals gesetzt inlineImages; nichts, was ein Mitglied schickte, konnte überhaupt dorthin gelangen. applyBody baut nun, welche Form der Inhalt fordert - html allein, verwandt wenn der Körper Referenzen Bilder, gemischt, wenn es Befestigungen, gemischte Verpackung verwandt, wenn es beides gibt und ein Kalendereinladung behält seine Bilder mit dem Angebot die verwandte als HTML-Alternative. antworten und weiterleiten durch senden, so dass sie Alles erben. /send nimmt die Bilder als eigene binäre Teile, die jeweils nach der Inhalts-ID benannt sind die HTML-Referenzen bereits. Base64 im JSON-Teil würde wieder ein Drittel kosten in der Größe gegen die kleinste Decke in der Kette, so dass ein Screenshot oder zwei würde aus einem Grund abgelehnt werden, gegen den das Mitglied nichts unternehmen konnte. Der Name eines Teils wird eine Content-ID-Header, so dass InlineImageParts sie mit der genauen Form abstimmt Komponist prägt und lehnt alles andere ab - ein falscher scheitert eher im Senden anstatt leise fallen und ein Loch im Körper hinterlassen.
· kamo-asterisk-support
Reconcile per-Extension WebRTC Blöcke statt von Hand-Bebauung eines Dienstplans
Eine Erweiterung, die durch FreePBX's API erstellt wird, bekommt keinen WebRTC-Block, also Registriert sich über WSS und hat dann keine DTLS oder ICE . Das Browser-Softphone zeigt angeschlossener Anruf mit keinem Audio. Diese Einstellungen können nirgendwo ausgedrückt werden FreePBX akzeptiert sie: "dtls_cert_file" und "Transport" sind keine Spalten in die Tabelle "Sip" und nicht Felder auf der "addExtension" Mutation, so müssen sie be .[<ext'(+)" - fügt sich in **************** an war ein handgepflegeter Dienstplan in einer ConfigMap, was jede neue Erweiterung bedeutete wurde still gebrochen, bis sich jemand erinnerte, es zu bearbeiten und umzuschichten (8888 saßen seit Monaten nicht gelistet). Die Erweiterung 8777 war die jüngste. WebRTCReconciler liest die Erweiterungsliste aus der FreePBX-generated pjsip.endpoint.conf und hält einen marker-delimited verwalteten Abschnitt im Gleichschritt mit es, alle 30er Jahre. Gelöschte Erweiterungen verlieren ihren Block automatisch - a (+) Block für einen Abschnitt, der nicht mehr existiert, macht Asterisk-Log "Sektion existiert nicht" auf jede Nachladung. Es füllt nur Lücken: jede Blockierung außerhalb unserer Marker (die KlusterServices) Dienstplan, ein Administrator) wird genau so gelassen, wie es ist, nie dupliziert und nie übernommen. Nur all-numerische Endpunkte werden berührt, so dass Stämme nicht angebunden sind ein WS-Transport mit DTLS aufzwingt. Ein fehlender pjsip.endpoint.conf ist ein No-Op anstatt "Null-Erweiterungen", die sonst von jedem WebRTC abziehen würden Erweiterung, die eine hat. OFF standardmäßig (MANAGE_WEBRTC_ENDPOINTS), ein für k1m1. Der Block ist genau falsch für ein SIP-Desk-Telefon: es zwingt DTLS-SRTP das Telefon nicht tun kann und pins es zu einem Transport spricht es nicht. Zwei Dinge, die auf der Live-K1m1-Box gemessen wurden, anstatt angenommen zu werden: - Die Reload muss "modul reload res_pjsip.so" sein, nicht "pjsip reload". Nach Hinzufügen eines "[8999](+)"-Blocks, "pjsip reload" den Endpunkt auf webrtc=no; ein Modul Reload angewendet, und ein Modul reload auch umgedreht es, wenn die Block wurde entfernt. Mit dem CLI eigenen "pjsip reload" hier würde ein schreiben die Datei korrigieren und die laufende Konfiguration falsch hinterlassen. - A (+) Block kann nur ADD-Optionen, nie überschreiben. Appending "direct_media=yes" zu einem Endpunkt, dessen generierte Konfiguration sagte "direct_media=no" hat es auf "no" - der erste Wert gewinnt. ('webrtc=yes' ist die Ausnahme nur, weil es eine additive Kurzschrift ist, kein gespeichertes Feld.) Alles, was einen generierten Wert ändern muss, muss im FreePBX fixiert werden Datenbank. Verifiziert gegen die reale /etc/asterisk: korrekt herausgesucht die ungedeckte Verlängerung von 23, übersprungen die Erik_Primary Kofferraum, links Roster-Byte-für-Byte identisch, und war ein No-Op auf dem zweiten Durchgang.
· kamo-internal
Personieren Sie, so dass ein Betreiber ein Org als eines seiner Mitglieder öffnen kann
Gezeigt neben Enter auf jeder /Netzwerk-Ansicht für eine Plattform-Administrator halten das neue IMPERSONATE-Recht. Ein anderes Recht von SYSTEM_USER und bewusst nicht impliziert: Die Eingabe als Systembenutzer ist eine sichtbare, separate Identität a Mieter können in ihrer eigenen Mitgliedsliste sehen, während dies eine Sitzung nichts produziert Downstream kann von dieser Person, die in sich selbst unterschreibt zu sagen. Der Picker ist MemberPickerDialog - das gleiche Popup öffnet sich der /leads Agent Filter unverändert. Es besitzt bereits die Suche, das Paging, die Tastatur-Handling und die Art und Weise, wie sich eine unpickbare Reihe erklärt. Was neu ist, ist sein "fetcher", das ersetzt den Verzeichnis-Endpunkt direkt und weist auf die Zielorganisation auf Mitglieder, weil das Standardverzeichnis die eigene Org der Session ist und das ist genau die falsche Liste. Niemand wird Client-Seite gefiltert. Der Server markiert ein Gotteskonto, eine Plattform Administrator oder ein Off-Boarding-Mitglied mit einem Grund nicht wählbar, und die Die Vernunfttabelle des Dialogs wuchs, um sie zu decken: das Verstecken dieser Zeilen würde eine Betreiber auf der Suche nach einem Kollegen einfach in der Organisation und bekommen nichts zurück, das sich eher als eine gebrochene Suche liest und nicht als Verweigerung. Der Reiter wird synchron innerhalb des eigenen Klicks des Pickers beansprucht, bevor warten, und seine SitzungStorage gelöscht - die gleichen Tanzhandle Enter Dokumente, aus den gleichen zwei Gründen: ein Popup nach einem Warteschlangen geöffnet ist eine der Browser nie sah jemanden fragen, und ein gleicher Herkunft window.open CLONES dieser Registerkarte Speicher, Sitzungs-ID enthalten. Auch fügt das Symbol der Plattform Admins Registerkarte für die neue Rechte benötigt; tsc gefangen das, wofür RIGHT_ICON ein erschöpfender Record ist.
· SecurityService
Geben Sie eine Mieterorganisation als eines ihrer Mitglieder, von /network
Eine zweite Tür neben dem gleichen-Orgott-Modus. Gated auf dem neuen IMPERSONATE Plattform rechts über @RequirePlattformRight, wo die bestehende Tür betreten ist die Sitzung mit GD. Gefasst als zwei Handler und nicht als einer mit einer Flagge. Ihre Anrufertore sind wirklich anders, und @RequirePlatformRight hat keine In-Handler-Variante von Design - ein Tor, das Sie haben zu erinnern, zu nennen ist eine, die schließlich bekommt vergessen auf dem Endpunkt, der zählte. Wer kann ENTERED AS sein kann, ist eine separate Frage, und ImpersonationTargetRules beantwortet es als reine Funktion über gelöste Fakten: abgelehnt für die Top-Level org, selbst, eine Mitgliedschaft ohne Benutzer, den Systembenutzer, ein Gotteskonto, Plattform-Administrator, oder jemand, der nicht in sich selbst unterschreiben konnte. Dasselbe Funktion entscheidet, ob eine Zeile im Picker wählbar ist, so dass die Liste nicht jemandem anbieten, der sich abwenden würde. Die Tür der gleichen Org-Seite teilt diese Regeln absichtlich NICHT. Es arbeitet innen die eigene Organisation des Anrufers, die für einen Gott Admin in der Regel die Top-Ebene ist ein, und auf Menschen, die häufig Administratoren selbst sind - beide hart Ablehnungen hier. Falten der beiden zusammen würde die Einstellungen Seite brechen oder ruhig erweitern diese. ************ füllt den Picker. Es ist der eine Endpunkt in dass der Controller eine andere Organisation als die der Sitzung benennt, weshalb es ist ein separater Handler und nicht ein Parameter auf /search: das Versprechen der Klasse dass /search kann nicht durch Zufall erweitert werden bleibt wahr. Verweigerte Menschen bleiben in die Liste mit einem Grund, anstatt von einer Suche nach einem Kollegen, der ist eindeutig in der Org. workspaceHostFor bewegt sich von EnterAsController in WorkspaceHostResolver, seit beide Türen brauchen die gleiche Antwort. Zwei Exemplare von "welcher Host ist offen" ist wie einer die Betreiber immer wieder zu einem Zertifikat nacheinander schickt gestoppt. Seine Tests bewegten sich mit ihm.
· kamo-shared-library
IMPERSONATE, so dass ein Betreiber einen Mieter als eines seiner Mitglieder eingeben kann
Angelegt an PlatformRightType statt eingefügt: getSortOrder() zurückgegeben ordinal(), so dass ein rechts in der Mitte hinzugefügt wird jede andere rechts unten in der Konsole. Zuschüsse sind @Enumeriert(STRING), so dass das Anhängen ändert nichts bereits gewährt. Bewusst nicht in SYSTEM_USER gefaltet. Dieses Recht tritt als sichtbar ein, separate Identität, die ein Mieter in seiner eigenen Mitgliedsliste und Audit-Trail sehen kann; Dieses produziert eine Sitzung nichts nachgeschaltetes Programm, das von der Mitgliedsunterzeichnung sagen kann in sich. Verschiedene Fragen, unterschiedliche Strahlradius, so ein Operator Das zustehende erste ist damit nicht berechtigt, die zweite. ReportVisibilityTest angeheftet MANAGE_REPORTS als LAST-Wert, der angehängt wird Pausen beim Beweisen nichts - die Invariante, die zählt, ist, dass nichts war Eingefügt ABOVE es, so dass es jetzt steckt die ordinal statt. Zwei Stapel-Repository-Lookups für den Picker dahinter: die Mitgliedschaften ein Satz von Benutzer halten in einer Organisation, und welche von einer Reihe von Mitgliedern sind Plattform Administratoren. Row-at-a-time, das ist zwei Abfragen pro Name, auf eine Steuerung, die Neu-Runs auf jeden Tastendruck.

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