Jurnal de schimbări
Ce e nou.
Fiecare îmbunătățire a platformei, pe măsură ce se livrează.
· VOIPService
Apeluri și apeluri asociate, mesaje și mesaje vocale cu piste
Apelurile nu au fost niciodată înregistrate nicăieri. pentru browser și păstrat nimic, și ÎNREGISTRĂRI există doar atunci când audio a fost capturat. Sincronizarea per-intentanță trage acum istoricul apelurilor prin intermediul telefonuluiProvider abstractizare și Upserts PHONE CALL LOG, tastat pe (integrare, furnizorul apel id). Acesta este singurul traseu care funcționează pentru FreePBX și Microsoft Teams, nici unul dintre care oferă un webhook utilizabil per-call. Mătura e singura scriitoare. Persisting from the RingCentral webhook as well a fost încercat și eliminat: notificarea sa poartă telefonieSessionId în timp ce Call-istorie API returnează un alt ID record, astfel încât cei doi scriitori au produs două rânduri și două intrări cronologie pentru un apel. Apelurile sunt atribuite unei prelungiri numai atunci când această extensie este de fapt pe Sună. Obiectivul final al RingCentral este prelungirea/~ și ignoră argumentul, așa că buclare pe extensie ar fi altfel fișiere apelurile fiecărui membru sub oricare dintre acestea Bucla vizitat ultima. Id-urile de înregistrare sunt rezolvate per pagină prin ÎnregistrareLookupService, la fel îmbogăţire istoria softphone-ului devine există, dar nu poate juca. Link-uri text la trimitere/primire; link-uri vocale la sincronizare.
· InitializerService
Schemă și semințe de punct de contact pentru comunicațiile cu plumb
Hibernate creează cele trei tabele noi de la entitățile comune-lib; acest lucru adaugă ceea ce nu se poate exprima fereastra punctului de contact per (lider, slot) și DESC care acoperă indexurile pentru Scanarea cronologiei. Seminţele deschid o primă fereastră pentru fiecare plumb care precede indexul. Nu a back-fill comunicare: nici un apel istoric sau mesaj este asociat Orice. Fără ea, o pistă preexistentă nu are puncte de contact. Niciodată nu se potrivesc cu un apel primit, astfel încât fiecare filă ar rămâne gol pentru totdeauna. Acesta rulează prin LeadContactPointService, mai degrabă decât o INSERT vrac..SELECT astfel există exact o punere în aplicare a canonicizării. Un geamăn SQL ar avea pentru a re-derive digit stripping, de manipulare NANP, etajul de extensie și adresa despachetare, și orice divergență mai târziu ar fi invizibile rânduri însămânțate ar fi pur și simplu nu se mai potrivi cu traficul live. Aplicat împotriva producției: 66 de puncte de contact deschise pe 45 de piste.
· kamo-shared-library
Index punct-in-time al punctului de contact și linkuri de comunicare cu plumb
Adaugă coloana vertebrală fila de comunicare plumb citește de la. LEAD CONTACT points înregistrează fiecare număr de telefon și e-mail un plumb a avut vreodată, ca o fereastră cu activFrom/activTo. LEAD COMUNICATIONS înregistrează durabil legătură între un fir și un apel, mesaj vocal, text sau e-mail, scris la moment se întâmplă împotriva punctelor de contact live în acel moment un număr de plumb leagă traficul viitor doar și lasă istoria exact așa cum a fost. PHONE CALL LOG este înregistrarea de apel platforma nu a avut: ÎNREGISTRĂRI are doar un Rând atunci când audio a fost capturat, atât de pierdut și apeluri neînregistrate lăsat nici o urmă. ContactCanon este definiţia unică a "acelaşi număr" pentru întregul platforma; LeadController.canonic Telefonează acum delegaţilor să-l caute invers iar comunicarea nu poate fi de acord. LeadContactPointService și LeadCommunicationLinker NU sunt în mod deliberat stereotipuri în fiecare serviciu care nu a adăugat pachetul, care a preluat producția jos de trei ori. Serviciile proprii declară fasolea; LeadService le ia @Autowired (necesar=fals) astfel încât încă fire peste tot.
· MediaService
Captura demo plumb înainte de etapa de rezervare
Formularul demo al site-ului de marketing colectat nume, email, companie, dimensiunea companiei, Industria și un mesaj, apoi avansat la programare fără a spune nimănui. Creaţia de plumb a trăit doar în interior. fiecare vizitator care nu a terminat o rezervare în timp ce nu se publică nici o disponibilitate detalii. - Postul ************* scrie rolul pe cont propriu. Deține org vine de la X-Public-Chat-Org-Id antet APIService timbre de la Cheie validată, niciodată de la corp. - Găsi OrCreatePublicLead este acum singura cale de a scrie plumb pentru toate cele trei suprafete publice (forma demo, program, unire), astfel încât un vizitator produce un plumb Oricât de mulţi paşi ar face. Marchează "KamoCRM" de orga / "Demo" Cerere" produs de vanzator si ia piata de la acest furnizor, si-l rute prin LeadService.createLead în loc să salveze entitatea direct vechi inline salva produs nici un rând de istorie și nici un eveniment LEAD CREAT, astfel încât cele Nu au apărut niciodată piste într-o reţea deja deschisă. - Dimensiunea companiei, industria si mesajul vizitatorilor sunt pastrate ca o istorie principala intrarea; plumbul nu are coloană pentru niciunul dintre ei și ele sunt partea a Vânzătorul chiar citeşte. - GET /api/public/webinar/types permite unei pagini publice să descopere mai degrabă tipul ID decât transporta o copie hardcoded, și sloturi / disponibile acum, de asemenea, întoarce availableTimes fus orar în instante care pot fi postate înapoi ca un StartTime programat.
· kamo-shared-library
Primitivele demo-cereri publice de captare a plumbului
Un vizitator care completează formularul demo al site-ului de marketing dar niciodată nu face rezervări nu a lăsat nici o urmă: plumbul a fost scris doar vreodată în interiorul tranzacției de rezervare. Capturarea în față are nevoie de trei piese biblioteca nu a avut. - ************* se potrivesc cu o depunere repetată pe să conducă aceeași formă deja produsă. Domeniul de aplicare al produsului furnizor mai degrabă decât la e-mail singur astfel încât un formular anonim nu poate adopta (și re-timbru) un plumb personal creat pentru această adresă. - PublicWebinarDateSlotsDTO: disponibilitate rezolvată în instante absolute. ă Slot stocat este o dată locală plus un timp de perete-oră fără zonă, care a browserul nu se poate transforma într-un program programat StartTime. - PublicWebinarTypeDTO: un tip webinar fără lista prezentatorului, deci un public pagina poate descoperi tipul de ID fără scurgeri adrese de e-mail prezentator.
· kamo-internal
Înregistrați furnizorul de configurare în navigație, și scrie sfaturi rapide
Fila de configurare a furnizorului redată în interiorul SetăriView dar a fost accesibilă numai prin dactilografierea URL-ului destinatii: meniul de setari nav si pagina de aterizare a setarilor. Acum conduce. fiecare, potrivirea comenzii file, deoarece care furnizor găzduiește reuniuni decide care dintre celelalte setări sunt chiar disponibile. Sfaturile rapide despre cele cinci file existente nu au fost niciodată scrise. un titular ("Help Heading," "Bullet Lobby Title"). Acum spun ceva, și să acopere setările adăugate pentru Zoom și echipe: controale de întâlnire, cod de acces policy, lobby bypass and presenter roles, telemote recording pull and transcripts; și invitații trimise de furnizor. Fiecare filă explică, de asemenea, dacă furnizorii diferă, astfel un control dezactivat are un motiv declarat mai degrabă decât doar în căutarea rupt.
· kamo-internal
Aplicarea normelor de acces geo și IP la sarcinile de pagină
checkAccess a evaluat regulile în sine și nu s-a potrivit cu nimic pentru întreaga sa viață: față de tipurile de reguli În timp ce editorul scrie numele enum WHITELIST/BLACKLIST/TEMP BLOCK. Geo a fost un comentariu spunând Node are fără baza de date GeoLite. Ambele jumătăți au dispărut Caches in Redis si cere acest serviciu pe o rata, asa ca exista o implementare a Politica şi nici o copie lăsată aici să plutească. Adresa este cea mai din dreapta şi cea mai publică săritură din X-For, mai degrabă decât din stânga. Proxies append, astfel încât elementul din stânga este ceea ce clientul a trimis, și citirea ar au lăsat un antet să decidă în ce ţară este tratat vizitatorul. Un vizitator blocat primeşte acum un document simplu de 403 în loc de JSON brut. browser-ul face o navigare de nivel superior. Acesta nu numește nici o regulă și nici o țară: cititorul nu poate Acţionează în acest sens şi cineva care verifică graniţa nu ar trebui să primească o hartă a ei. Eşecuri deschise pe fiecare cale. Un proxy care blochează atunci când Redis este scurt inaccesibil ia Tot chiriaşul offline.
· APIService
Obținerea normelor de acces chiriaș la poarta de acces
Acest filtru a fost inert de când a fost scris. resultOrgId read org:domeniul: <host> de la Redis, nimic nu a scris vreodată acea cheie, și întoarcerea nulă a căzut prin pentru a permite; Geo Sucursala a fost un gol dacă-bloc cu un comentariu de amânare la SecurityService, care a fost nu se aplică nici. Fiecare cerere a trecut. Acum citeste verdictul SecurityService caches si cere ca serviciul pe o rata, asa ca politica trăieşte într-un singur loc decât într-un alt loc. Calea fierbinte este una Redis citeste; o rata costa un scurt-time-out HTTP apel pe organizatie si adresa la 30 de ani. Adresa clienţilor este cea mai potrivită speranţă publică a X-Forwarded-For. Proxies append, so the elementul din stânga este atacator-supplied țara din care se consideră că provine cererea. Exprimă sonde de viata, CORS înainte de zbor și obiectivul de decizie în sine, și niciodată adresa internă a clusterelor de judecători: traficul între servicii nu are o țară și Blocarea ar distruge platforma. Fail-deschis pe fiecare cale, cu un test per dependență. Asta stă în faţa tuturor chiriaşilor. Trafic API, astfel încât un filtru care blochează atunci când Redis este lent este o pană totală. De asemenea, picături ********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* schele de la comiterea inițială, într-un pachet fără @SpringBootConfigurare la Găseşte. Acesta nu a trecut; CI construiește cu -DskipTests așa că nimic observat. Îndepărtarea ei face 'mvn test' utilizabil aici.
· SecurityService
Aplicarea normelor de acces geo şi IP
Regulile au fost stocate, cached la Redis și niciodată consultat. AccesCheckController a fost singurul apelant al evaluării și nimic numit AccessCheckController; APIservice's Orgile de filtrare rezolvate dintr-o cheie Redis nimic nu a scris și tratat domnișoara ca permisiune. Configurarea unui bloc geo nu a făcut nimic. Serviciul de decizii de acces este acum autoritatea unică. Login îl numeşte direct, poarta filtrul și proxy-ul intern kamo ajung la aceeași decizie prin intermediul obiectivului de verificare; şi politica există o dată în loc de o dată pe strat. Copia Node a plutit departe suficient pentru a se potrivi cu nimic: a comparat tipurile de reguli cu "lista albă" /"temp-block" în timp ce Editorul scrie WHITELIST / TEMP BLOCK. Rezoluția GeoLite este cached în Redis pentru o zi, pozitiv și negativ, și sare adrese private în întregime. Adresa vine de la un antet, deci fără o cache negativ un apelant rotativ bogons transformă fiecare cerere într-o nouă sondă a tabelului 5.7M-rând forma DoS găsitByIpInRange a fost deja rescrisă o dată pentru a evita. ClientIpRezolvator citește cel mai bun salt public de X-For, nu cel mai stâng. Elementul din stânga este ceea ce clientul a trimis: anexe proxies, deci "X-forwarded-For: 8.8.8.8" plus propria anexă a lui Traefik ar fi lăsat pe oricine alege ţara blocul lor este judecat împotrivă. Fiecare regulă geo ar fi fost la un antet distanţă de bypass. Eșec deschis pe tot parcursul, per dependență și a afirmat per dependență. Un control al accesului care Eșuează închis pe un Redis wobble blochează fiecare chiriaș din platforma, care este un rău incident decât fereastra se închide. O adresă albă ocoleşte şi geo, deci un admin care îşi blochează propria ţară păstrează o cale de întoarcere.
· kamo-internal
Card de înregistrare a platformei pentru aplicația Zoom Marketplace
Completează calea de conectare a lui Zoom. Platforma deja rezolvă PlatformOauthProviderType.ZOOM, dar cu nici un card aici un operator de platformă a avut nicăieri pentru a introduce acreditările Marketplace, astfel încât furnizorul întâlnirea Setup ecranul a raportat întotdeauna un click conectați ca neînregistrate. Opțional prin proiectare: calea server-to-Server per-org nu are nevoie de nimic aici și rămâne implicit recomandat, astfel încât o carte goală păstrează pur și simplu un clic ascuns. Întâlnirile echipelor reutilizează înregistrarea Microsoft 365 existentă.
· kamo-internal
Microsoft Teams Furnizor telefonic din faţă în spate
Adds Teams to ************* și fire întreaga cale prin: selectie furnizor, Entra + Azure Communication Services config; Consimțământ admin chiriaș, per-membru conectați, și un softphone în-browser. Softphone-ul este partea care diferă structural de orice alt furnizor. Echipele nu expune un registrator SIP unor terţi, aşa că o linie de echipe nu poate fi înregistrate la SIP.js sau RingCentral's WebPhone. Traseul sprijinit este Azure Echipele personalizate ale serviciilor de comunicare: platforma de sprijin schimbă membru Entra token pentru un jeton ACS, și TeamsAcsPhoneSdk transformă că într-o apel agent în spatele aceleiași interfețe PhoneSdk implementa adaptoarele SIP, astfel încât Utilizați Softphone și fiecare componentă UI sejur-agnostic furnizor. SipCredențials câștigă acs* câmpurile opționale; sipInfo este pur și simplu gol pentru echipe. Pachetul ACS este numai pentru browser și importat dinamic în interiorul startului (), deoarece o import static ar sparge redarea serverului. Două echipe specifice adevărurilor au apărut în UI mai degrabă decât lăsat să eșueze la runtime: apelarea în browser este opțională (lăsați ACS gol și org încă devine prezența și istoricul de apelare, cu dialler ascuns, mai degrabă decât erori); și mesaj vocal este oprit în mod implicit pentru că echipele nu are mesaj vocal API în cutia poştală a fiecărui membru, astfel încât citirea lor este un material mai larg consimt ca un admin ar trebui sa opteze in mod deliberat. Membrul conecta cartela de pe fila telefon-setări este acum furnizor-conștient în schimb numai pentru RingCentral. Ambii furnizori au nevoie de o autorizaţie pentru fiecare membru. diferite motive: RingCentral deoarece un softphone se poate înregistra doar ca propria extensie a contului conectat, echipe deoarece prezenta scrie și chemarea schimbul de jetoane este doar delegat. Branding: tigla utilizează marca Microsoft corporative și denumirea produsului simplu. Microsoft permite numirea echipelor pentru a descrie integrarea, dar limitează echipele logo-uri și branding pentru a certificate Teams parteneri, astfel încât nici o Teams glyph este expediat. Verificat: npm test Paznicul cheie i18n şi paznicul de navigaţie al clienţilor trec amândoi. Coarde de dicționar debarcate Prima dată în dictionarul kamo-translation 0801a17.
· VOIPService
Microsoft Teams Phone as a provider
Teams is not one API, so the provider glues three control planes together: • Graph, app-only — call history (getPstnCalls), presence reads, directory and Teams device inventory. Call records are application-permission by design; Microsoft states plainly that they have no delegated form. • Graph, delegated — presence writes (Presence.ReadWrite exists only as a delegated, self-only permission) and voicemail, which lives in the member's Exchange mailbox because Teams has no voicemail resource at all. • Azure Communication Services — the in-browser softphone on the member's own Teams Phone line, via the custom Teams endpoint token exchange. This is the only supported route: Teams exposes no SIP registrar to third parties, and the Graph calling API joins as a bot rather than as the user. Capabilities are computed from what an instance is actually configured for rather than hardcoded, so an org without ACS reports voiceCalls=false and the UI hides the dialler instead of surfacing a 501 mid-call. Deliberately absent, because no Microsoft API exists at any version: SMS from a Teams number, call queues, call forwarding, auto-answer, and starting/stopping recording. Those stay on the interface defaults that raise 501. Credentials resolve per-instance first (an org registers its own Entra app — the common enterprise shape, and it needs nothing of Kamo the platform) and fall back per-field to a MICROSOFT_TEAMS row in the platform OAuth registry. Onboarding runs in two hops because the tenant must be discovered before it can be pinned: an admin signs in, the id_token's `tid` gives the real tenant, then they are sent to that tenant's /v2.0/adminconsent. Consent is confirmed by minting an app token and calling Graph — Microsoft returns admin_consent=True even on failure, and warns that the `tenant` redirect parameter is forgeable, so neither is trusted. Both Teams flows and the per-member delegated connect multiplex onto /api/voip/oauth/callback, the one path already public at the gateway, so APIService needs no new route. Change notifications ride the existing /api/voip/webhook for the same reason. Graph's handshake differs from RingCentral's — a ?validationToken query parameter echoed as text/plain — and is answered before anything else, since Graph drops notifications for ten minutes if an endpoint is slow. Subscriptions are created unfiltered on purpose: the subscription filter still targets the legacy `participants` collection that stopped returning data in June 2026. Two pre-existing defects fixed because Teams makes them load-bearing: • CallController, CapabilitiesController and CallFeaturesController resolved the provider via getPrimaryForOrg — the org's oldest active instance of ANY type. That is only ever right for a single-provider org. Teams will usually be a second provider, so every member's history, voicemail and agent state would have been served by whichever provider was created first. They now use a member-aware getForMember, mirroring what SipController already did. • Deleting an instance left member_voip_oauth_token rows behind, since there is no FK to cascade from, and they kept reporting "connected". Verified: mvn test — 133 tests, 0 failures (49 new).
· kamo-internal
Setare filă de configurare furnizor și setările de întâlnire gated capacitate
Adaugă fila de configurare a furnizorului la /setări/fetures/meets și face fiecare alte fil sincer despre furnizor este configurarea. useMeeting no longer builds meet.<domain>/<room> in the browser A făcut fiecare întâlnire o întâlnire Kamo Meets indiferent de configurare. Acum creează întâlnirea prin backend și utilizează URL-urile pe care furnizorul le returnează; așa că Centrul de Interacțiune, fereastra de instrumente de chat și directorul membru toate traseu prin abstractizare, fără modificări ale propriilor lor: ele împart Întâlnire Dialog, care împărtășește acest cârlig. - Setare furnizor: carduri furnizor cu un bar de acoperire setările, astfel costul comutația este vizibilă înainte de comutator mai degrabă decât descoperită ulterior pe o fila de control gri-out. Formularele credibile sunt numai returnări pe care câmpurile sunt stabilite, niciodată valorile lor și instrucțiuni de configurare pentru fiecare furnizor. - Gating capacitate: useMeetProvider citește setările suportate de furnizor și MeetSettingRow dezactivează restul cu un sfat instrument de numire a furnizorului. Fără suport setările sunt afișate mai degrabă decât ascunse, și sunt cu adevărat dezactivate decât doar diminuate, astfel încât acestea nu pot fi schimbate de tastatură. Salvează omite-le în întregime. Gating eșuează deschis un ecran de lucru este mai rău decât a arăta un control pe care backend-ul ar ignora. - Setări noi pe care ceilalți furnizori le susțin: se alăture-înainte-host, în-întâlnire chat, cota de ecran, dial-in, numai utilizatorii autentificati, lungimea codului de acces si incorporarea; lobby bypass domeniu de aplicare, prezentator și control participant, înregistrare nor; transcrieri, înregistrări de descărcare și invitații de furnizor-trimis. - /meet/join/<ref> is now provider-aware: Kamo Meets are încă o cheie unică Mented la timp click, Zoom și echipe redirecționa la URL-ul propriu al furnizorului. Acesta acceptă un ID de întâlnire sau un nume de cameră, astfel încât invitaţiile trimise înainte de această schimbare Continuă să lucrezi. - Link-ul de invitație de e-mail este construit dintr-o întâlnire validată UUID mai degrabă decât un nume de cameră, păstrând regula existentă că un URL furnizat de client nu este niciodată încredere într-un e-mail brand-org.
· kamo-shared-library
Tipul de furnizor MICROSOFT TEAMS
Adaugă MICROSOFT TEAMS la VoipProviderType. Enumul persistă ca ORDINAL pe - Deci poziţia e portantă. constant merge ultimul; clasa Javadoc spune acum mai degrabă decât lăsând următoarea persoană care să-l inspire. Nicio modificare a DDL-ului Whitelist, deci asta nu are nevoie de kamoInitializer. Adăugă două întrebări derivate pe depozitul MemberVoipOAuthToken: • gindBindByProviderAnd InterfaceId Id obiect Entra pe un record de apel Teams) înapoi la un membru Kamo. • ştergereByInfoId furnizorul îi lăsa în urmă încă raportând "conectat.".
· APIService
Traseu furnizorul de întâlnire OAuth apel înapoi
Zoom şi Microsoft redirecţionează browserul către această poartă după autorizarea unei org Aplicaţia lui Kamo. Popup aterizeaza aici cu nici o sesiune chirias ?state ?so the callback needs the sessionless, auth-stropping pass through the Email provider callback folosește deja, nu obișnuit /api/meet /** forward.
· MediaService
Intalnire abstractizare furnizor cu Zoom si Microsoft Teams
Întâlniri au fost Kamo Întâlniri prin construcţii. Numele şi nimic altceva. Acest lucru introduce abstractizarea și doi furnizori la distanță În spatele ei. indeplineste/oferta oglindeste stratul furnizorului de email: IntalnireProviderRezolvator asambleaza un Context al Întâlnirii (acreditari decriptate, o finanţare OAuth reîmprospătată, politica org, cont gazdă furnizor-side) și o hartă a capacităților, astfel încât apelanții solicită ÎntâlnireScheduler mai degrabă decât ramificare pe tip furnizor. Adăugarea unui al patrulea furnizor înseamnă adăugarea unei boabe, nu editarea site-uri de apel. - KamoMeetProvider: nume de cameră şi construcţie URL, mutat server-side. ă org-namespacing care oprește doi chiriași care împărtășesc o conferință Prosody folosit pentru Trăiește în browser; este acum fixat de teste. - ZoomProvider: REST v2, Server-to-Server OAuth sau aplicația Marketplace. Creează în numele membrului organizator, trage înregistrările și transcrierile cloud. - MicrosoftTeamsProvider: Graf onlineMeetings, app-only or delegated. Este Sondele de încercare de conectare care îndeplinesc crearea, deoarece politica de acces la aplicație Echipele necesită, de asemenea, este un lucru obișnuit un admin ratează numai permisiunea Autentifică bine şi apoi 403 la fiecare întâlnire. Şedinţă Caracteristica este contractul cu admin UI: fiecare furnizor declară setările pot fi onorate, iar ecranele de setări dezactivează restul. Cererile sunt afirmate mai degrabă în teste decât de încredere, deoarece un furnizor suprasolicitant produce comută că în tăcere nu face nimic FurnizorRecordingSweep trage înregistrări de la distanță în propriul depozit Kamo astfel încât rezumatele de păstrare, cotă și post-întâlnire funcționează identic pentru fiecare furnizor. Descărcările sunt limitate: acest serviciu servește, de asemenea, chat și întâlniri în cadrul unui 1Gi limita, astfel încât o înregistrare supradimensionată este omis cu un avertisment, mai degrabă decât riscul capsula. Credențialele sunt criptate cu cheia platformei existente, astfel încât nici un nou secret nu are să fie prevăzute. Manipularea sesiunii împărţită în funcţie de criteriile finale se deplasează în Faceți cunoștință cu SesssionRezolver .
· InitializerService
Schema pentru stratul de întâlnire multi-furnizor
Creează ******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** coloanele de identitate a furnizorului către REC MENȚIUNEA RECING și RECOMANDAREA RECOMANDĂRII ȘI Setări cu zoom/Teams-capabile pentru ORG MEET CONFIG și completează fiecare set existent organizarea unui rând explicit KAMO MEET/ACTIVE. Două lucruri pe care le-am învăţat, ambele codificate aici. Hibernate ddl-auto construiește Sesiunea Factorie înainte de orice comandăLineRunner, astfel încât declarațiile de tabel CREATE în mod normal, nu-op și coloanele ajung cu nici un implicit Aprovizionarea cu acte de identitate și marcaje temporale în mod explicit, în loc să se bazeze pe ele, motiv pentru care Prima versiune nu a introdus nimic. Şi unicitatea declarată pe entitatile inseamna ca Hibernate isi mentine propriile constrangeri, asa ca numele indexeaza un revizia anterioară adăugată au fost duplicate; acestea sunt retrase aici. Adaugă com.kamo.z.shared.meet la lista explicită @EnableJpaRepositorii, fără pe care noile depozite nu le au şi KI le anulează înainte ca vreun alergător să tragă.
· kamo-shared-library
Model de reuniuni ca furnizor-agnostic
Kamo Meets a fost singurul suport posibil: OrgMeetConfig a fost un plat Meet Sacul de setări şi un MeetingRecord nu aveau decât un nume de cameră. Acest lucru adaugă schema pentru rularea unei organizații pe Zoom sau Microsoft Teams în schimb. - meet. provider: MeetingProviderType / MeetingProviderStatus, the per-org OrgMeetingProviderEntity (bib credibil criptat, ultima stare verificată) și OrgMeetingOauthTokenEntity, oglindind pachetul de e-mail ofertă care deja susține abstractizarea furnizorului de e-mail. - MeetingRecord câştigă propria identitate a furnizorului de găzduire; se alăture și gazda URL-uri, parola, cont gazdă S-a împăcat cu cine o găzduieşte. - Intalnire inregistrare castiguri furnizorRecordingId, care mentine traseul unei telecomenzi cloud de înregistrare idepotent furnizor. - OrgMeetConfig câștigă setările Zoom și Teams susține că un Doar Meet config nu a avut nici un motiv pentru a transporta: unire-înainte-host, modelarea codului de acces, lobby ocolirea domeniului de aplicare, controlul prezentatorului și al participantului, înregistrarea norilor, transcrierile; invitații de furnizor-trimis, și întâlnirile gazdă de rezervă sunt create în atunci când un membru nu are cont asupra furnizorului. Fiecare org cu nici un rând furnizor se rezolvă la KAMO MEET, astfel încât acest lucru este inert până la o Admin alege altfel. Coloanele au fost aplicate producţiei de către KamoInitializer înainte să aterizeze. PlatformOauthProviderType câștigă ZOOM (9) pentru aplicația Zoom Marketplace; echipe reuniuni de reutilizare a MICROSOFT (3). Test de pază se mișcă cu ea, deoarece un enum și testul de fixare a id-urilor sale persistente nu poate ateriza separat.
· kamo-internal
Țările cu lista de permise de pe cardul de geoblocare
Cartea putea nega doar ţările, astfel încât o org care serveşte o ţară a trebuit să enumere Pe toate celelalte. Acum are ambele liste: un mod de comutare alege care lista țara aleasă aterizează şi cele două mese stau unul lângă altul. O listă de permise goale permite orice nu este blocat; un non-gol neaga fiecare țară absent din ea. Această inversare este suficient de drastică pentru a afirma pe card mai degrabă decât să plece să fie descoperite, astfel încât nota de mai sus tabelele spune care regim este în vigoare. Limita unică (org, țară) menține o țară pe exact o listă, care ar face Readding-l la celălalt eșuează, astfel încât fiecare rând poartă o acțiune mișcare care se răstoarnă prin Put În schimb.
· SecurityService
Ţări cu lista de permise alături de blocurile geo
Secţiunea geo doar a negat vreodată: o ţară a fost blocată sau absentă. Orgs that doresc să servească o țară a trebuit să enumere fiecare alta, care este de nepătruns și în tăcere greșit în momentul în care apare un nou cod de țară. org geo block rules.is blocked deja a existat și a fost hardcoded adevărat, astfel încât un permis Regula este că coloana set fals Evaluare: un bloc explicit câştigă, atunci o listă permite nega tot ce lipsește de la ea, și o listă de permise goale totul nu este blocat. Care păstrează vechile orgi care se comportă exact ca înainte. publicăGeoReguli acum nave ambele părți ale regulii stabilite, deoarece permite regulile sunt portante odată ce există unul. Încărcături cache scrise înainte de această schimbare transporta nici un câmp blocat și Supravieţuieşte cache-ului TTL printr-o desfăşurare, aşa că un câmp lipsă e blocat. De asemenea, domeniul de aplicare setBlocked și ștergeți în org apelantului. șterge o regulă rezolvată anterior numai de către UUID, astfel încât un ID de la un alt chiriaș ar fi fost onorat.
· kamo-shared-library
Citește calitatea ajustărilor și versiunilor orientative
Un preț asamblat este o celulă de bază PLUS ajustările stivuite pe ea, deci judecând numai celulele judeca jumatate din numar: un curat citit 99.875 cu o citire gresita -1.50 LLPA pe partea de sus este încă un preț greșit. MlosPriceAdjustment poartă acum calitatea de citire din care o ajustare, astfel încât poarta semn-off poate lua cea mai slabă legătură peste întreaga adunare. MlosGuidelineVersion primeste acelasi camp pentru consistenta cu coloana de calcul -- deja transporta documente sursă, astfel încât aceasta completează proveniența sa. Ambele nu pot fi anulate; nul înseamnă nici un semn mai degrabă decât bun. Coloane aplicate prod CockroachDB via KamoInitializer.
· kamo-internal
Deschide link-uri înapoi în această aplicație în fila membrul este deja în
Mail în panoul de lectură deschide fiecare link într-o filă nouă, care este potrivit pentru internet întreg și greșit pentru noi. Mesajele noastre de notificare sunt aproape în întregime link-uri înapoi în aplicație, și trimiterea celor la o filă proaspătă aruncă sesiunea membru are deja și le face să stea printr-o cizmă rece pentru a ajunge la o pagină această filă ar putea face imediat. Aceeaşi origine este întregul test "Seamănă cu un domeniu Kamo" şi nu o potrivire sufixă pe domeniul orgului. Asta este. set exact de URL-uri sesiunea curentă este valabilă pentru, care este întregul motiv pentru a rămâne în această filă, și este ne-poofable prin e-mail: gazda altui chiriaș, un lookalike sau userinfo care indică gazda în altă parte sunt toate origini diferite și Du-te la o nouă filă ca orice alt link străin. Rutarea mai degrabă decât atribuirea locației: o încărcătură completă document rupe în jos React copac și distruge fiecare fereastră instrument deschis, împreună cu orice proiect netrimis, motiv pentru care Acest repo are o poartă de construcţie împotriva navigaţiei interne dure. Modificat și mijlociu click-urile sunt lăsate în pace Ascultarea de la părinți funcționează deoarece cutia cu nisip păstrează deja permis-aceeași origine pentru măsurarea înălțimii în timp ce omite permise-scripționare, astfel încât nimic din e-mail Se execută vreodată; handler este al nostru, atașat de afară. O capcană care merită înregistrată, prinsă prin propriul test: returnând o cale mai degrabă decât un URL este necesar, dar NU este suficient. "https://host//evil.test" este cu adevărat aceeași origine; și numele său de cale este "//evil.test" Urmează off-site-ul. Un e-mail deschis redirecționare care trece o verificare de origine. O astfel de legătură Acum se încadrează printr-o filă nouă, în cazul în care browserul rezolvă URL-ul real, inofensiv, Mai degrabă decât a fi rescris în tăcere undeva email-ul nu a indicat.
· kamo-shared-library
Încrederea în extracţia pe celule + provenienţa matricei de eligibilitate
Două lacune în modelul de încredere, ambele pe calea banilor. Per-cell. Un etaj la nivel de foaie este granula greșit pentru a judeca un preț: un singur Cupon prost citit trage tot foaia în jos și ar trimite fiecare alt preț pe ea la un om, în timp ce un etaj foaie de mare spune nimic despre celula specifică un împrumutat a fost de fapt citat din. Nu-ţi face griji. Înregistrează cât de bine Această rată/preț / rând de blocare a fost citit, astfel încât un cupon greșit costă doar prețul propriu. Demonstraţie de flexibilitate. MlosEligibilitate Matrix nu a avut cale către un document sursă la Toate -- singura sa ruta a fost un ghid NULLABLEVersionId, astfel încât o matrice promovată ar putea să nu fie urmărite în foaia din care a venit. Eligibilitatea decide dacă este un împrumut ofertabil, ceea ce face exact în cazul în care o negare trebuie să fie explicabil; o proveniență Există un decalaj în momentul în care un debitor este refuzat. Acum poartă SourceDocumentId și același contract de încredere de extracție ca și coloana vertebrală a foii de calcul. Atât nul, și nul înseamnă nici un semn mai degrabă decât bun. Coloane aplicate pentru prod CockroachDB via KamoInitializer.
· kamo-signer-monorepo
Arată telefonul agentului, fără taxe și e-mail pe copia clientului
· kamo-internal
Arată telefonul agentului, fără taxă și e-mail pe previzualizare
Fiecare pe linia sa proprie: un run-on de două numere și o adresă citește ca un șir și este format greşit.
· SecurityService
Rezolvați datele de contact publicate ale agentului
E-mailul vine de la cutia poştală primară a membrului, mai degrabă decât de la TeamMember.emailWork coloana este un text gratuit înainte de furnizarea căsuţei poştale şi de obicei nu este de acord cu adresa pe care o trimit. Rămâne de rezervă atunci când nici o cutie poștală este primară. Un membru VOIP cu o extensie este publicat ca propria linie a orgului plus că extensia, oferind numărul fără taxă atunci când org are unul. Fără o prelungire, lor telefon de lucru Un handicapat. VOIP config nu publică nimic, deoarece această extensie nu răspunde. Fiecare aspect este defensiv: nu reușesc să facă un document orientat spre client deoarece o cutie poștală Rândul lipsește ar fi mai rău decât imprimarea o modalitate mai puțin de a face contact.
· kamo-shared-library
Publică orice mod de a ajunge la agent, nu doar un nume
Numai numele și titlul spun unui client care deține citatul, dar nu cum să întreb despre el. Blocul poartă acum e-mail și telefon, rezolvate de apelantului trăiește în schema furnizorului de e-mail și extinderea în configurația VOIP, nici accesibil de la un ajutor static. Linia principală și fără taxe sunt câmpuri separate astfel încât documentul să poată imprima atât: alegerea între ele este alegerea ceea ce apelul costă clientul. linieCuextensie perechi o extensie cu linia org se atârnă off, și returnează nul dacă oricare jumătate lipseşte. Un orfan "Următorul. 204" nu este un număr pe care să-l poată suna oricine şi un gol. Linia de org ar devia clientul spre tabloul de distribuţie ca şi cum ar fi a agentului.
· kamo-shared-library
Extragerea încrederii în catalogul coloanei vertebrale + off automat
Un preț este la fel de demn de încredere ca foaia a fost asamblat de la, și nimic pe calea de stabilire a prețurilor a purtat acest semnal: încrederea a existat NUMAI în prepromovare rânduri de montare (MlosExtracted Candidate) pe care nici un cod de producție citit. ***************** este cea mai slabă încredere pe teren pentru candidaţii aprobaţi promovaţi în versiune -- minim, niciodată rău. O foaie de 200 de celule curate și o medie de 0.20 greșite la 0.96 și ar șterge orice prag, în timp ce acea celulă este cea care face un împrumut greşit. Null înseamnă NU SEMNAL (autorizat manual sau promovat înainte de existenţa coloanei) şi consumatorii trebuie refuza sa se aprobe automat; citirea absenta la fel de buna este modul in care un pret neverificat iese neverificat. VORM-protejat ca celelalte coloane pretioase - surprins în @PostLoad și diffed in @PreUpdate, sau ar fi o gaură mutable tăcut în lanțul de audit. MlosPricingSignaff câștiguri automatizate / bază încredere / prag aplicat. Fără ei o aprobare mașină este imposibil de distins de la un om, cu excepția unui membru ID, care pe calea banilor este un defect de audit. Pragul este depozitat lângă valoarea deoarece configuraţia se mişcă: "încrederea a fost de 0,72" nu poate fi judecată mai târziu fără să ştie dacă barul din acea zi era 0,70 sau 0,90. Coloane aplicate pentru prod CockroachDB via KamoInitializer.
· kamo-internal
Citează fila
Un server-pagină DataGrid lângă Leads, cu căutare peste număr și titlu, stare, total gama și gama de date create. Filtrele împărtășesc o debușă și se prăbușesc într-o singură interogare, astfel încât ajustarea unui interval în timp ce dactilografierea costă mai degrabă o călătorie rotundă decât una pe teren. Orice modificare a filtrului Se resetează la pagina 1 Expirarea este afișată în afara statutului: un citat SENT poate fi trecut de data de valabilitate și încă citit ca SENT, astfel încât aceste rânduri transporta propriul lor marker în loc de a fi tăcut marcat greşit. Rânduri și coloana de plumb ambele traseu în tab-ul de citate care plumb.
· SecurityService
GET / cotații/cont/ {uid}
Datele sosesc ca și siruri de caractere ISO și parse indulgent: un filtru clientul trimite prost ar trebui Îngustează nimic mai degrabă decât 400 întreaga reţea. O singură dată "la" acoperă întregul În acea zi, în caz contrar filtrarea la astăzi nu întoarce nimic ridicat de la miezul nopții.

Universul tău te așteaptă.
Începeți gratuit în câteva minute.Adăugați produse oricând sunteți pregătit — fără migrare, fără autentificări noi.
Gratuit pentru totdeauna — nu este necesar un card de credit