Changelog
Was ist neu?
Jede Verbesserung an der Plattform, wie sie geliefert wird.
· kamo-marketing
CSP, COOP und Trusted Types
Fügt die drei Kopfzeilen der Vertrauen und Sicherheit Audit gefragt, plus Referrer-Politik und Genehmigungen-Politik. Jeder Ursprung in der Politik wurde genommen von dem, was die Website tatsächlich lädt, anstatt zu erraten, das Chat-Widget-Bundle auf theme.kamocrm.com (die eine WebSocket für Medien öffnet. und ruft api. und capcha.), das analytische Skript auf Analytik., die HLS-Leiter des Helden, und die ***'s Herausforderung Endpunkt. Geprüft die gebaute Seite gegen die fertige Politik Ressource für Ressource: Null blockiert. ON script-src 'unsafe-inline' - das ist ein echter Kompromiss und es lohnt sich, dies zu sagen anstatt zu begraben. Die starke Form eines CSP ist ein pro-Antwort nonce mit "streng-dynamisch", und es ist nicht verfügbar: ein nonce bedeutet das Lesen von Headern() während des Renders, das die Route aus der statischen Erzeugung auswählt. Diese App hat 200 Pfund Vorgerenderte Routen und ihre Statik ist tragend - eine dynamische Route mit keine Ladenfläche prefetches nichts, so dass jeder Linkklick kalt beginnt. Dort ist auch kein hash-basierter Escape, denn die Inline-Skripte sind Nexts eigene RSC Flugdaten, deren Inhalt sich je und pro Build unterscheiden. Also: Dieser CSP stoppt NICHT ein injiziertes Inline-Skript. Was es tut, ist eng zu halten jede externe Skript, holen, Frame, Bild und Medienlast an bekannte Ursprünge, Verbot Plugins, Pin der Basis URI so injiziert Markup kann nicht wiederroot relative URLs und Stop-Formular-Posts an Dritte. TRUSTED TYPES brauchte drei Versuche, um sicher zu gehen, und die Ausfälle sind die interessanter Teil: 1. Eine einfache Inline <script&s zuerst im Layout <head's ist nicht first. Reagieren Hebt Next's "<script async src" Tags über alles, was das Layout wiedergibt, so die Politik landete nach zwölf von ihnen - und async Skripte führen die Moment, sie beenden das Herunterladen. Turbopacks Laufzeit ist dabei und tut es "createElement("script")" setzt dann "src", die exakte Spüle, die wirft ohne Politik. 2. "next/script" mit strategy="beforeInteractive" hat es auch nicht bewegt; noch zwölf Skripte vor sich. 3. Was es sicher macht, ist, dass kein Waschbecken so früh feuern kann. Alle 78 Flugdaten Drücker sind im Körper - zuerst im Offset 193,072, mit </head" bei 11.940 . so React kann nicht beginnen Hydratation, bis lange nach der Politik installiert ist, und es gibt keinen Senken-Touching-Code in <head" vor ihm. Verifiziert auf der gebautes HTML und nicht angenommen. Zwei Dinge wären zerbrochen, ohne dafür gegrenzbar zu sein. Das *** Widget ist ein Svelte bauen und schafft eine Politik namens "svelte-trusted-html"; ein Politikname ist ein Laufzeit-String, so dass nichts über sie Oberflächen in Arten, lint oder der Build, und Das Weglassen von der Genehmigungsliste hätte geworfen und den Kontakt und Demo genommen Formen nach unten. Und hls.js und die *** beide bauen Web-Arbeiter aus createObjectURL, so muss die Politik passieren "blob:" vor seiner Ursprungsprüfung blob: URL hat keine nützliche .origin und sonst hätte es versäumt, unter der Held Rolle mit ihm. Die Police createScriptURL wird gegen kamocrm.com, die streng ist überprüft freizügiger als Skript-Src, so dass es nie etwas verweigern kann, das CSP erlaubt. createHTML-Pässe durch und sämt NICHT: ein echter Sanitiser würde müssen auf dem kritischen Pfad Schiff und könnte lautlos mangle die JSON-LD-Blöcke und das Widget Markup. Diese Hälfte ist ein Chokepoint und ein Audit Haken, nicht ein filtern und es ist, wo als nächstes zu härten. Cross-Origin-Resource-Policy wurde geschrieben und dann entfernt. Übergangs gewandt Es deckt die Open Graph Bilder ab, die es speziell geben soll Eingebettet von anderen Ursprüngen. Frame-Ahnen ist 'selbst', um die X-Frame-Optionen zu entsprechen: SAMEORIGIN ist bereits serviert, anstatt sich zu "kein" zu straffen und eine Einbettung zu brechen, an die sich niemand erinnerte. Veredelt gegen den realen Standalone-Server, nicht nur die Konfiguration: Headers vorhanden sowohl auf einer vorgerenderten Route und einer *** Route, und die langlebige Anlage Cache-Control noch intakt.
· kamo-internal
Erstellen von Tracking-Codes anstelle des Empfehlungsplatzhalters
/marketing/discounts war ein ComingSoon Stub; es ist jetzt /marketing/Tracking, a Arbeitsbereich, mit dem alten Pfad als Client-Umleitung so vorhanden gehalten Lesezeichen landen immer noch. Auf dem Reiter steht "Tracking Codes". Ein Mitglied prägt einen Code und die Seite zeigt ihnen den Link, den es produziert, gebaut von der Host, der tatsächlich die Seite bedient - internal.acme.com ergibt ************ - also ist es für jeden richtig White-Label-Domain ohne Anwendungsbereich wird irgendwo fest codiert. Das Gitter trägt die sechs Summen pro Code, und eine Reihe öffnet eine Schublade mit dem Konvertierungstrichter, die letzten dreißig Tage, Top-Standorte, Geräte und Referer, und die Besucher Ein Besucher öffnet sein eigenes Panel mit Herkunft, Netzwerk, Client, UTM Zuschreibung und eine Zeitleiste von jeder Seite, die sie geöffnet haben. Länderflaggen verwenden Reaktionsfeld-Flagge, wie anderswo. Scope folgt den Rechten: "Mein Team" erscheint für beide Quereinzugsrechte, "Alle Mitglieder" nur für VIEW_ALL_MEMBER_TRACKING, und der Selektoren folgt dem Umfang der SERVER sagt, dass es angewendet wird und nicht der angeforderte, so dass eine Herabstufung nicht Lassen Sie das Mitglied ihre eigenen Reihen unter einem "Alle Mitglieder"-Etikett lesen. Chromfarben von --color-primary und --color-secondary durchgehend, da jeder org ist White-Label und MUIs Standard-Button würde das gleiche blau machen für alle von ihnen. Zwei Dinge, die das Netz brauchte, die nicht offensichtlich sind. Reihenklicks werden auf einem gefiltert explizite Marker-Attribut statt Stopp-Propagierung, weil AG Grid hört zu native auf dem Zeilentainer, während Reagieren delegiert auf die Wurzel Handler läuft an zweiter Stelle, so dass die Kopie-Taste und das Zeilenmenü beide geöffnet haben die Schublade. Und die Suche ist nur serverseitig: ein zweiter Client-seitiger Schnellfilter konnte nur von einem korrekten Ergebnissatz abziehen und Zeilen verstecken, die auf Mitglied passten Name in einem Umfang ohne Mitgliedsspalte. VIEW_REFERRAL_CODES und MANAGE_REFERRAL_CODES verlassen die nicht ausgedüftete Liste Gate reale Dinge jetzt - über eine regenerierte Prüfung statt einer Hand bearbeiten. The TS Spiegel erhalten die beiden neuen Rechte und den MARKETING ServiceType, auf den sie zeigen, die gefehlt hatte.
· kamo-register
Tragen Sie die Marketing-Verweisung in die Anmeldung
Die Marketing-Website markiert einen überwiesenen Besucher mit kmrt_vid und kmrt_src auf der Shared apex, also registrieren.<apex? kann sie lesen; handleVersundung sendet beides in der Anfrage Körper, Rückfall auf ?mrt= für den Code, wenn der Besucher ankommt mit der Link noch in der Adressleiste. Körper, nicht Header: die /api-Proxy-Streifen Cookie und die Ingress-Neufassungen X-Forwarded-Host, weshalb die Cookies nicht httpOnly sind. Fehlende Werte werden eher weggelassen als als leere Strings gesendet, da die meisten Anmeldungen weder haben. Der Cookie-Reader, den die Logout-Seite inline hatte, ist jetzt app/lib/cookies.ts und gemeinsam von beiden Anrufern, anstatt dass ein zweiter Parser daneben geschrieben wird.
· kamo-marketing
Einen Partner Link ehren und berichten, was er gebracht hat
Ein Besucher, der https://www.<apex?mrt=<code" folgt, bekommt zwei First-Party-Cookies von der Kante Middleware - eine undurchsichtige GUID, die zwei Jahre und der Code sich für neunzig Tage - und jede Seite, die sie danach öffnen, wird einmal gemeldet, aus dem Leerstand, von sendBeacon. Die Domäne wird von den weitergeleiteten Headern abgeleitet, nicht von nextUrl. Nächster Builds die URL der Middleware von ihrer eigenen Höradresse, also ist nextUrl.hostname Container, und die Domain-Attribut stillschweigend nie erschienen: ein Host-only-Cookie angeheftet auf www, dass Register.<apex? kann nicht lesen, die die Überweisung mit verliert nichts fehlschlägt irgendwo. Cookie-Zustimmung löscht durch den gleichen Helfer, so dass die Zwei können nicht wieder auseinanderdriften. Ein Besucher, der nie einem Partner-Link gefolgt ist, wird nie ein Cookie gegeben und nie Leuchtfeuer überhaupt. Das ist es, was das, was das hält, anstatt ein Banner zu umschalten Verhältnismäßigkeit: Der Rekord hinter den Gesamtsummen eines Partners ist, was dieser Partner bezahlt wird gegen, und eine Zustimmung Gate würde nicht machen die Zahlen kleiner, würde es machen sie falsch - die Besuche immer noch passieren und die Anmeldungen immer noch konvertieren, sie nur aufhören, zuzurechnen. Beide Cookies werden unter Essential auf dem Cookie veröffentlicht Politik mit einer Kontrolle, die sie klärt. Unsere eigene Produktanalyse bleibt gated. /api/mrt ist eine Vertrauensgrenze, keine Pfeife: es befestigt den API-Schlüssel dieser Seite, also validiert die GUID, den Code und die gemeldete URL, baut die Nutzlast von legt Werten, die sie besitzt, lehnt einen standortübergreifenden Anrufer ab und leitet nur die Einbrüche ein Peer IP - die inbound X-For-Kette wird am linken Ende kundengesteuert und würde sonst lassen Sie einen Anrufer wählen Sie die IP der Kommission Bericht Aufzeichnungen. Es antwortet 204 vor der Weiterleitung und warnt höchstens einmal pro Minute, wenn der stromaufwärts ist unerreichbar, weil die vorherige Form behandelt einen 404 genau wie Erfolg. Statische Darstellung ist unberührt: keine Cookies() oder Header() in einer Seite, kein Script Tag, keine Framer-Bewegung auf der Beacon. check-mrt-cookie.ts pins die Invarianten, die keine andere Wache haben, einschließlich, dass das Leuchtfeuer ungesunde bleibt und dass nichts ist von einem unreferenzierten Besucher gesammelt.
· SecurityService
Anmeldung und org-created für verfolgte Besucher
Die Registerseite leitet jetzt die Marketing-Besucher-GUD und Tracking-Code in der Antragskörper - kein Header, weil der Proxy Cookie und den Einbruch abstreift rewrites X-Forwarded-Host und Register() gibt sie an ein Anmeldesignal weiter, wenn sie sind vorhanden. Die meisten Anmeldungen tragen keines und veröffentlichen nichts. MarketingSignalPublisher serialisiert mit einem LOCAL ObjectMapper, absichtlich nicht die gemeinsame Ban. Diese Beine schreibt auch die Redis *** Sitzungskarte und 65 Anruf Websites lesen ids wieder aus ihm als Nummer; geben es eine globale Long-String-Regel verwandelt Org-Auflösung in eine ClassCastException, die die Helfer schlucken, und null org ist ein 401 auf jeder authentifizierten Anfrage über vier Dienste. Die Publisher ist best-anfiness, hält eine optionale NATS-Verbindung, und wirft nie. Beide Signale werden nach dem Engagement mit der Nutzlast-Schnappshot im Inneren der Transaktion, so dass der Verbraucher nicht nach unten schauen kann eine Benutzer-oder Organisationsreihe, die noch nicht gebunden. RoleRightsSyncSeedTest erhält einen negativen Fall: Keines der beiden neuen Trackings Rechte können jemals NEW_RIGHT_SEEDS eingeben, da das Aussaaten jeder bestehende Empfehlungscode-Inhaber-Sichtbarkeit in die Analyse der Kollegen auf Besucherebene auf dem Entladeboot. Ihre IDs sind bei 200 und 201 festgepinnt.
· BillingService
Veröffentlichen Sie die bezahlte Konvertierung für verfolgte Organisationen
Beide Wege, die BillingSourceType.PAID jetzt veröffentlichen marketing.visitor.paid, weil das Einhaken nur eine leise verfehlt die Hälfte des Verkehrs . AccountSubscriptionService behandelt die Konsole eigenen abonnenten, ConsumerCheckoutService die Stripe Kasse. Drei Dinge, dies richtig macht mit Absicht. Es veröffentlicht auf der TRANSITION, Lesung die vorherige Quelle vor dem Schreiben und Brennen nur, wenn es nicht schon war PAID, so dass eine Planänderung oder ein re-POSTed "Change Plan" kann nicht die Zähler aufblasen. Es schnappt Schüsse in eine unumstößliche Aufzeichnung innerhalb der Transaktion, weil Konto und targetOrganization sind beide faul und lesen sie von AfterCommit Würften. Und die org es berichtet, ist die TARGET-Organisation, nie der Zahler - ein Elternteil Konto zahlt routinemäßig für ein Abonnement für ein Kind org, und der Trichter zählt die Org, die konvertiert ist, nicht die, die die Karte hält. Registriert durch ************ anstatt veröffentlicht inline, die auch recordPaidFromCheckout richtig: seine @Transactional schließt sich die äußere Transaktion des Stripe webhook, also nur ein AfterCommit-Haken feuert auf die echte Grenze zu begehen.
· APIService
Versendet die Tracking-Strecke an MediaService
Clones forwardPublicWebinar anstatt der generischen vorwärts(): diese Methode druckt jede URI, Header-Karte und Körperlänge zu stdout ohne Niveau, und ein Besucherbeacon trägt eine IP und einen Referer. Der API-Schlüssel ist hier eine Tarif-Limit und Missbrauchskontrolle, keine Mietgrenze. Eins Marketing-Pod dient jedem www.* Host mit einem öffentlichen Schlüssel, so dass der Schlüssel org ist immer die Plattform org - die Tracking-Code eigene OrganisationId ist, was entscheidet Mietjahr, nachgelagert in MediaService. Diese Argumentation ist in einem Kommentar auf dem Anruf Website, damit es nicht "fixiert" in eine defekte org überprüfen später.
· MediaService
Servieren Sie die Tracking-Codes Registerkarte und die Besucher-Beacon aufnehmen
MediaService unterstützt bereits die anderen Marketing-Tabs, so dauert es beide Hälften der Tracking-Codes: die authentifizierten CRUD und Statistiken Oberfläche bei /api/media/marketing/tracking, und der öffentliche Datenträger hinter APIService Kante. Der Ingest-Handler tut nichts anderes, als zu validieren und vor sich herzuschrecken. Alles real - die Code-Lookup, die Geo-Lookup, der User-Agent parse, die vier schreibt . passiert auf einem begrenzte Ausführender aus dem Anfrage Thread, und die Antwort ist ein 202 mit einem leeren Körper unabhängig vom Ergebnis, denn eine Marketing-Seite darf nie auf Analytik warten und ein öffentlicher Anrufer darf nie erfahren, was schief gelaufen ist. Die Ablehnungspolitik ist AbortPolicy, nicht CallerRunsPolicy: Caller-Runs würde die Datenbankarbeit zurückschieben auf dem HTTP-Thread, das genau das ist, was diese Form zu verhindern existiert. A volle Warteschlange lässt den Treffer fallen und zählt ihn. Jeder vom Client gelieferte String wird auf seine Spaltenbreite geklemmt, bevor er ist beharrte. Hibernate nicht durchsetzen @Column(Länge) zur Laufzeit, so auf eine Öffentlichkeit endpoint a over-length Refer oder Accept-Language ist SQLSTATE 22001 und nimmt die ganze Leuchtfeuer mit ihm - trivial von jedermann ausgelöst. Ein Besuch ist neu, als die Linkreihe zuletzt vor mehr als 30 Minuten gesehen wurde, passend die Analytik installieren eigenen Fenster, so dass die beiden nie uneins über "Besuche". Bots werden geparst, fallen gelassen und gegen nichts gezählt. Umfang ist Server-Seite aufgelöst und neu validiert: "Verwaltet" muss entweder Cross-Mitglied rechts und beinhaltet immer den Anrufer, "alle" Bedürfnisse VIEW_ALL_MEMBER_TRACKING und liest nach Organisation, so dass keine IN-Klausel jemals eine leere Sammlung übergeben. Ein nicht autorisierter Umfang wird auf "eigene" herabgestuft, anstatt Fehler, und die Antwort spiegelt den Umfang tatsächlich angewendet, so dass der Client kann bewegen Sie seinen Selektor, anstatt darüber zu lügen, was das Mitglied betrachtet. Die Antworten sind Aufzeichnungen mit String-IDs und numerischen Zählern. MediaService hat keine Wire-Level Long-String-Regel, so dass eine rohe Long in einer Karte würde eine JS-lossy-Nummer versenden mit nichts, um es zu fangen; TrackingCodeDtoWireTest Pins beide Hälften davon. Der dauerhafte Filter des Konvertierungskonsumenten ist marketing.visitor.* und ist repariert. Für immer - ein langlebiger hält den Filter, mit dem er erzeugt wurde, und es später zu erweitern ergibt eine dauerhafte SUB-90011 auf einen Verbraucher, der immer noch gesund aussieht. Es stößt ein Zähler nur, wenn der bedingte Stempel tatsächlich eine Reihe beeinflusst. Eine nächtliche versöhnen recomputes alle sechs Zähler aus Reihen, die dieser Dienst besitzt, so dass ein fallengelassen zukrementieren heilt sich selbst.
· kamo-shared-library
Modell-Tracking-Codes, ihre Besucher und die Besuche, die sie mit sich bringen
Ein Mitglied prägt einen Code, teilt ************ und die sechs Summen auf der Registerkarte Tracking Codes beantworten, was dieser Link tatsächlich getan hat: einzigartige Besucher, Besuche, Seitenanfragen, Anmeldungen, Organisationen erstellt und bezahlt Konten. Vier Tische tragen es. MARKETING_TRACKING_CODES speichert den Code-String selbst anstatt es von MemberId und Iteration zu recomputieren, so dass die Öffentlichkeit Pfad einnehmen ist eine Unique-Index-Sonde ohne Parsing und eine missgebildete ?mrt= ist ein Miss statt einer NumberFormatException. MARKETING_VISITORS ist die Identität Wirbelsäule, eine Zeile pro Cookie GUID, und seine zugeschriebenen Code ist einmal geschrieben und nie bewegt: mit First-Touch-Zuschreibung der drei Konvertierungszähler können nicht doppelt zählen Besucher, der später mit einem zweiten Code anreist. MARKETING_VISITOR_CODES ist der Besucher x Code Link und die Autorität für die Verkehrszähler, und MARKETING_VISIT_EVENTS ist die anhängende Zeitleiste, die die Besucher-Schublade liest. Die Zähler werden beibehalten, nicht abgeleitet, weil das Gitter macht sechs von ihnen pro Reihe und sechs COUNT(DISTINCT) Aggregate über eine Onend-Ont-Only-Tabelle in einer Reihe speichern ist ein Scan pro Seitenladung. Was macht das sicher ist, dass jede Beule ist ein atomar SET x = x + 1 statt eines read-modify-Writes und jeder Konvertierungsstempel ist eine bedingte UPDATE gated auf IS NULL so eine neu gelieferte NATS-Nachricht-Updates Null-Zeilen - der rowcount ist der Dedupe. Beide "First Time seen"-Tests sind native INSERT ... ON CONFLICT NICHTS für die Der gleiche Grund. Die offensichtliche Alternative, fangen die einzigartige Verletzung und Wieder lesen, nicht hier arbeiten: auf YugabyteDB die Verletzung abgebrochen die ganze Transaktion (25P02) und Frühjahr markiert es Rollback-only, so dass ein verlorenes Rennen fallen würde fallen die gesamte Leuchtfeuer - die Veranstaltungsreihe, die Besucherreihe und jede Zähler dazu. Rechte: 154/155 behalten ihre konstanten Namen und werden nur auf "View" und "Verwalten Tracking Codes", weil Rechte mit Namen reisen in der Sitzung Token und ein Umbenennen würden sie von jeder Live-Sitzung ohne Compiler-Fehler abziehen. Ids 200 und 201 sind neu und Gate Cross-Mitglieder Sicht. Keiner wird eingesät in NEW_RIGHT_SEEDS: Vor dieser Funktion konnte niemand den Besucher eines anderen Mitglieds sehen Analysen überhaupt, so dass die Aussaat von VIEW_REFERRAL_CODES jeden vorhandenen geben würde Halter eine Fähigkeit, die sie nie hatten.
· KlusterServices
Bereitstellung MARKETING_EVENTS für Besucher-Konvertierungssignale
Marketing-Tracking-Codes Gutschrift ein Partner für die Anmeldungen, Organisationen und bezahlte Konten ihre Link produziert, und diese drei Momente passieren in Dienstleistungen die keine Tracking-Tabellen besitzen: SecurityService veröffentlicht marketing.visitor.signup und marketing.visitor.org-created, BillingService veröffentlicht marketing.visitor.paid, und MediaService verbraucht alle drei. Nichts schafft diese Stream-Anwendung-Seite - die Produzenten nur veröffentlichen - so es muss hier existieren, bevor sie eingesetzt werden, oder die ersten Konvertierungen veröffentlicht werden ins Nichts und die Zähler bleiben still bei Null. R1 wie jeder andere Strom auf diesem Single-Node-Server.
· kamo-internal
Verkürzung des Leer-Beschreibungshinweises
Die Beschreibung Spalte zeigt {keine Beschreibung] anstelle von "Keine Beschreibung vorausgesetzt".. Der String war hartcodiert Englisch, so kommt es jetzt von der Wörterbuch mit den in der Komponente aufgebrachten Zahnspangen, seit einer Meldung Mit ihnen würden als Intensivstations-Peetholder geparst.
· kamo-internal
Die Registerkarten des Dokuments neu ordnen und umbenennen
Der Streifen lautet nun Originals | Modify (n) | Modified | Binder | Common | Uploads, und Common tauscht das Zahnrad-Symbol für eine Bibliothek ein, jetzt, dass es keine länger sagt "System". Jeder Tab pinnt einen expliziten "Wert", so dass die visuelle Reihenfolge ist frei zu ändern, ohne die Renummerierung der activeTab überprüft, dass der Rest der Die Datei ist darauf aufgebaut. Shared With Me, History, Hidden Docs und Trash fallen ihre Etiketten für tooltips - Die Geschichte vertreibt sich aus dem Hauptstreifen, um sich ihnen anzuschließen, die auch behebt seinen fetch-Effekt: es wurde auf Tab 5 (Uploads) eingegliedert, während das Panel Renders auf 6, so dass die Historienlisten nie geladen.
· kamo-internal
Die Wissensbasis als Konsole neu aufbauen
Die vier Wissens-Basis-Bildschirme waren die letzten in der App noch tragen die alte schauen, und drei von ihnen erklärten Dinge, die nicht wahr waren. /kb zeigte "Pinned Articles" von einem Endpunkt, der Pin-Reihen mit dem gesendet Artikel abgestreift von @JsonIgnore - der Abschnitt ist noch nie erschienen für Jedermann. Darunter war "Recent Articles" die ersten zehn Knoten des Artikels. Baum, in Baumfolge, jeder gestempelt PUBLISHED mit einem leeren Datum: weder neu noch notwendigerweise veröffentlicht. Der Baum neben ihnen stürzte sich auf jeden Navigation, weil jeder Zweig seinen eigenen Gebrauch hielt. Eine Idee trägt den Wiederaufbau: THE RAIL IS THE FILTER. Eine Kachelzahl und die Liste es öffnet beide kommen von matchesFilter im Modell, so eine Kachel Lesung 4 öffnet genau diese 4. Es gibt keine zweite Reihe von Chips, die das gleiche wiederherstellen Prädikate in verschiedenen Worten, warten darauf, zu widersprechen. Rund um ihn herum: Suchen, dass Streicht passt Titel, Adresse und Körper und markiert, welche es getroffen (die alte Box debounced 500ms zu einem Server, der Inhalt gesucht Nur fragenPlainText Der genaue Titel eines Artikels ergab nichts), ein Baum, der sich erinnert, was Sie geöffnet und kann verkleinert werden, Gesichter auf jeder Karte aus dem Mitgliedsverzeichnis, und ein Needs Aufmerksamkeitstafel - Bewertungen, die gewartet haben, Entwürfe ruhig geworden, veröffentlichte Artikel, die niemand in einem Viertel berührt hat. /kb/resources war ein modaler Dialog, der flach auf eine Route gerendert wurde, mit open={true? und ein onClose, das weg navigierte. Es ist jetzt eine Bibliothek: eine Schiene, die wiegt was die Organisation speichert und verdoppelt sich als Typfilter, Fliesen mit echte Gesichter für Video und Dateien statt eines Rasters aus identischen grauen Boxen, drop-anywhere Upload mit realem pro-Datei-Fortschritt (etch kann nicht berichten Fortschritt, so ein 40MB Video sah genau wie ein 4KB-Symbol), und Umbenennung in Ort statt eines Modal von einer Fußzeile gestartet. Die Einlage-Medien des Editors Picker ist jetzt die gleichen Fliesen, die gleiche Detailscheibe und die gleiche VerwendungKbMedia Haken in einem Dialog - ein Kit, zwei Flächen, so dass sie nicht driften können. /kb/reviews war eine Liste von Titeln. Ein Rezensent konnte sehen, dass vier Dinge waren warten und nichts anderes - nicht wer sie geschrieben, nicht, wie lange sie gesessen hatten dort, nicht, was sie sagten - und zu entscheiden bedeutete, jeden Artikel zu öffnen, scrollen zu einer Tafel an der Unterseite, und wieder kommen. Das Schlimmste von allen ein gescheitertes Holen als "Keine Artikel in Erwartung der Überprüfung": die Warteschlange meldete sich klar auf einem Tag kann es nicht gewesen sein. Jetzt trägt die Warteschlange jedes Artikels Alter, Einreicher und Größe; der Artikel sitzt daneben; und die Urteils-Buttons sind neben dem, was Sie gelten für. /kb/new war ein Formular, das einem Autor nichts erzählte. Die Schnecke Feld sagte "Auto-generiert aus dem Titel" und dann können Sie speichern eine Schnecke der Server lehnt mit einem 400, nachdem der Artikel geschrieben ist. Die Eltern Dropdown eingerückte Optionen mit zwei Leerzeichen, die HTML zusammenbricht, so dass jede Option top-level aussah. Und alle drei Sichtbarkeitsboxen könnten mit KI-Training abgehakt werden, die still bedeutet, niemand sieht es irgendwo. Der Komponist beantwortet diese drei Fragen vor der Arbeit und nicht nach der Ablehnung, und bietet Speichern Entwurf neben Erstellen und einreichen. Behoben entlang des Weges, alle von ihnen sichtbar: - KbStatusBadge ausgeliefert vier hartkodierte englische Wörter und vier hartkodierte Hex Paare - eine spanische Konsole sagte "Draft" in einem grauen keine White-Label-Palette könnte sich bewegen. - KbPinButton gefangen ist einmalPinned, so eine Seite, die ihren Stift Zustand lernt nach dem ersten Render (jede Seite hier) zeigte einen Umrissstift über einem gepinnte Artikel für immer; eine fehlgeschlagene Anfrage ließ den Pin gesetzt. - Der Artikel Leser lesen article.pinned, ein Feld KbArticle nicht haben. - mediaId wurde Nummer über die vier Editorknoten-Typen erklärt und extrahierenMediaIdsFromJson, während KB_MEDIA.UID ist eine UUID und die Werte immer Schnüre. Es überlebte nur, weil nichts jemals rechnen auf eins; eine einzelne Nummer(mediaId) wäre ein stilles NaN gewesen. - KbMediaResource.uid hatte die gleiche Lüge. - Medienanfragen gerannt: eine langsame frühe Suchreaktion könnte nach einem schnellen später ein und neumalieren das Gitter für eine Abfrage niemand sah. Die reinen Regeln leben in app/lib/kbConsole.ts und app/lib/kbMedia.ts mit 52 Tests, denn vitest hier sammelt nur .test.ts nur eine Regel in einem .tsx ist eine Regel ohne Test. Was sie durchgehend kodieren: ein Unbekannter ist nie eine Null. Ein fehlendes Datum hält sich eher als die Epoche, ein unerkannter Status malt neutral statt grün, eine leere Warteschlange hat keine ältestes Element statt einer Null-Tage ein, und eine Ressource, deren Nutzung zählen nie ankam warnt, anstatt zu versprechen, es ist ungenutzt.
· SecurityService
Enforce is_fake, und schließen Sie die Löcher, die eine unbeaufsichtigte Anmeldung in lassen
Zwei Hälften von einem Vorfall. Ein Konto registriert, überprüft eine Adresse an einem Einweg Anbieter, nahm eine Auto-Login-Sitzung und erstellt fünf Organisationen in drei Minuten und 42 Sekunden - vier von ihnen schiffsidentisch "Acme Corp"-Reihen, die sich nur in ihrem Domain. Es produzierte ZERO-Zeilen in system_access_logs, so dass es keine IP und keinen User-Agent gibt auf Rekord für jede davon. Die Flagge durchsetzen ************ - UserAuthenticationService: "u.is_fake = FALSE" geht in ACCOUNT_QUERY_PREFIX, nicht in ein Anrufer. Alle drei Login-Kennzeichen - Benutzername, Konto-E-Mail und das Primär-Mail-Postfach re-lookup keyed by id - Wiederverwendung dieser einen Projektion, so dass eine Klausel alle drei schließt und Die vierte Kennung, die später hinzugefügt wurde, erbt sie. Ein beflaggter Account liest sich als nicht existent und bekommt das generische "Benutzer existiert nicht oder Passwort ist falsch"; eine Nachricht, die die Flagge würde einem Täter genau sagen, was zu ändern. - KSessionService.createSession: lehnt sich direkt ab. Dies ist die schmalste Taille in der System für "kann dieses Konto handeln" - jeder *** wird hier geprägt, so dass ein Tor abdeckt Passwort-Anmelden, Enter-as, Desktop SSO, Gerät auth UND der Registertrichter Post-Verifikation Auto-Login, das ist, wie das Konto in Frage bekam eine Sitzung ohne jemals /login anzurufen. Werfen statt zurück null, weil dreißig Anrufer Übernahme einer Non-Null-ID und würde NPE ganz woanders; Login und die Auto-Session Pfad fangen Sie es und formen Sie eine saubere Antwort. - FakeAccountGuard: zwei Stufen absichtlich. Der Single-Account-Check ist UNCACHED (es geht zurück die harten Tore, wo eine abgestandene Antwort bedeutet, dass ein markiertes Konto noch hereinkommt); die ID-Sets sind für 60er Jahre zwischengespeichert (sie lesen Sie Filterung zurück, wo der schlimmste Fall ist eine synthetische Org Verweilen in einer Liste für weniger als eine Minute). Fails offen - eine Handvoll Reihen zu verstecken ist nicht im Wert von 500ing eine Org-Liste - und nicht Cache einen Ausfall, so dass ein Blip nicht werden eine Minute der Flagge still nicht funktioniert. - OrgObjectStorageSweep: stoppt Snapshotting synthetische orgs. Hier war das Geld: Schnappschüsse werden für immer pro Org pro Tag geschrieben, und fünf verlassene Orgs hatten bereits werden 9% dieser Tabelle. Ein Konto, das sich nicht einloggen kann, tut nichts über die Arbeit der Plattform weiterhin in ihrem Namen zu tun. - FakeAccountController: Flag, unflag, list - hinter MANAGE_ORGANIZATIONS statt einer neue Plattform rechts, denn kamo-internals platformRightCoverage-Test behauptet das Recht gegen die gerenderten Oberflächen der Konsole gesetzt. Entrufen Live-Sitzungen auf Beflaggung, da die Gates sind auf MINTING eine Sitzung, nicht auf die Verwendung eines; weigert sich, den Systembenutzer zu markieren, die würde die Plattform nicht in der Lage, ein Kind org geben. Die Löcher **************** - / registrieren Sie nie lesen "***Token". Das Register UI hat immer ein Capcha gelöst Herausforderung und veröffentlicht das Ergebnis; grep für das Feld über alle Java zurückgegeben nichts. Das Widget war im Browser und der Endpunkt war weit offen. Jetzt verifiziert, und FAIL GESCHLOSSEN - asymmetrisch mit Login absichtlich: Login kann nur eine Nutzlast überprüfen, wenn man vorhanden, weil der mobile Client sendet keine und hart ernorgt es würde sperren echte Benutzer aus. Die Registrierung hat genau einen Client und der ist bereits der Token. - CapchaVerificationService hat TRUE zurückgegeben, wenn "capcha.service-url" nicht gesetzt wurde, also eine config Ausgelassenheit war von einer gelösten Herausforderung nicht zu unterscheiden. Jetzt lehnt ab, hinter "capcha.allow-unconfigured" (Standard falsch) für lokale Läufe. Keine Produktionsänderung Die Immobilie ist in kamowssecurity-config gesetzt, aber die latente Umgehung ist weg. - POST /org hatte keine Tarifbegrenzung. Jetzt gedeckelt pro ACCOUNT (nicht pro IP - ein IP-Schlüssel würde jeden hinter einem korporativen NAT bestrafen). Bewusst großzügig: ein echter Kunde erstellt drei Orgs in fünfeinhalb Minuten, zwei mit dem gleichen Namen und Alias, während den Assistenten ausarbeiten. Eine enge Begrenzung hätte sie blockiert. Zählt Versuche, nicht Erfolge, und scheitert offen an einem Redis Ausfall. - Der Org-Alias hatte KEINE Einzigartigkeit auf diesem Pfad - nur die Domain tat es, weshalb vier lebende Orgs teilen "acme-corp" und warum der Schöpfer variierte nur die Domain jedes Mal: es war das eine Feld, das der Server ablehnen würde. Jetzt ein 409, zum Sicherheitsanbieter weil "(security_provider_id, alias) " ist das Paar Login löst einen Web-alias Host auf. - REGISTRATION / REGISTRATION_REJECTED / EMAIL_VERIFIED / ORG_CREATED sind jetzt mit IP und User-Agent. Jede Erkennung Regel Schlüssel von Login-Ereignissen, so dass das ganze Register Trichter saß außerhalb des Sichtfeldes der Erkennungsmaschine. Bewusst NICHT getan, überprüft: Login ist nicht ***-streng (bricht das Handy App, braucht eine koordinierte Freigabe); Einweg-E-Mail-Domains werden nicht blockiert (eine echte Kunde meldet sich bei proton.me an, und eine naive "kein Mainstream-Anbieter"-Regel blockiert real Personen); kein Content-Scoring-Autoblock (das am stärksten aussehende Verhaltenszeichen duplizierten org-Namen erstellt Minuten auseinander - passt ein echter Kunde genau). Schema-Voraussetzung bereits erfüllt: KamoInitializer angewendet user.is_fake vor der Shared-lib Push, verifiziert als "boolean NOT NULL DEFAULT false" mit seinem Teilindex, und re-lief idempotently, ohne die Flagge zu löschen.
· KBService
Servieren, was die Wissenskonsole liest, und beheben, was es nie könnte
Vier Endpunkte der wieder aufgebauten Wissensbasis benötigt, und drei Fakten der API war unfähig zu erklären. GET /api/kb/pins zurückgegeben eine Seite von Pin ROWS, und KbArticlePin.article ist @JsonIgnore - so die Antwort trug eine Pin-ID, ein Mitglied id und ein Datum, und nichts darüber, welcher Artikel gepinnt worden war. Die Homepage hat darum gebeten Liste, da es ausgeliefert und gemacht nichts, weil eine Seite Umschlag hat keine .Länge und die Wache vor dem Abschnitt war eine Länge Überprüfung. Pinning hat nie arbeitete Ende zu Ende. Es gibt jetzt die Artikel selbst zurück, gelöst innerhalb einer Transaktion, anstatt sich auf Open-in-View zu lehnen. GET /api/kb/articles/overview ist neu: Status zählt, jeder Artikel ist real Daten, Autorschaft, Wortzahl und Auszug, plus die angehefteten Guride des Anrufers, in man liest. Die Homepage verwendet, um "jüngste" zu fälschen, indem Sie die ersten zehn Knoten von der Baum und Stempel sie mit einem leeren Datum. GET /api/kb/reviews/queue ist neu: was wartet und was vor kurzem war abgewickelt, beide Hälften in einer Anfrage. Ein Rezensent, der auf eine leere Warteschlange schaut, fragt die gleiche Frage so oder so - ist nichts Warten, oder habe ich nur klar. Seine entschiedene Lektüre ist eine LIST mit einer Grenze, nicht eine Seite: innerhalb der lesbaren Transaktion einer Seite verworfen COUNT ist nie Aussage #1, so Yugabyte kann nicht Starten Sie es neu und ein gleichzeitiges Schreiben verwandelt die Warteschlange in eine 40001. GET /api/kb/media sendet jetzt die Artikelauszählung jeder Zeile und für die Typen ein Raster zeichnet, seine vorsignierte URL. Die Zählung wurde immer nur von der Single-Ressource Endpunkt, so dass die Bibliothek "in N-Artikel" Warnung vor ein Lösch könnte nie feuern - ein Diagramm eingebettet in neun Artikel als gelöscht ruhig wie ein Waisenkind. Die URLs waren eine Anfrage pro Miniaturbild nach der Liste war schon gelandet. POST /api/kb/media/urls Zeichen eine Charge für Anrufer, die halten Sie schon Reihen. Jede int64 Mitglieds-ID geht als STRING. Sie sind 19-stellige unique_rowid() Werte und eine JSON-Nummer ist ein IEEE-Double im Browser - die Einsender-ID auf der Überprüfung Warteschlange kam vor gerundet, weshalb es nie sein konnte abgestimmt gegen das Mitglied Verzeichnis und eine rohe ID saß, wo ein Name hingehört. Keine Shared-Bibliotheksänderung, also kein KamoInitializer-Lauf und keine Flotten-Umschichtung.
· InitializerService
Hinzufügen von users.is_fake, in der einzigen Anweisungsbestellung, die eine bevölkerte Tabelle erlaubt
Spiegelt das neue Feld "User.isFake". Vier Aussagen, und die Reihenfolge ist die ganze Migration: YugabyteDB lehnt "ADD COLUMN ... NICHT NULL" auf einer bestückten Tabelle ab die gesamte Erklärung, nicht nur die beleidigende Klausel - so kommt die Spalte annulliert, ist Verfüllt, gewinnt seine DEFAULT, und nur dann wird angezogen. Diese in eins eins zusammenzuklappen ALTER produziert eine Migration, die eine Warnung protokolliert und die Spalte abwesend lässt Erfolgsforme Leistung für eine totale No-Op. "@Bestellung (0) " pro Spalten-Add-Konvention. Der Moment, in dem die Shared-lib-Entitätseinheit Karten Jeder spätere Läufer, der einen "User" durch JPA lädt, sendet ihn in seinem SELECT aus, also eine späte geordnete Migration würde nie erreicht werden - ein früherer Läufer stirbt auf "column u1_0.is_fake existiert nicht" und nimmt den Run zuerst herunter. Der Index ist partiell (WHERE is_fake = TRUE). Die heiße Abfrage des Wächters ist "welche IDs sind markiert", und auf einem Tisch, wo effektiv jede Zeile ist FALSE ein voller Index auf der Spalte ist totgewicht, während ein Teil eine Handvoll Einträge hält. Die Backfills "WHERE is_fake IS NULL" ist tragend, nicht Dekoration: KamoInitializer Wiederholungen in voller Höhe jedes Mal, und ein bloßer "UPDATE Benutzer SET is_fake = FALSE" würde leise un-flag jedes Konto, das ein Operator absichtlich versteckt hatte, auf jeder Ausgabe. Ein Test behauptet Diese Klausel ist immer noch da. Übertragen auf die Produktion 2026-08-19; alle fünf angemeldeten Aussagen, BUILD SUCCESS. Spalte verifiziert als "boolean NOT NULL DEFAULT false" mit dem Teilindex vorhanden.
· kamo-shared-library
Hinzufügen von is_fake, das Flag, das ein Konto unsichtbar macht, anstatt gelöscht zu werden
Ein synthetisches Konto - ein Testartefakt, eine gesäte Hung oder eine Anmeldung, die als automatisiert - trägt jetzt "users.is_fake", und die Plattform stoppt die Anerkennung. Das Löschen eines solchen Kontos ist keine wirkliche Option: eine Benutzerreihe ist die Wurzel von sieben Satellitentabellen, jedes Mitglied, das es besitzt und jede Organisation, die es geschaffen hat, die in Drehen Sie eigene Domains, Funktionen, E-Mail-Vorlagen, Rollen und Speicher-Schnappschüsse. Deleting bedeutet, durch all das zu kaskadieren oder Waisen zu verlassen, und es zerstört die Beweise von was auch immer das Konto tat. Ein Boolean ist reversibel und kostet eine Spalte. Die Flagge lebt vom NHER, nicht vom Mitglied oder der Organisation, weil Eigentum ist die einzige Kante, die zuverlässig die abgeleiteten Daten erreicht: "orgs.user_id_owner" und "members.user_id" beide weisen hier zurück, so dass eine Flagge antwortet "ist der Urheber dieser Reihe synthetisch" für alle drei Stacheln. Die Org-Flagage statt würde das Konto in der Lage verlassen sich anzumelden und mehr zu schaffen. Was die Flagge erreicht, und warum jede ist hier und nicht im Anrufer: - "UserRepository.findSession" und die authe Projektion: das markierte Konto löst zu null Zeilen, so liest es sich als nicht existent und nicht als blockiert. - "MemberRepository" / "TeamMemberRepo": von org Mitgliedslisten und von beide Verzeichnis-Suchen, neben dem Systembenutzer, der dort bereits gefiltert wurde. - ************ die Aufzählung Choke Punkt neun nennen Websites teilen. "getOrganizationById" wird absichtlich NICHT gefiltert - es schreibt und es ist, wie die Admin-Oberfläche erreicht eine markierte Org, um es zu entflaggen. - **************** ein beflaggte org hört auf, sich vom Wirt zu lösen, so dass es kann nicht immer wieder echte Anmeldungen unter einer eigenen Register-Subdomain akzeptieren. - ************ gefiltert in der Abfrage statt in der Watcher, weil der Sweep jede Minute eine feste Charge braucht und eine Domain, die niemand besitzt würde sonst halten eine dieser Slots für immer, Sondierung jemand anderes DNS. Jeder von ihnen verwendet einen expliziten Alias-Leitung-LINKS. Ein nackter Weg von "o.owner.isFake" in eine WHERE-Klausel lässt Hibernate einen zweiten, impliziten INNER-Beitreten hinzufügen, der stillschweigend wäre lassen Sie jede Zeile, deren Besitzer ist null "und für "findByDomain", das ist Login-Auflösung. Die Sucher oben sind additiv; die Identitätsfinder auf UserRepository sind übrig ungefiltert absichtlich. Die meisten von ihnen sind tragend für Einzigartigkeit Pre-Checks sowie wie für Nachschaustellungen, und "USERS.EMAIL"/"ALIAS" sind einzigartig pro Sicherheits-Anbieter - so ein Registrierung Duplikat-Check, der nicht sehen konnte, eine beflaggte Zeile würde an seiner eigenen vorbeisegeln Wache und sterben auf einer Einschränkung Verletzung statt. Auch REGISTRATION, REGISTRATION_REJECTED, EMAIL_VERIFIED und ORG_CREATED zu AccessLogEventType. "system_access_logs" hat immer nur Login, fehlgeschlagene Anmeldung und Logout gehalten, so ein Konto, das registriert, verifiziert, nahm eine Auto-Login-Sitzung und erstellt fünf Organisationen produzierten Null-Zeilen - kein Ereignis, keine IP, kein User-Agent - und jede Erkennung Regelschlüssel von Login-Ereignissen, so dass der gesamte Registertrichter unbeobachtet bleibt. In Produktion ist bereits "users.is_fake" vorhanden: KamoInitializer's UserIsFakeMigration lief vor diesem Push, so dass kein Dienst gegen ein ungewandertes Schema aufbauen kann.
· kamo-internal
Rebuild /hr/Betreuung als Lohn- und Gehalts-Konsole
Acht flache Tabs auf acht Tafeln, die jeweils ihre eigene Überschrift, Tabelle, skelett, Fehlerlinie und Snackbar - und hatte sich abgedriftet. Die Überholung ist drei Dinge auf der Seitenebene und ein Umbau jedes Panels obendrauf. **Eine Zusammenfassung:** steht auf einer neuen Kommandozeile und jedem Schienenabzeichen. Es beantwortet die Frage, die der Bildschirm nicht konnte: ob etwas zwischen hier und Gehaltsabrechnung. Früher nahm man drei Klicks - ein Admin öffnete die Dienstplan ohne Möglichkeit zu wissen, dass zwölf Blocking Ausnahmen würden verweigern jede Genehmigung, die sie im Begriff waren, auf der nächsten Registerkarte zu machen. Blockieren und Warten Chips Deep-Link zu dem Panel, das sie besitzt. Umfragen sind angepflegt Seite Sicht, so dass ein Tab links geöffnet über Nacht Haltestellen fragen. **Ein Toast-Host**, über den Panel-Schalter gehievt. Eine Botschaft, die von einem Aktion, die navigiert - "klar die Sperrung Ausnahme zuerst", die sendet der Leser zu einem anderen Sub-Tab verwendet, um mit seiner eigenen Tafel vor Jeder liest es. **Eine Tonkarte** (BemerkungConsole.ts, einheitgetestet) ersetzt drei bereits widersprach, und trägt die Regel dieses Modul schaltet sich: ein Unbekannter ist nie eine Null. Eine zurückgehaltene Genehmigungszahl, eine fehlende Nettominuten-Zahl und ein Zeitraum niemand hat alle erzeugt erreichen das Auge als "wir wurden nicht gesagt", weil Darstellung einer von ihnen als 0 sagt einem HR-Admin eine Warteschlange, die sie nicht sehen können, ist klar. "railBadgeFor" daher nie emittiert eine Null-Plakette, und "consoleVerdict". ist "unbekannt" vor dem ersten Lesen statt "klar". Zwei Lücken geschlossen, die nicht kosmetisch waren: - **Eine Person ist eine Person.** Fünf Tafeln drucken einen rohen 19-stelligen "unique_rowid() " in den Reihen, die entscheiden, ob jemand bezahlt wird. "PersonCell" zeigt das Gesicht und den Namen, mit der ID auf dem Tooltip; ids bleiben STRINGS Ende zu Ende und nichts parsiert ein. "useMemberDisplayNames" jetzt das Ganze Verzeichnis-Reihe anstatt des Namens allein, so dass der gleiche Spaziergang avatare füttert und Berufsbezeichnungen, anstatt eine zweite zu benötigen. - **Ein Bohrer, der nie existierte.** Das Mitglied Timecard unter /settings ist selbst-only durch Konstruktion - seine Endpunkte nehmen keine Mitglieds-ID - so die nur Route von "diese Person sind falsch" zu "hier ist der Punch" war die Ausnahme-Warteschlange, die den Tag auflistet und nicht die Schicht um ihn herum. "MemberTimecardDrawer" öffnet den bestehenden Zeitraum Editor auf einem anderen Mitglied; diese Endpunkte nehmen ein "subjektsmitgliedId" und SecurityService Attribute der Anpassung an den HR-Akteur, das ist es, was die Wiederverwendung richtig macht. Pro Panel: der Dienstplan erhält Suche, Sortierung, eine Karte und eine Tabelle, ein Aktuelle Periodenbereich und CSV (jeder Wert des Servers eigenen Strings - eine Datei Gehaltsabrechnung versöhnt gegen darf nicht eine Zahl dieser App erfunden tragen). Zulassungen wird Tastatur Triage mit klaren Karten von blockiert getrennt eins und eine "genehmigen alles bereit", die noch geht die Staatsmaschine eine Karte nach der anderen und benennt jede Ablehnung. Ausnahmen gewinnen einen Typ Histogramm, das als Filter und, noch wichtiger, ein **Fix it** verdoppelt Aktion: der Bildschirm ausgeliefert bietet nur Re-detect und Waive, keiner von die einen fehlenden Punch zurück setzt, so dass der Weg des geringsten Widerstands von "einen Tag is missing its clock-out" war, um darauf zu verzichten - genau die Entscheidung der Warteschlange existiert, um jemanden zum Nachdenken zu bringen. Gehaltszeiten gewinnt eine Zeitleiste, weil Lücken oder Überlappungen in einem Kalender sind auf einem Track sichtbar und in einer Liste unsichtbar. Export berechnet die Abweichung gegenüber der Vorperiode, anstatt die Operator zum Erinnern zu vergleichen. Schließen wird ein nummerierter Schrittler, da die Ordnung ist real: Recomputing nach Genehmigung Änderungen Zahlen bereits vereinbart. Ein "ReasonDialog" ersetzt sechs handgerollte, die gedriftet waren. Nach der Überprüfung getrimmt, so drei Räume aktiviert die Taste und reichte eine leerer Grund, den der Server als Geschenk gemacht hat. Unter Anderson v. Mt. Clemens Pottery, dass Grund ist der Rekord, so dass die Überprüfung auf dem getrimmten Wert jetzt. "TIMECARD_SUB_TAB_IDS" bleibt unberührt: Es bleibt der URL-Vertrag anhängen und "ATTENDANCE_RAIL" ordnet nur die Pillen nach, so dass jedes Lesezeichen noch landet. Ein Test behauptet, dass die Schiene jede ID genau einmal abdeckt.
· kamo-internal
Die Netzwerkseite als Operationskonsole neu erstellen
Die Seite war der letzte Bildschirm noch mit dem alten Look - eine flache Steigung bar, weiße Karten, ein zentrierter Spinner, Alarm() für jeden Ausfall - während der Der Rest der Konsole war in die Instrumenten-Panel-Sprache umgezogen. Es auch Daten weggeworfen, die das Backend bereits gesendet wurde: jede Organisation eigenen Markenfarbe, ihre vollständige Domain-Liste, ihre Geräterichtlinien. Eine Idee trägt den Umbau: Die Zahlen sind die Filter. Die alte Seite hatte eine Reihe von Zählungen und, separat, eine Reihe von Filter-Chips, die die gleiche Prädikate in verschiedenen Wörtern - zwei Kontrollen, um im Einklang zu halten und zwei Chancen sich nicht einig darüber, was "Besessen" bedeutet. Eine Statistik-Fliese ist jetzt ihr eigenes Prädikat, und sowohl die Anzahl als auch die Auswahl kommen von matchesFilter im Modell. Was die Seite gewonnen hat: Suche in allen sechs Feldern mit dem Spiel markiert (eine sekundäre Domäne verwendet, um nichts zurück, auch während die Karte angezeigt "+2 more" darunter), / um es zu fokussieren, vier Sortierungen, Raster und dichte Listenansichten, Pinning und eine Detail-Schrörbe, die als ?org=<id" adressiert ist, was das ist, was lassen die Karten werden leiser, da die Reihe nicht mehr versucht, kurze Titel zu zeigen, alias, Jahr, Konfiguration, Domain und Anzeigename auf einmal in 0.7rem Grau. Ansicht, sortieren, Pins und Neulinge bestehen in den ui-Präferenzen des Mitglieds, also die Die Anordnung folgt ihnen zwischen Maschinen. Abmelden ist mit der Endpunkt, der jetzt existiert, hinter einer getippten Bestätigung: jede andere Steuerung hier ist reversibel von der Person, die es verwendet, und das ist es nicht. Die 1341-Zeilen-Datei ist jetzt nur noch Anordnung. Was eine Organisation ist, und jede Frage, die der Bildschirm über eine stellt, lebt in networkModel.ts unter Unit Test; was der Server gefragt wird, lebt in Hooks/. Die drei Ansichten lesen die gleichen Ableitungen, so können sie nicht in Meinungsverschiedenheiten über die Organisationen sind erreichbar. Bewegung ist real, aber leise: gestaffelter Eintrag, Layout-Reflow auf Filter und sortieren, eine langsame Drift im Mastkopf und das vorhandene Kilometersegelskelett der Konsole statt eines Spinners. Alles von ihm gated auf bevorzugt-reduzed-Bewegung. Drei Fehler beim Schreiben gefunden, jeder hier behoben: Vergleichen eingeben?.orgId to detailOrg?.id ist undefiniert === undefiniert, wenn beide abwesend, und dann liest .mode aus nichts; window.open mit noopener kehrt zurück null, so dass eine vorgeforderte Registerkarte nie navigiert werden könnte (die Opener-Referenz ist stattdessen abgetrennt, was der gleiche Schutz ist); und ein Next-intl-Callback in die Abhängigkeitskette des Fetch-Effekts könnte eine Re-Runder in eine Refetch verwandeln Schleife, so dass die Nachrichtenhilfen durch einen Schiedsrichter gelesen werden.
· SecurityService
Lassen Sie ein Mitglied seine eigene Mitgliedschaft aufgeben
Die Netzwerk-Seite bietet "Abmelden" an, seit es geschrieben wurde. Es eröffnet ein Bestätigungsdialog und sagte dann, die Funktion würde bald implementiert werden, weil es keinen Endpunkt dahinter gab - ein Mitglied in ein Organisation hatte keinen Ausweg, der nicht durch einen Administrator ging. POST /api/security/org/{id'/leave agiert nur in der eigenen Mitgliederzeile des Anrufers, also nimmt es kein eigenes Recht: Niemand kann es anrufen, um jemand anderen zu entfernen. Es deaktiviert anstatt zu löschen. recordState.isActive ist die Soft-Löge flag, so dass die Reihe überlebt für die Prüfung und kann wiederhergestellt werden, und die Beschäftigung Lebenszyklus auf TeamMember.teamMitgliedMitgliedStatus ist eine andere Achse, dass dies absichtlich in Ruhe gelassen. Jede Live-Session, Dienstplan und Benachrichtigungspfad bereits Tore auf ****************, deren Grundbegriff ist, dass gleiche Flagge, so Clearing es endet Chat-Präsenz, Erwächtbarkeit und Zuordnung Förderfähigkeit ohne weitere Arbeit. Sessions bereits offen gegen die Mitgliedschaft wird widerrufen, wie Off-Boarding es tut, so dass der Zugriff endet jetzt anstatt bei der gleitenden TTL. Drei Mitgliedschaften dürfen nicht aufgegeben werden, jede verweigern eine andere Art von Schaden: die Organisation, die den Antrag bedient (lässt es strandet, dass Anfrage eigene Sitzung), die ursprüngliche Organisation des Anrufers (wo der Benutzer Konto ist verankert, ohne wieder einladen Weg zurück), und einer, den der Anrufer besitzt (was es verlassen würde, ohne dass es jemanden geben könnte, der es verwalten könnte).
· kamo-internal
Rebuild /hr/legal-compliance als gesetzliche Registrierung
Die Oberfläche war ein MUI Tab-Streifen über zwei AG Grids. Pakete als sieben gemacht Spalten von Grafen und eine Aktionen Zelle von sechs unbeschrifteten Icon-Buttons, drei von die sich selbst deaktiviert, ohne zu sagen, warum - die einzige Möglichkeit zu lernen, dass Publish benötigt einen Ordner, um einen hinzuzufügen und zu beobachten, die Taste aufwachen. - Ein Compliance-Meter öffnet die Seite: jede Zuordnung in der org als ein Stapel bar über vier Eimer, gebaut aus sieben Total-only zählt, weil DocsService hat keinen aggregierten Endpunkt. Seine Legende Reihen sind die Kontrollen (die Bar selbst ist ariaversteckte Dekoration), und die Wahl einer filtert die Zuweisungen durch ?bucket= - ein Link, den ein Admin senden kann. - Pakete werden zu einem Kartenspiel, das das trägt, was ein Tisch fallen musste: die Version als Medaillon, der echte ************ Rücken, Publikum, Berichterstattung und der veröffentlichte Inhalts-Fingerabdruck als Monogramm. Jeder blockiert Aktion bleibt sichtbar und gibt seinen Grund als Text, nie als Tooltip auf einem Behindertenkontrolle. - Zuweisungen bleiben ein Netz, jetzt mit einer führenden staatlichen Eisenbahn, das Mitglied über ihre Adresse, Unterschrift Fortschritt als Bar, und ein Status SENTENCE in der eigenen State's Farbe statt eines grauen Chips. - Ein Wortschatz Ende zu Ende (veröffentlichen / liefern / neu auflegen / zurücktreten), passend die eigenen Verben des Backends. Interaktion Farbe ist --legal-Marke durchgehend, nach der Hausregel, die Marke besitzt jeder Schwebering und Fokus skizzieren; --legal-seal bleibt für Identität und Zustand, so ein White-label org sieht auf dieser Seite noch seine eigene Farbe. Jede Regel, die die Oberfläche zieht, ist eine reine Funktion in app/lib/legalRegistry.ts mit 36 Tests, darunter ein Beweis, dass die vier Eimer die sieben Aufgaben abdecken Status genau einmal - ohne es ein Status hinzugefügt, um das Backend würde ausfallen der Zähler leise, so dass die Bar in voller Breite und ein Teil der Org ungezählt. buildAssignmentQuery sendet jetzt Status als REPEATED Params, so dass ein ganzer Eimer eins ist Anfrage; ein CSV würde bei DocsService als ein wörtliches Token doppelt codiert ankommen.
· kamo-marketing
Spielen Sie die Kamo13 Rolle
Zeet den Helden auf der Leiter der neuen Rolle, MP4- Fallback und Poster. Die Quelle ist spektidentisch zu dem, den es ersetzt (H.264 720p24, 66s, ca. 30 MB), also nichts über den Spieler oder die Leiter ändert.
· KlusterServices
Tauschen Sie die Heldenrolle zu kamo13
kamo13.mp4 hochgeladen bei MinIO auf public/kamo13.mp4 (30 MB, sha256 174aaec6...,, verifiziert byte-identical auf die lokale Quelle nach der Übertragung . Diese Verbindung hat eine Geschichte des Manglings großer Kopien). Die alten Kamo12 Objekte werden an Ort und Stelle gelassen: Nichts wird von MinIO gelöscht, und sie sind der Rollback-Pfad. Die neue Quelle ist spektidentisch zu der, die es ersetzt. 3.56 Mbps Video + 256k AAC, 66.005s - so braucht die Leiter keine Neutuning. Immer noch nein 1080p rung; die Quelle ist 720p und eine wäre rein gehoben. Die encod Job-Tasten auf der SHA-256 der Quell-Bytes, so zeigt es auf eine neue Objekt ist genug, um es wieder zu kodieren; es wird öffentlich/hls/kamo13/ und veröffentlichen kamo13-poster.jpg/.webp auf der nächsten Station. Auch dokumentiert eine Bestellerlaube Warnung, die der Swap aufgedeckt: der Einsatzschritt rollt die Einsatz vor dem Ausführen der Encode-Job, so dass die neue pod beginnt, während loop.mp4 gehört immer noch zur vorherigen Rolle. Nur der /live/ Kanal ist betroffen, und nur nach Segment-Jitter - die /vod/ Leiter, die die Homepage spielt gebaut und ist unbeeinflusst. Ein Rollout-Neustart nimmt es auf.
· kamo-internal
Rebuild /hr/Training als Trainingskonsole
Die Registerkarte war zwei AG Grids unter einem Tab-Leiste: präzise und stumm. Es jetzt öffnet sich auf die gesamte Ausbildungsverpflichtung der Org und lässt einen Admin einwirken die Lücken. - Ein Mastkopf, dessen Kohorte Schiene die Zuordnungspopulation IST, bestanden, überfällig, im Gange, nicht begonnen, entschuldigt - in Proportionen und gezeichnet auf Last. Jedes Segment Deep-Links in Zuordnungen vorgefiltert, so ist das Diagramm der Weg in die Arbeit und nicht ein Bild von ihm. - Das Versionsbuch: ein solider Tick pro veröffentlichter Version mit dem Live ein lit, weiter in einen gestrichenen Stummel, wenn der Entwurf vorbeidriftete es. Ein Kurs veröffentlicht als Versionen und Lernende werden an die eine angeheftet sie wurden gesendet, das war vorher eine Zeile lesen eine Zeile an Zeit. Getragen von der Galerie und der Tabelle, so dass die beiden Ansichten teilen ein Wortschatz. - Kurse werden zu einer Kartengalerie mit Suche, Statuschips, Sortierung und Abdeckung Kunst; das Gitter bleibt hinter einem Kipp für dichtes Scannen. Beide lesen von shapeCatalog, so dass sie nicht darüber streiten können, was passt. - Zuweisungen erhalten Suche, multi-select mit massenhaft erinnern/extend/excuse/ stornieren, und CSV exportieren. Jede Schütttaste gibt an, wie viele der Auswahl kann es tatsächlich berühren - ein Erinnern 40, dass Mails 31 ist eine Lüge Der Admin handelt dann weiter. - Ein drittes Sub-Tab, Insights: Pass-Rate und Durchschnitts-Score-Ringe, die Jagdschlange, Mitgliederwertungen, aktuelle Aktivitäten. All das kommt von der Schulungsblock von /api/docs/hr/summary, der die HR-Übersicht ruft bereits an; DocsService ist unberührt. - coverImgId ist seit dem Modul auf der DTO und in der save payload mit nichts, was es einstellen könnte und nichts, was es lesen. Die Editor bekommt den Picker, der das Feld real macht. Vier Mängel auf dem Weg behoben: - Publish war auf jeder Katalogreihe deaktiviert und war immer gewesen. veröffentlichenBlockedReason geht course.items, aber list() Kartenreihen durch toDto(Kurs, falsch), das sie nie setzt - so sah der Artikel zu Fuß eine leere Liste und zurückgegeben 'leer' für jeden Kurs, einschließlich derjenigen, die veröffentlichen perfekt aus der Redaktion. KatalogPublishBlockedReason Tore auf die Zählungen, die die Liste sendet; die Pro-Fragen-Verweigerungen bleiben in der Editor, wo die Fragen vorhanden sind. - Die Nachricht der Löschung der Bestätigung war der Leerzustand der Kurse, eingefügt, so heißt es "Bauen Sie einen Kurs von Dias und Multiple-Choice Testen, dann weisen Sie es Ihrem Team zu.' - Zuweisen Status-Chips gemacht status.replaceAll('_', '', ') Datenbank enum, in Englisch, in allen 22 Orten. - Zwei window.prompt() Anrufe gesammelt eine Einhaltungsfrist und einen Verzicht Grund in einer unstyled OS Box. Beides sind jetzt echte Dialoge; der Verzicht Vernunft ist das, was ein Prüfer liest. Regeln leben in app/lib/trainingConsole.ts unter 36 Tests: vitest hier läuft in der Knoten-Umgebung und sammelt nur .test.ts, so eine Regel geschrieben innerhalb eines .tsx ist eine Regel ohne Test. Strings landeten zuerst in kamo-translation-dictionary b5ed84af.
· kamo-marketing
Wire das Angebot Banner, fix tot Erfahren Sie mehr Links und das Sechseck Feld
Fünf Fixes, allesamt Dinge, die präsent aussahen, aber nichts taten. ANGEBANNER - HeroOfferBanner war toter Code; nichts importierte es. Restauriert, aber angetrieben von dem, was die Preis-API tatsächlich zurückgibt, anstatt von der alten f) mit PROMO_CODE plus FALLBACK_PROMOTION. Dieser Fallback ist, warum es starb: seine Enddatum übergeben und die Komponente dann nichts für immer gemacht. Jetzt publizieren eine Förderung im Backend lässt es auf dem nächsten Revalidate erscheinen und lassen Sie es lapse entfernt es, ohne Einsatz in beide Richtungen. Promotions kommen schon zurück neben den Plänen, so dass das Banner kostet keine zusätzliche Anfrage. Die Auswahl filtert zu FLAT_PER_SEAT, der eher ein Korrektheitswächter ist als eine Präferenz: die Kopie des Banners lautet "Save $N/user", also ein PERCENTAGE promo würde "$20/User" für das, was wirklich 20% Rabatt machen. Es erfordert auch eine real endDate - ein Countdown braucht etwas zum Countdown, und die vorherige Version gefälscht ein mit dem Jahr 2099. LEARN MEHR - der Indikator auf jeder Heim-Feature-Karte war ein bloßes <div> auf einem nichts. Es ist jetzt ein echtes Link mit einem gestreckten ::nach so die ganze Karte ist der Trefferbereich, der auf einen neuen Anker pro Kategorie auf / zweckmäßig ist. Die Sechs Kategorieschnecken sind jetzt ein öffentlicher Auftrag und werden als solcher kommentiert. HEXAGON FIELD - "hexagon-grid" erklärt "Position: relativ", während seine nur Nutzung fragt nach "absolute inset-0" über Utilities. Diese Datei lädt nach dem Tailwind Import, so bei gleicher Spezifität das Stylesheet gewonnen: das Element brach auf Null Höhe und schnitt seine eigene ::before durch "overflow:hidden" und "enthalten:malen". Das Feld hatte überhaupt nichts gemacht. VIDEO CUT OFF - der Rahmen der Rolle überhängt den Blickport um 1.5 x 5m, so dass es würde sichtlich aus dem Off laufen. Das liest sich gut für Dekoration und schlecht für ein Produkt Demo, wo der beschnittene Streifen zufrieden ist jemand soll beobachten. Es endet jetzt bündig mit der Kante: immer noch keine rechte Dachrinne, so hält es liest sich als ein Fenster anstelle einer Karte, aber die ganze Rolle ist sichtbar. Außerdem: eine Neustart-Steuerung neben der Soundtaste und Integrations 64 -- 100+. Beide Video-Steuerelemente sind Icon-only jetzt, das ist eine Lösung eher als ein Stil Auswahl. HeldVideoMute/HeroVideoUnmute fehlte in der Übersetzung Wörterbuch, so next-intl gerenderte den rohen Schlüsselpfad - Live-HTML diente **************** und der Held Umbau verwandelte das sichtbarer Text auf der Taste. Die Schlüssel werden dem Kamo-Translation-dictionary hinzugefügt (f4d2b65b); Symbole und ein Arien-Label verhindern, dass eine Kopierlücke zu Möbeln wird. Der Countdown 50ms tick ist 20 macht eine Sekunde für immer auf einer Seite, die auch ist Entschlüsselung Video, so dass jeder, der für reduzierte Bewegung fragt bekommt eine 1s Uhr und verliert die Millisekunden-Einheit.
· kamo-login
Wiederaufbau der Willkommenstafel rund um eine Live-Status-Schiene
Die linke Spalte war eine generische Schlagzeile, eine Sicherheitsplattitüde und ein Haufen von Umgebungsdekoration (Punktgitter, schwimmende Kugeln, ein pulsierendes Strich). Ersetzen Sie es mit eine gemeinsame WelcomePanel-Komponente: ein gewichtskontrastiger Geist Lockup, ein Haaransatz Regel, eine einzige Zeile der Orientierungskopie und eine Monospaced-Schiene, die berichtet was ist eigentlich wahr über die Anmeldung - ob die Verbindung verschlüsselt ist, welcher Host Sie sind auf, und wo Sie in der Strömung sind. Der Recovery-Bildschirm verwendet das gleiche Panel mit einer eigenen Kopie und Schritt Mapping so die beiden Bildschirme bleiben eine Oberfläche.
· kamo-marketing
Bauen Sie den Helden als redaktionelle Spaltung mit der Rolle als Blende
Die Rolle war ein zentriertes abgerundetes Rechteck mit einem Fallschatten - ein Objekt platziert über das Design und nicht Teil davon - und es war das EINZUNGSache im Helden: ff04781 löschte die Plakette, Überschrift, Beschreibung, CTAs und Statistiken, als sie landete das Video, das HeroHeadline.tsx verwaist und zehn Kopietasten unbenutzt ließ. Also der Abschnitt hatte keine These und keinen Aufruf zum Handeln, was ist der größte, warum es lesen als Quadrat in der Mitte des Bildschirms. Jetzt eine Zwei-Senken-Komposition: Augenbraue, Schlagzeile, lede, CTA und die free-forever-Note links; die Haspel rechts, rechts auf der Haspel Rand des Aussichtshafens. Drei Dinge tun die Integration: - Die Ecken des Rahmens sind bei 45° abgeschirmt, die gleiche Geometrie wie das Sechseck Feld bereits dahinter, anstelle des Grenz-Radius jeder SaaS Held verwendet; - eine Stadtbahn auf der linken Seite trägt die Olive der Schlagzeile Reisepass, die die beiden Hälften des Spliters miteinander verknüpfen; - es blutet aus dem Off, anstatt kurz zu stoppen, so gibt es keine vierte Kante um es als Karte lesen zu lassen. Das Überlauf-versteckt des Abschnitts ist es, was es abschneidet. Die Felge ist ein 1px-Gradien, der durch die Paddeldose der Eltern erscheint, weil Clip-Pfad schneidet die Grenzen an der Fachin ab. Beide Boxen wiederholen das Polygon Clip-Pfad erbt nicht, und eine quadratische innere Box stochert seine Ecken durch. Detailarbeit: Die Soundsteuerung bewegte sich nach unten LINKS, da der Rahmen Rechtskante ist absichtlich aus dem Off und eine Kontrolle verankert wäre unerreichbar. Eine Fortschrittsschiene entlang der Unterseite zeigt Position in der Schleife das einzige Stichwort, dass die Rolle endlich ist und nicht ein animierter Hintergrund. Statistiken sind eine Haaransatzregel unter der Zusammensetzung, ohne Count-up: vier Figuren Rennen auf Last konkurrieren mit der Rolle im Moment sollte es sein Beobachtet. "Watch Demo" ist als CTA verschwunden, weil die Rolle neben der Taste ist die Demo; die sekundäre Verbindung verwendet das Etikett "View Pricing" des CTA-Streifens und zielen darauf, dass die Seite die Aktion in eine Richtung benennt. Keine neue Kopie: jeder String existierte bereits in en.json. i18n/request.ts Deep-Fusionen jeder Lokal mit Englisch, so dass die Statistik-Etiketten fehlen von 21 Locales geben in Englisch, bis das Wörterbuch CI aufholt. Toter Code auf dem Weg entfernt: ein Akzent-Glow div Keyed aus einer "Gruppe-Hover" ohne "Gruppe" Vorfahre, ein ungenutzter VideoContainerRef, und Objekt-Container auf einem 16:9 Quelle in einem 16:9 Rahmen.
· kamo-marketing
Spielen Sie die Rolle als adaptive HLS Leiter statt einer 31,8 MB MP4
Der Held wies eine bloße <Video src" auf eine einzelne 3,9 Mbps 720p24 MP4, so ein Telefon auf einer schwachen Verbindung genau den gleichen Stream wie ein Desktop heruntergeladen Ballasten und weiter heruntergeladen, nachdem der Besucher vorbeigescrollt war. Es spielt jetzt die 720p/540p/360p Leiter gebaut von KlusterServices' hero-hls-encode Job: die Spieler nimmt die Sprosse seine Verbindung trägt und holt nur 4s Segmente beim Beobachten. Die 360p-Steigerung ist 5,4 MB gegenüber dem Original 31.8 MB. Playback bewegt sich aus dem JSX und in einen Effekt, weil die Wahl zwischen HLS und die MP4 ist eine Laufzeitentscheidung. Safari und iOS erhalten die Wiedergabeliste nativ (iOS hat keine Medienquellen-Erweiterungen, so ist hls.js keine Option dort); alle anderen bekommen es durch eine dynamisch importiert hls.js, die aus bleibt das Einstiegspaket. Ein fataler hls.js-Fehler, ein nicht unterstützter Browser oder ein fehlgeschlagener Brockenlast alle Landung auf der ursprünglichen MP4, die immer noch die Quelle der Wahrheit ist. Das <video" trägt absichtlich keine .src. deklarieren, dass man die 31.8 MB progressive Download diese Änderung existiert zu entfernen. hls.js wird zu einer direkten Abhängigkeit. Es war nur vorübergehend über @react-three/drei, die überhaupt nicht mehr in package.json ist; npm install Beschnitt der 67 übrig gebliebenen Pakete aus der abgestandenen Lockfile. Nichts in der App/ Importe drei, drei oder Reakt-Welt-Flagge (FlagEmoji.tsx Dokumente ersetzen die letzten von denen absichtlich). Auch das Plakatattribut beginnt zu arbeiten: es hat sich verwiesen public/kamo12-poster.jpg da diese Komponente geschrieben wurde, aber das Objekt nie existiert und der Held leer gemacht, bis der erste Frame decoded. Die encode job veröffentlicht es jetzt.
· KlusterServices
Einsatz eines Streaming-Servers und einer ABR-Leiter für die Heldenrolle
MediaMTX bedient Live-Kanäle über HLS, WebRTC, RTSP und RTMP und schliesst die Marketing-Rolle als immer verfügbarer Kanal über alwaysAvailableFile 08.09.2018peg Sidecar, und jeder RTMP/RTSP-Publisher nimmt den Kanal transparent über und kehrt auf die Rolle auf trennen. Die Homepage-Video selbst wird NICHT über MediaMTX gedient. MediaMTX ist ein Live Server ohne VOD-Modus; Looping einer Datei in einen Live-Kanal würde jeden fallen Besucher in der Mitte der Rolle statt des ersten Frames. Also hero-hls-encode-Job baut eine 720p/540p/360p HLS-Leiter aus dem gleichen MP4 und veröffentlicht es an MinIO, routed as /vod/ auf dem Streaming-Host. Gegen die 31,8 MB Single-Bitrate Original: 18,8 MB bei 720p (SSIM 0.989), 9.8 MB bei 540p, 5,4 MB bei 360p, in 4er Segmenten holt der Spieler nur beim Zuschauen. Der Job ist ETag-idempotent, so dass es No-Ops auf jedem Einsatz, der kein Video ist tauschen, und es veröffentlicht auch public/kamo12-poster.jpg Homepage, da es geschrieben wurde, aber eine 404 bis jetzt. Routen live auf Stream.* und Thema.*: Thema.<domain" hat bereits DNS und ein Zertifikat für jeden Mieter, so funktioniert dies heute, und der Strom.* Formular aktiviert sich von selbst, sobald ein DNS-Rekord existiert. Die WebRTC-Route passt ************ statt einer Vorwahl bewusst - MediaMTX bedient WHIP am gleichen Port, und ein Präfix-Match würde veröffentlichen einen nicht authentifizierten Ingest-Endpunkt ins Internet. Dies berührt .forgejo/, was FULL=true und einen Vollcluster versöhnt. Besichtigt zuerst nach dem dokumentierten Verfahren: kubectl diff über alle 112 Ziele ist sauber auf 104; fünf sind diese neuen Dateien, zwei sind die nats/mail Bootstrap Jobs der Workflow absichtlich gelöscht und erneut angewendet, und mail/mysql-permissions-job.yaml scheitert als unveränderlicher abgeschlossener Job, der Der Workflow verträgt bereits mit "| echo". Jedes kubectl Löschziel war bestätigt abwesend.
· KlusterServices
Workstation-Side Mount-Skript für die KAMOTEAM-Aktie
NFSv4 über den NodePort, weich montiert mit einem systemd automount so unerreichbar Cluster gibt einen Fehler zurück, anstatt jeden Prozess aufzuhängen, der die Ordner, und so der Laptop immer noch in der Regel bootet, wenn aus dem LAN.

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