Changelog
Cosa c'è di nuovo.
Ogni miglioramento alla piattaforma, come si spedisce.
· kamo-shared-library
Conteggio eventi DISTINCT attraverso i proprietari di un rollup
Un numero di telefono può essere un punto di contatto su più di un proprietario contemporaneamente, e due porta su un conto condividere uno è il caso ORDINARY — sono comunemente la stessa persona che chiede due volte. Il matcher scrive una riga per proprietario deliberatamente, perché ognuno di quei tempi ha bisogno di sé. Suggerito su un rollup, pianura conta una chiamata come due, e una lettura della ferrovia 11 sopra un elenco che mostra 6 è peggio di nessuna rotaia. COUNT (DISTINCT sourceId) su una lista di proprietari di un tipo conta esattamente ciò che la timeline fusa mostra, e trasforma un conto di 26 domande conteggio in due.
· kamo-internal
Portare la finestra di linea per membro, e mostrare quale modalità si è in
Il controllo del rollout. Predefinito, opt-in per membro da Impostazioni del telefono, nidificato sotto l'interruttore VOIP perché non significa nulla per un membro senza linea. Un gancio possiede il cancello in modo che i suoi due consumatori non possono disaccordo — il controllo NavTop che apre la finestra e la striscia all'interno del softphone che lo offre. A membro che vede uno ma non l'altro è peggio di uno che non vede. Si'. fallisce chiuso: una configurazione non raggiungibile la lettura nasconde la funzione piuttosto che offrire una finestra che non può funzionare, e il softphone in-page non è influenzato in entrambi i modi. La striscia risponde a una domanda a un membro altrimenti non può vedere la risposta a: è questa chiamata al sicuro da un rinfresco? Con la finestra aprire la chiamata vive lì e pannello è un telecomando, quindi offre di portare avanti la finestra — un popup può finire dietro il browser e nient'altro può alzarlo. Con la finestra chiuso la chiamata vive nella scheda e un aggiornamento finisce, così dice così. Inbound ora utilizza l'unico gesto che può produrre: la notifica del desktop click, che in precedenza non aveva alcun handler affatto.
· VOIPService
Leggi e scrivi il cancello della linea
GET superfici lineWindowEnabled; PUT lo accetta come un nullable Boolean in modo che assente significa "non menzionato" e conserva il valore memorizzato. Ogni esistente chiamante di questo endpoint omette il campo, e trattando quelli come falsi sarebbe spegnere la funzione per qualsiasi membro le cui impostazioni del telefono sono state salvate per un ragione non correlata. Anche normalizza un nullo letto a falso prima di salvare: una riga scritta prima del colonna esisteva può ancora portare null attraverso Hibernate, e la colonna NON è NULL.
· kamo-shared-library
Mappa LINE WINDOW ENABLED su MemberVoipConfig
Il cancello per membro per la finestra di linea softphone dedicata. Perno di versione rimane a 1.6.0 — l'aggiunta di un campo non ha bisogno di urto, e un perno diviso rompere CI per ogni consumatore contemporaneamente. La colonna esiste già nel database; il DDL è atterrato in KamoInitializer in primo luogo, deliberatamente, perché un servizio che mappa una colonna mancante non riesce a fagioli creazione piuttosto che degradare.
· InitializerService
DDL per il cancello della linea per-membro
Addiziona il falso. Una colonna piuttosto che una caratteristica bandiera perché non c'è nessun sistema di bandiera qui e MemberCapabilities è un insieme chiuso, non chiuso con nessun slot di ricambio — quindi controllo vive accanto alle altre preferenze del membro del telefono, che è anche dove un amministratore lo cercherebbe. Il suo corridore piuttosto che una linea in MultiInstancePhoneMigration perché il ordinare è il punto: KamoInitializer non ha CI, quindi questo viene applicato a mano e deve atterrare BEFORE a VOIPService costruire che mappa la colonna, o Hibernate fallisce a creazione di fagioli e il servizio non inizierà. L'ALTER è già stato applicato al database live per esattamente questo motivo; questo corridore lo rende ripetibile e idemponte per ogni altro ambiente.
· kamo-internal
Un sub-tab AI nel Centro Interazione
Le sessioni AI vivono in AIService e non sono MediaSessions, quindi questo secchio ottiene il proprio caricatore davanti alla /api/media/sessioni/chat prendere gli altri quattro condividere, quindi adatta ogni sessione nella stessa forma Row piuttosto che un secondo renderr — l'elenco, la sua ricerca, i suoi avatar e il suo chip non letto sono uno superficie, e un secondo andrebbe dalla prima all'interno di un rilascio. Non c'è arriva attraverso il corridoio: namespace the hexhead badges read (getUnread, not conversazioneKeyForWindow — una riga di chat-list non è una finestra di strumento), quindi una riga e la sua finestra minimizzata non può mai non essere in disaccordo sul numero. Tre lacune al di là del piano proprio breve, catturato prima che spedissero tranquillamente: secchiOf() sessione mai indirizzataTipo 'AI' ovunque, così ogni riga AI ha deciso di 'teamMembers' e la scheda AI avrebbe reso permanentemente vuoto; la riga il proprio titolo non legge mai la riga. titolo, così ogni conversazione AI avrebbe mostrato come "Empty Chat"; e 'ai' mancava da ALL BUCKETS, quindi il sub-tab per-member la preferenza si rifiuta silenziosamente di ripristinarlo dopo un interruttore. Il brief è il proprio non lettoPer() l'esempio non è utilizzato anche come scritto — sostituendo l'esistente calcolo non letto con esso all'ingrosso avrebbe zero ogni fila sociale badge (mai nella mappa dal vivo, a differenza di CHAT/SUPPORT) e lampeggiato ogni riga per zero prima che l'istantanea live carichi; il ramo AI è piegato nell'esistente calcolo invece, preservando entrambi.
· kamo-internal
La finestra della linea dedicata
La chiamata ora vive in una finestra un rinfresco dello spazio di lavoro non può toccare. SoftphoneProvider diventa proprietario-o-follower. Solo il proprietario REGISTRI e si apre la presa STOMP; un seguace rende lo stato a specchio, invia comandi sopra il bridge, e rimane silenzioso — senza suoneria, senza ringback, nessun suono di evento, perché esso non tiene alcuna sessione e il suo pulsante Risposta non farebbe nulla. Dove Web Locks è non disponibile la scheda possiede semplicemente la linea e non c'è finestra, che è comportamento di oggi: mai degradare in due registrazioni. /phone rende attraverso un terzo ramo AuthedChrome che trasporta SoundProvider e SoftphoneProvider e nient'altro. Escluso ToolWindowRestore è portante di carico — la sua guardia è portata modulo, quindi un documento fresco rigiocherà l'intero membro dock all'interno del popup — e così esclude SessionManager, che naviga a /logout alla scadenza e cancellerebbe la sessione Redis condivisa fuori da sotto scheda workspace. Per lo stesso motivo utilizzareUserInfo e apiClient ora rifiutano di self-navigate da questo percorso; una sessione persa è resa, non reindirizzata. La finestra si apre sincronamente da un clic in NavTop (l'attivazione transitoria fa non sopravvivere a un'attesa), è chiamato così un secondo clic si concentra piuttosto che duplicare, e segnala un popup bloccato invece di fallire silenziosamente — il in-page softphone continua a lavorare in entrambi i modi. Dentro: un cancello di partenza che acquista attivazione appiccicosa prima di qualsiasi cosa ne abbia bisogno, ingoiare chiavi di ricarica, chiudere confermare, e un blocco della sveglia dello schermo.
· kamo-internal
Una scheda di comunicazione che aumenta le piste del conto
Il livello che la maggior parte delle persone significa quando dicono "le chiamate di questo cliente". Varie piste comunemente appendere un conto proprio perché sono la stessa persona domandando due volte, e ciascuna delle loro chiamate è stata abbinata a qualsiasi pista ha tenuto numero al momento — quindi la lettura della timeline di un lead risponde ad una domanda più stretta di quello che qualcuno che guarda un cliente sta realmente chiedendo. Questo rende la timeline esistente della piattaforma, non una seconda. La colonna vertebrale è La storia di lead disegna un conto ha dato una base diversa. Un matcher, uno La scheda dice che cosa NON mostra. Il server cancelli ogni piombo roll-up sul gli stessi diritti che la pagina principale applica e i berretti quanti rotola, ed entrambi sono superficie: "I cavi N non sono mostrati perché non hai il permesso" è un frase diversa da "questo conto ha più piste di quanto si arrotola subito", e un banner per entrambi nasconderebbe il primo dietro il secondo. Note e chat sono assenti piuttosto che vuoti. Entrambi sono leadnative — una nota vive su un flusso di media di piombo, chat sul suo collegamento sociale — quindi un account non ha nulla a mettere lì, e una scheda permanente vuota legge come rotto piuttosto che inapplicabile.
· KlusterServices
Bounce a bare visit to the Kamo login, e terminare la sessione sulla scheda chiudere
La chiusura della scheda KamoDesktop ha lasciato una sessione live seduta sulla macchina. Guacamole mantiene il suo token auth in localStorage (GUAC AUTH), che sopravvive alla chiusura della scheda, chiudere la finestra e riavviare il browser, e il token rimane valido per 60 pochi minuti dopo il suo ultimo uso. Quindi la persona successiva per aprire il gateway su quello computer ha ereditato il desktop della persona precedente. Riprodotta fine alla fine. Due modifiche, deliberatamente entrambi lato server prima. Il bordo ora reindirizza una richiesta di documento nudo a login.kamocrm.com. KamoDesktop ha esattamente un punto d'entrata legittimo — un link firmato a un unico uso coniato per qualcuno già autenticato a Kamo — quindi una persona che digita il nome host, o ripristinare un segnalibro, o lasciare il browser completarlo, non ha business vedere la password di Guacamole. Servire uno offre un target di fidanzamento per l'account `sage` e permette a un browser che tiene un token live di riprendere silenziosamente sessione. Percorso(`/`) di proposito: un carico SPA freddo tira ~41 beni e API chiama che non portano ?data=, quindi qualcosa di più ampio rompe l'applicazione in modo definitivo. Il #/client/... fragment non raggiunge mai il server, quindi un link profondo contrassegnato da segnalibri è un nudo `/` qui ed è rimbalzato troppo — che è corretto. E il token è ora revocato quando la scheda va via, piuttosto che semplicemente dimenticato: DELETE /api/sessione dell'intestazione Guacamole-Token (verified live — 204, e il gettone cessa di funzionare immediatamente). E' saltato per un congelamento di bfcache, quindi... premendo Indietro non firma nessuno fuori. kamo-reconnect.js è andato. C'era scritto su sessioni sganciate. desktop giù due volte, e le cause che stava compensando — distribuisce il riavvio il gateway, e l'OOM — sono fissati alla loro fonte. Ciò che lo sostituisce è un il quarto delle dimensioni e il suo peggior fallimento è che si è firmato, che è il risultato che sta cercando di produrre.
· kamo-internal
La proprietà della linea, il ponte e la regola di non-yank
Tre moduli puri senza consumatori ancora, quindi questa navi inerte. lineOwnership elegge esattamente un registrar SIP per browser tramite Web Locks. Che cosa? è obbligatorio qui piuttosto che difensiva: verificata dal vivo, ogni AOR FreePBX è max contacts=1 con remove existing=yes, quindi un secondo REGISTER eviterà il primo e il documento espulso continua a mostrare "registrato" mentre non riceve nulla. Web Locks non ha bisogno di protocollo di liveness — la serratura appartiene all'agente, quindi un crashed o task-killed finestra rilascia e il prossimo cameriere è promosso. Dove l'API è assente si segnala "non supportato" e il chiamante mantiene oggi comportamento piuttosto che rischiare due registrazioni. lineBridge è una busta BroadcastChannel versione. Non finestra.opener: che va stallo esattamente quando l'apritore ricarica, che è l'evento tutto questo esiste per sopravvivere. La versione skew si degrada a un telecomando stante, mai un tiro in una chiamata UI live. Lo stato specchiato è una lista consent-list — directory i dati rimangono dove è caricato. lineHandover è una regola: una chiamata dal vivo non è mai sbavata.
· kamo-internal
Il titolo della scheda conta tutto in attesa, non solo chat
Il tab strip ha spazio per un numero, e 'solo catena e supporto' smesso di essere che cosa un membro sta aspettando una volta SMS, AI, chiamate mancate e rapporti non visualizzati ognuno ha un indicatore.
· kamo-internal
Badge l'opzione AI con risposte non visualizzate
· kamo-internal
Un totale sull'icona del telefono, la ripartizione nel menu
Questa icona non ha portato alcun distintivo affatto, quindi una chiamata mancata mentre il softphone era chiuso ha raggiunto il membro da nessuna parte. Aprire il telefono cancella il conto mancato.
· kamo-internal
Un totale sull'icona, la ripartizione nel menu
in attesaPaese era l'intero distintivo, così i rapporti bug non visualizzati e webinars prenotato per conto di qualcuno non aveva modo di raggiungere nessuno. Aprire i timbri della riga webinar hanno visto, così il conte può effettivamente uscire.
· kamo-internal
Il badge di chat conta chat
Era silenziosamente chat più supporto, quindi un biglietto acceso la campana di chat e niente distinguono i due. Il supporto ha la sua icona ora; sociale si unisce chat, perché una conversazione sociale vive nella lista Chats e non ha alcuna icona propria.
· kamo-internal
Lascia che una riga a discesa porti il suo conto
L'icona mostra la somma e le righe mostrano la ripartizione — il punto di divisione Gli indicatori stanno vedendo la cosa di WHICH ti vuole senza aprire nulla.
· kamo-internal
Thump all'arrivo, con il bagliore che si dissipa verso l'esterno
Il suo strato all'interno .hex-scale: quell'elemento già anima trasforma per hover crescere, e due animazioni su un elemento non comporre — il secondo sostituisce il primo, quindi un battitore medio-hover avrebbe lasciato cadere la scala hover. Chiuso piuttosto che gioco di classe, o due messaggi in rapida successione thump una volta. Gated la scala-pulse su una classe `.thumped` presente solo dopo un vero thump: il cambiamento chiave rende `.hex-thump` un nodo DOM fresco sia su un vero thump E sul primo montare, e CSS non può dire a quei due a parte la chiave da solo, quindi il brief è cablaggio letterale avrebbe suonato il polso su ogni testa una sessione restaurata spawns — la "schermosa di esagoni pulsanti" dovrebbeThump esiste per prevenire.
· SecurityService
Una linea temporale di comunicazione a livello di account
Il livello che la maggior parte delle persone significa quando dicono "le chiamate di questo cliente". La colonna vertebrale è già keyed su un proprietario, quindi il endpoint dell'account è lo stesso fuso, componente lo rende con nient'altro che una base diversa. CommsSubjectResolver decide quali proprietari una linea temporale può leggere, ed è il un posto che risponde è permesso di essere più ampio del soggetto chiesto. Solo ACCOUNT si espande. Un piombo non eredita il traffico di un piombo fratellino: il due possono essere assegnati a persone diverse. Un paziente non eredita nulla, qualsiasi cosa dica il grafico dell'account — un grafico che mostra i messaggi del comando CRM essere una rivelazione, e quel test esiste per mantenerlo in quel modo. Il rollup è bloccato a 25 proprietari e la risposta dice quando il tappo morso. A rollup che silenziosamente cadere proprietari è una linea temporale mancante messaggi per no ragione visibile, che è peggio di uno che ammette che è parziale. Cross-org e account mancanti ottengono lo stesso 404 in modo che la risposta non possa essere utilizzata per sondare quali conti esistono, e la signorina è controllata anche. risolvereOrgId piuttosto che un nuovo sinonimo: il ratchet endpoint riconosce che nome, e legge un corpo metodo senza le seguenti chiamate, quindi un aiutante non può vedere le letture come un endpoint non protetto.
· kamo-shared-library
Lascia che un account riduca le sue comunicazioni
Diversi conduce comunemente appendere fuori un conto proprio perché sono la stessa persona che chiede due volte, e ciascuna delle loro chiamate è stata abbinata a qualsiasi al momento ha tenuto il numero. Quindi "le comunicazioni di questo cliente" è la — lettura di una La timeline di piombo risponde a una domanda più stretta di quella che viene chiesto. findUidsByAccount progetti uids piuttosto che entità di proposito: Lead siede in una gerarchia ereditaria JOINED, e selezionare le entità qui trascinare la tutto il piano di ricerca per produrre una lista di ids. PhiResourceType.ACCOUNT così il nome delle righe di audit della timeline dell'account Leggete. Appendito, mai inserito — l'enum è ordinale-persisted.
· kamo-internal
Un contesto per i quattro contatori
Compone ciò che esiste e possiede i tre che non avevano casa: bug non visualizzato segnalazioni, webinar non visualizzati, e il telefono mancate chiamate e segreteria. La zecca di primo piano degli anni 60 non è cintura-e-bracce — molti di questi arrivano sopra core NATS senza replay, quindi un frame pubblicato su una scheda dormire non sta arrivando.
· kamo-internal
Il punto di partenza riporta quale percorso ICE ha effettivamente scelto
Il beacon ha spedito il ghiaccioCandidateType come campo permanente-null. Questo è peggio. che ometterlo: fa sembrare la telemetria più informativa di quanto sia, e questa è l'unica misura che può reindirizzare l'intero progetto della linea-finestra. Il web softphone costruisce la sua connessione peer con uno STUN pubblico hardcoded il payload delle credenziali non l'ha mai portato. Quindi un membro dietro un NAT simmetrico, un VPN o carrier CGNAT non riescono a stabilire i media con nulla a cui tornare, e ciò che essi riferiscono è "la chiamata è caduta". Dopo il fatto che è indistinguibile da "ho colpito rinfrescare", e i due hanno completamente diverso correzioni — una di loro due linee di configurazione TURN piuttosto che un nuovo contesto di navigazione. `relay` / `srflx` / nulla è la prova che li separa. Il sentiero SIP.js riutilizza il candidato abbina la sua scarica diagnostica esistente già calcola, quindi costi non extra getStats; il percorso RingCentral campioni raw.rtcPeerConnection su Rispondi. Una lettura nulla è RECORDED piuttosto che saltata — "ICE non selezionato coppia" è il fallimento senza relè e la lettura più preziosa disponibile — e callDurationSeconds lo separa da "la chiamata terminata prima di campione". Registra anche nel piano ciò che effettivamente spedito, tra cui la Task 6 guardia che differisce dal piano come scritto.
· kamo-internal
Un giorno picker, condiviso dal calendario e dalla scheda impostazioni
Le due superfici erano cresciute la loro risposta a "quali giorni?". Le impostazioni tab put Workweek Days, Weekend Days e ogni giorno dietro un dropdown; il l'editor del calendario aveva un nastro multi-seletto e nessun gruppo affatto. Qualunque cosa. membro ha imparato prima, l'altro non poteva fare quello che ha fatto. Condividi disponibilità DayPicker ora — i pulsanti di gruppo E i sette chip, su entrambe le pagine, definite una volta. Questo è l'unico accordo che li mantiene la prossima volta sia toccato. I gruppi scelgono piuttosto che salvare. Premere "Giorni di lavoro" si accende cinque chip e nulla a valle interpreta un sentinel: il membro può immediatamente deselezionare il mercoledì sono lontani per, e quello che raggiunge il backend è quello che ha sempre preso, una finestra al giorno. Un pulsante di gruppo legge solo quando EXACTLY i suoi giorni sono scelti, quindi il controllo può dire "questa è la settimana lavorativa" invece di lasciare qualcuno a contare patatine accese. La scheda impostazioni guadagna qualcosa che non ha mai avuto — una scelta arbitraria multi-giorno. "Lunedì, mercoledì e venerdì" non è stato espresso prima; era un giorno o un gruppo. dayToSave richiede quindi un giorno LIST piuttosto che un giorno o un gruppo, che è quello consente a entrambe le superfici di condividere un tipo di selezione. Entrambe le guardie sono ancora in attesa e sono ancora pinned: una modifica non si espande mai in diverse righe, e una scelta multi-day mai crolla a uno. Il pannello e' "Cosa significa?", ora inizia a crollare per tutti. Apertura per un membro con nulla dichiarato era inteso come una gentilezza ed era sbagliato uno — ha spinto la lista e il pulsante che inizia l'intera cosa giù colonna, quindi la prima cosa che un nuovo presentatore ha incontrato è stato un muro di prosa piuttosto che il controllo della prosa è circa. Aumenta anche il timeout della scansione integrale del catalogo sonoro. Legge e concatena ogni file sorgente nell'app, atterra a 6-13s ogni volta che la macchina è occupato, e stava fallendo la suite contro il 5s default di vitest — con un messaggio che non ha nominato evento, perché non ha mai raggiunto la sua affermazione. La scansione vale mantenere; il timeout predefinito non è semplicemente dimensionato per esso.
· kamo-internal
Badge una finestra minimizzata con il suo server conteggio non letto
L'unico componente che vede sia l'elenco delle finestre che le mappe non lette — la il motore non sa nulla di conversazioni e il contesto illeggibile non sa nulla riguardo alle finestre, così nessuno potrebbe rispondere da solo. Dispatches solo su cambiamento: le chiavi thump fuori un aumento, quindi un conteggio ripetuto sembrerebbe un arrivo e le teste pulsano sul timer di aggiornamento.
· kamo-internal
Impostare un conteggio non letto assoluto dal server
Sostituisce hexhead:incoming, che nulla ha mai spedito. Il +1 avrebbe ha contato un'istantanea rinnovata come un nuovo messaggio, e il suo spawn-if-missing ramo lascerebbe una testa la cui finestra non esiste — cliccabile, e inerte.
· kamo-internal
Messaggi e chiamate, sul componente timeline esistente
CommunicationsTimeline e EmailEntry prendono un endpoint opzionaleBase e mantenere il percorso principale come predefinito, quindi ogni sito di chiamata esistente è byte-for- non importa quale sia la timeline ABOUT — la chiave del proprietario è interamente lato server, esattamente come MediaStream prende un feedEndpoint e il DocManager prende un (assocType, assocObjectId). I messaggi di un paziente sono disegnati dal La striscia del punto di contatto sopra la linea temporale è la parte che altrimenti mancare. Una linea temporale è una vista; chiamate in entrata e messaggi solo sempre LAND su un proprietario il matcher può risolvere, quindi un paziente senza numero registrato ha una timeline vuota per un motivo nient'altro sullo schermo sarebbe spiega. Il suo stato vuoto dice esattamente questo, piuttosto che non implicare nulla E' mai successo. 3149 test green, typecheck clean.
· SecurityService
Chiamate, testi e-mail di un paziente sulla spina dorsale
Non una seconda linea temporale. LeadCommunicationsService ora prende un CommsSubject e il sovraccarico di piombo delegati ad esso, quindi /leads mantiene il suo comportamento esatto alla deriva. Un paziente e' solo un altro proprietario. Note e chat appaiono solo per un vantaggio, e questo è un fatto piuttosto che un guard: le note provengono dal flusso mediatico di un piombo e la chat da SocialRemoteUserLead, nessuno dei quali esiste per un paziente. Entrambe le fonti già tornare vuoto quando il loro collegamento è assente, quindi un paziente viene abbinato traffico e niente fa finta di niente. Registrare i punti di contatto è la metà che lo fa funzionare. Puntare un timeline a un nuovo proprietario cambia ciò che è READ; traffico in entrata solo mai LANDS su un proprietario il matcher può risolvere, quindi un paziente il cui numero non è un punto di contatto riceve chiamate che si risolvono a nessuno. Registrazione punto in tempo come la spina dorsale principale — cambiando un numero chiude il punto vecchio e ne apre una nuova, quindi una chiamata di due anni fa spiega ancora cosa — e applica lo stesso pavimento a sette cifre, perché un quattro cifre l'estensione corrisponderebbe altrimenti a ogni paziente che condivide queste cifre. Leggere qualsiasi di esso ha bisogno di una relazione di cura con il paziente, esattamente come il grafico, e ogni voce mostrata scrive la propria riga di audit. Una segreteria da un paziente è come identificare come una lista di problemi. Il endpoint del corpo-mail ricontrolla la riga contro il paziente nel percorso. Il controllo della relazione è soddisfatto dal paziente nell'URL, quindi senza che il secondo controlli un medico con una relazione con un paziente può leggere qualsiasi messaggio nella pratica fornendo il suo id — il piombo endpoint fa lo stesso ricontrollare per la stessa ragione. Il suo 404 è una risposta per "non di questo paziente", "non un'e-mail" e "non locabile ancora", così il risposta non può essere utilizzato per sondare per ids messaggio. Anche qui: il controller di scambio TEFCA — il §164.528 di un paziente contabilità, tutto inviato a un partner (la domanda che qualcuno gestisce l'ora di una violazione è segnalato), la Parte 2 rivelazioni come la propria domanda, e la coda di revisione cross-organizzazione match. 1278 test verdi.
· kamo-internal
Smettere di perdere le chiamate alla scadenza della sessione, alla rovescia e ai dispositivi di stallo
Quattro guardrails che condividono due file, quindi condividono un commit. Una chiamata dal vivo ora conta come attività di sessione. Attivazione client Tracker equato presenza con eventi di input, quindi un membro che ascolta su una lunga chiamata letto come idle: il Redis TTL decaduto, l'avviso di scadenza aperto in una scheda che non stavano cercando a, e /logout strappare giù l'albero tenendo la sessione SIP. Percorso attraverso il markNow() così logout's disabilita ancora vince — sessionPavimenti propri diMonitor (La finestra di attività 120s, il minimo di ri-estendere 60s) governa la cadenza, quindi questo non può scappa. Ora lo dice un documento che muore con una chiamata. la pagina accende un miglior sforzo BYE — l'estremo in precedenza seduto su una gamba morta fino al momento in cui il registrar contatto fuori, fino a dieci minuti a scade:600 — e un faro mangile che trasporta membro, org, fornitore e avevaLiveSession. Niente da nessuna parte contava quanto spesso strappare effettivamente costa una chiamata, quindi non c'era numero per pesare una correzione più grande contro. Il beacon consente di elencare i suoi campi: nessun numero remoto in un registro di pod, e ids rimanere stringhe perché sono int64. Una seconda scheda non suona più con un pulsante di risposta morto. L'argomento VOIP STOMP è una trasmissione, così ogni documento aperto haIncomingCall mentre solo quello il fornitore ha inviato il INVITE per poter rispondere. Gated sulla sessione piuttosto che la SDK, perché con due schede aperte entrambi tenere una registrazione. Una modifica del dispositivo raggiunge la chiamata da qualsiasi finestra. saveAVSettings invia un CustomEvent; solo utilizzareAVImpostazioni anche ascoltato per il cross-document evento di stoccaggio, così ogni consumatore call-path ha perso un cambiamento fatto altrove — silenziosamente, perché applicareSinkId ingoia ogni fallimento. Un abbonamentoAVImpostazioni ora copre entrambe le metà.
· InitializerService
Pulire la spina dorsale a un proprietario, nell'ordine che la mantiene al sicuro
LEAD CONTACT POINTs e LEAD COMMUNICATIONS acquisiscono il responsabile del documento (assoc type, assoc object id) coppia in modo da un account, un paziente o un commercio record può proprie comunicazioni senza prendere in prestito una pista. Quattro passi, e l'ordine è tutto il punto. Backfill primo: ogni riga esistente è un piombo, quindi assoc type = 'LEAD' e assoc object id = lead uid::text. Esecuzione dopo il vincolo swap costruirebbe il nuovo indice unico su nulls, non forzando nulla. Quindi scambiare il vincolo unico sulla coppia proprietario. (org id, lead uid, canale, source id) è ciò che rende ingestione idempotent — una chiamata RingCentral è visto due volte, una volta dal webhook e una volta dalla scansione di riconciliazione — e con lead uid null per un paziente, Postgres tratta ogni uno di questi NULLs come distinto, quindi il secondo avvistamento inserisce un duplicato. Il nuovo vincolo è aggiunto PRIMA il vecchio è caduto, quindi un fallimento tra lascia il tavolo protetto da uno piuttosto che da nessuno. Solo allora rilassare lead uid non è NULL. Hibernate's ddl-auto: aggiornamento aggiunge colonne ma mai rilassa un vincolo, quindi questo non può essere lasciato al mappatura — e facendolo prima che lo swap si apre esattamente la finestra duplicata sopra. Quindi verificare, leggendo pg constraint e information schema indietro. The chiavi primarie cliniche sono state corrette in Java e sbagliato nel DDL emesso, e solo la lettura pg constraint ha mostrato. Una riga sinistra senza proprietario tipo non comparirebbe mai su alcuna linea temporale, in modo che il caso registri un errore piuttosto che a rapporto di successo. Idempotent in tutto, e un tavolo mancante è saltato piuttosto che mancare l'avvio — un'eccezione qui prenderebbe ogni secondo corridore con esso. 176 test verdi.
· kamo-shared-library
Chiave della colonna vertebrale di comunicazione su un proprietario, non un piombo
La colonna vertebrale è stata costruita a forma di piombo — LEAD CONTACT POINTS.LEAD UID, LEAD COMMUNICATIONS.LEAD UID — e l'associazione di cui ha realmente bisogno è Più ampio. Un account possiede diversi lead, in genere condividendo lo stesso punto di contatto perché sono la stessa persona che chiede due volte. Un record di commercio blocca il conto piuttosto che qualsiasi pista. E una cartella paziente ha chiama e-mail su di esso e nessun piombo affatto. Chiavi di guida significavano ciascuno di quelli o preso in prestito una pista o crebbe una linea temporale parallela. Entrambe le tabelle ora portano il responsabile del documento (assoc type, assoc object id) coppia, con LEAD, ACCOUNT, PATIENT e COMMERCE RECORD come proprietari. LEAD UID è KEPT e ancora riempito per righe di piombo, così ogni esistente /leads query, indice e call site è intoccato — il repository chiave di piombo i metodi e il sovraccarico della timeline di piombo entrambi rimangono, e il nuovo proprietario-chiamato quelli seduti accanto a loro. Tre cose che dovevano andare bene, e una che ho quasi sbagliato. Il vincolo unico si sposta alla coppia proprietaria. (ORG ID, LEAD UID, CHANNEL, SOURCE ID) è ciò che rende l'ingestione idempotent — una chiamata RingCentral è vista due volte, una volta dal webhook e una volta dalla scansione di riconciliazione. Con LEAD UID null per un paziente, Postgres tratta ogni NULL come distinto e il secondo avvistamento inserisce un duplicato. La tabella dei punti di contatto conta più della linea temporale. Indicare una linea temporale a un nuovo proprietario cambia ciò che è READ; traffico in entrata solo LANDS su una proprietario che ha punti di contatto, perché è quello che il linker corrisponde contro. Un paziente il cui numero non è un punto di contatto riceve chiamate che a nessuno. Quello che ho quasi spedito: il linker de-duped partite di cp.getLeadUid(). Per un punto di contatto non-lead che è nullo, così vistoLeads.add(null) avrebbe lasciato esattamente un proprietario non-lead attraverso per messaggio in entrata — una chiamata a un numero due pazienti condividono raggiungerebbe uno di loro, silenziosamente. E ora dedupes su Il proprietario. assoc type è una STRING, mai un ordinale. Hibernate congela un CHECK (col TRA 0 E N) su una colonna enum ordinale a TABELLA CRETA e mai la rivisita, quindi l'aggiudicazione di un valore successivamente rifiuta ogni inserto che lo trasporta — silenziosamente, perché la dichiarazione di fallimento si trova all'interno di un metodo @Transactional il cui rollback rimuove le prove. Sette sono stati trovati pieni e già rompendo le cose su questa piattaforma in agosto. Un null memorizzato legge come LEAD, perché ogni riga scritta prima della colonna esistere è un piombo e di ritorno null per coloro che avrebbero vuoto la linea temporale questo cambiamento esiste per ampliare. Un valore UNKNOWN legge come nullo piuttosto che LEAD — collegare il traffico di qualcun altro a una linea temporale di piombo è quella risposta sbagliata peggio di nessuna. Anche in questo commit: il livello di scambio TEFCA (partner, la divulgazione ledger, cross-organizzazione del paziente corrispondente). I suoi codici sono ora i stesso HL7 v3 ActReason strings PhiPurposeOfUse già utilizza — un test catturato me inventando "T" per il trattamento dove la piattaforma dice "TREAT", e un scambio riga e una riga di audit descrivono la stessa divulgazione da due angoli, un rapporto che li unisce si unisce a quelle corde. 1932 test verdi.
· kamo-internal
SMS e AI conta, e una divisione per-superficie
Una snapshot MediaService copre tre superfici che appartengono a due diversi nav indicatori, quindi i totali sono separati dalla sessione dichiarata del server piuttosto che da quali finestre sembra essere aperto. Una voce senza sessioneType conta come chat — questo è ciò che un vecchio build invia, e mantiene il distintivo facendo quello che ha fatto piuttosto che cadere un conteggio mid-deploy.

Il tuo universo ti sta aspettando.
Aggiungi i prodotti quando sei pronto: nessuna migrazione, nessun nuovo login, nessuna richiesta di pagamento.
Gratis per sempre — nessuna carta di credito richiesta