diff --git a/docs/features/search-attributes.md b/docs/features/search-attributes.md index b31953ed603..40cedb1c56c 100644 --- a/docs/features/search-attributes.md +++ b/docs/features/search-attributes.md @@ -137,6 +137,35 @@ The qualified Server 2.11.0 list API has **no built-in roots-only or children-on Inspect the run's lineage when you need its actual parent/child relationship. Broader shared visibility filtering remains [product work](https://github.com/durable-workflow/.github/issues/224); this limitation and a user-authored metadata convention do not deliver that capability. The [verification receipt](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504) preserves the observed parent-and-child result and rejected predicates. +## Repairing datetime search attributes {#repair-datetime-search-attributes} + +The history-backed repair command requires an actually installed **Workflow 2.12.0 or newer**. Check `composer.lock` and `php artisan help workflow:v2:repair-search-datetimes` in the Laravel application that will run it. A source checkout or Composer constraint alone does not establish the installed command. + +Datetime projections store UTC instants with microsecond precision: `2026-10-08T12:34:56.123456+02:00` is `2026-10-08T10:34:56.123456Z`. Earlier writers could persist the offset’s local wall time while retaining its offset in typed history. Upgrading prevents new writer errors but does not identify or rewrite old rows. Never infer an original timezone from the stored wall time. + +Upgrade every projection writer and back up the workflow database first. Use the exact **run ID**, not a workflow instance ID. Start with a preview: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` is an exact equality guard; use the run’s actual namespace. Omit it only when the exact run ID is sufficient, including legacy null namespaces; an empty explicit namespace is refused. Without `--key`, the selection covers that run’s datetime attributes. Repeat the option for known keys, such as `--key=SubmittedAt --key=ApprovedAt`. + +Preview is the default. Review `examined`, `would_repair` and the exact run/key selection before explicitly applying the same selection: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +Read the selected attributes and run summary back, then preview again. With unchanged evidence and already-correct values, a repeat apply reports zero repairs. A repaired subset does not establish that unselected keys are correct. + +Repair requires the latest retained, explicitly typed `SearchAttributesUpserted` evidence for each key, with its original logical command sequence matching the projection. Pruned history, missing/stale evidence, timezone-ambiguous values, wrong namespace and selected keys no longer retained as datetime attributes refuse the operation. One unprovable key refuses the entire selection; inspect the history and select only proven keys instead of guessing an offset. + +The command locks and validates the complete selection before updating derived attributes and their summary in one storage transaction. Authoritative history, business commands, run/task identities and leases remain unchanged. JSON failures distinguish `refused` from `unverified`: after an unexpected storage error, inspect the rows before retrying because an uncertain commit is not a guaranteed rollback. + +This repairs derived search attributes and their summary; it does not restore pruned history or change authoritative input. The separate Server visibility-query binding path and Server image adoption require their own qualified delivery; a Core package tag does not establish an HTTP fix. See the [canonical recovery procedure](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes). + ## Continue-as-New When a workflow continues as new, the current search attributes are carried forward to the new run automatically. The new run starts with the full merged attribute map from the previous run and can continue upserting from there. diff --git a/i18n/de/docusaurus-plugin-content-docs/current/features/search-attributes.md b/i18n/de/docusaurus-plugin-content-docs/current/features/search-attributes.md index 4eb1bc3af88..b268bb54519 100644 --- a/i18n/de/docusaurus-plugin-content-docs/current/features/search-attributes.md +++ b/i18n/de/docusaurus-plugin-content-docs/current/features/search-attributes.md @@ -156,6 +156,35 @@ Die qualifizierte Listen-API von Server 2.11.0 hat **kein eingebautes Prädikat Prüfen Sie die Abstammung des Laufs, wenn Sie seine tatsächliche Eltern-/Kindbeziehung benötigen. Umfassendere gemeinsame Sichtbarkeitsfilter bleiben [Produktarbeit](https://github.com/durable-workflow/.github/issues/224). Diese Einschränkung und eine vom Nutzer definierte Metadatenkonvention liefern diese Fähigkeit nicht. Der [Prüfbericht](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504) bewahrt das Ergebnis mit Elternlauf und Kind sowie die abgewiesenen Prädikate. +## Datetime-Suchattribute reparieren {#repair-datetime-search-attributes} + +Der historiengestützte Reparaturbefehl benötigt **tatsächlich installiertes Workflow 2.12.0 oder neuer**. Prüfen Sie `composer.lock` und `php artisan help workflow:v2:repair-search-datetimes` in der ausführenden Laravel-Anwendung. Ein Quellcheckout oder eine Composer-Vorgabe allein belegt keinen installierten Befehl. + +Datetime-Projektionen speichern UTC-Zeitpunkte mit Mikrosekunden: `2026-10-08T12:34:56.123456+02:00` entspricht `2026-10-08T10:34:56.123456Z`. Frühere Writer konnten die lokale Uhrzeit des Offsets speichern, obwohl der Offset in typisierter Historie erhalten blieb. Ein Upgrade verhindert neue Writer-Fehler, identifiziert oder korrigiert alte Zeilen aber nicht. Leiten Sie die ursprüngliche Zeitzone niemals aus der gespeicherten Uhrzeit ab. + +Aktualisieren Sie zuerst sämtliche Projektions-Writer und sichern Sie die Workflow-Datenbank. Verwenden Sie die **exakte Run-ID**, keine Workflow-Instanz-ID. Beginnen Sie mit einer Vorschau: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` prüft exakte Gleichheit; verwenden Sie den tatsächlichen Namespace des Runs. Lassen Sie die Option nur weg, wenn die genaue Run-ID genügt, auch bei alten Null-Namespaces; ein ausdrücklich leerer Namespace wird abgelehnt. Ohne `--key` werden die Datetime-Attribute dieses Runs ausgewählt. Wiederholen Sie die Option für bekannte Schlüssel, etwa `--key=SubmittedAt --key=ApprovedAt`. + +Standardmäßig erfolgt eine Vorschau. Prüfen Sie `examined`, `would_repair` und die genaue Run-/Schlüsselauswahl, bevor Sie dieselbe Auswahl ausdrücklich anwenden: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +Lesen Sie ausgewählte Attribute und Run-Zusammenfassung erneut und wiederholen Sie die Vorschau. Bei unveränderten Nachweisen und korrekten Werten meldet ein wiederholtes Apply null Reparaturen. Ein reparierter Teil belegt nicht die Korrektheit ungewählter Schlüssel. + +Jeder Schlüssel benötigt das letzte erhaltene, ausdrücklich typisierte `SearchAttributesUpserted` mit einer ursprünglichen logischen Befehlssequenz, die zur Projektion passt. Bereinigte Historie, fehlende/veraltete Nachweise, uneindeutige Zeitzonen, falscher Namespace und nicht mehr als Datetime erhaltene Schlüssel führen zur Ablehnung. Ein unbelegbarer Schlüssel lehnt die gesamte Auswahl ab; prüfen Sie die Historie und wählen Sie nur belegte Schlüssel, ohne Offsets zu erraten. + +Der Befehl sperrt und validiert die gesamte Auswahl, bevor er abgeleitete Attribute und ihre Zusammenfassung in einer Speichertransaktion aktualisiert. Maßgebliche Historie, Geschäftsbefehle, Run-/Task-Identitäten und Leases bleiben unverändert. JSON-Fehler unterscheiden `refused` und `unverified`: Nach einem unerwarteten Speicherfehler prüfen Sie die Zeilen vor dem Wiederholen, denn ein unsicherer Commit garantiert keinen Rollback. + +Repariert werden abgeleitete Suchattribute und ihre Zusammenfassung; bereinigte Historie wird nicht wiederhergestellt und maßgebliche Eingaben bleiben unverändert. Der separate Sichtbarkeitsabfrage-Bindungspfad des Servers und die Image-Übernahme benötigen eine eigene qualifizierte Lieferung; ein Core-Tag belegt keine HTTP-Korrektur. Siehe das [kanonische Wiederherstellungsverfahren](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes). + ## Continue-as-new {#continue-as-new} Bei Continue-as-new werden die aktuellen Suchattribute automatisch in den diff --git a/i18n/de/source-hashes.json b/i18n/de/source-hashes.json index c384bb21231..47391867d2d 100644 --- a/i18n/de/source-hashes.json +++ b/i18n/de/source-hashes.json @@ -44,7 +44,7 @@ "features/queries.md": "c66dd9542a062edd8158a46cebc9f1bf926aaf3599dca4a3122bd9860df6e2a2", "features/sagas.md": "8dae955491a54bcbf545ce6972928df59f3885e00f98bf3a57b14dad98f89161", "features/schedules.md": "73dd4d49bfb61d5ecafc0fb799136fc170d8cd33781ff00f40893efe4e0de0d6", - "features/search-attributes.md": "74bd53d45dcde40597d7eb2f6bda6cd88c3a773ccf6beed08cd3eeb542d39b0d", + "features/search-attributes.md": "607a37a0ff8ffcb111d07f33de7b9d2797d24567fb4da37014f604a62ce709b5", "features/service-operations.md": "912131c0a8ef393040a933fb4a66e68abcb9d475a3ebd47c85287d4032f45a0e", "features/side-effects.md": "abdccab8d6fc1a12b3eff8a4ccc58730ac36f523559b4ad89c5c2a8d201a3b86", "features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822", diff --git a/i18n/es/docusaurus-plugin-content-docs/current/features/search-attributes.md b/i18n/es/docusaurus-plugin-content-docs/current/features/search-attributes.md index d0818e74154..946e7aa9aab 100644 --- a/i18n/es/docusaurus-plugin-content-docs/current/features/search-attributes.md +++ b/i18n/es/docusaurus-plugin-content-docs/current/features/search-attributes.md @@ -137,6 +137,35 @@ La API de listado del Server 2.11.0 verificada **no tiene un predicado integrado Inspeccione el linaje de la ejecución cuando necesite la relación real padre/hijo. La filtración compartida más amplia sigue siendo [trabajo de producto](https://github.com/durable-workflow/.github/issues/224); esta limitación y una convención de metadatos del usuario no entregan esa capacidad. La [verificación](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504) conserva el resultado con padre e hijo y los predicados rechazados. +## Reparar atributos de búsqueda datetime {#repair-datetime-search-attributes} + +El comando de reparación basado en historial exige **Workflow 2.12.0 o posterior realmente instalado**. Comprueba `composer.lock` y `php artisan help workflow:v2:repair-search-datetimes` en la aplicación Laravel que lo ejecutará. Un checkout de fuentes o una restricción Composer no demuestra que el comando esté instalado. + +Las proyecciones datetime guardan instantes UTC con microsegundos: `2026-10-08T12:34:56.123456+02:00` equivale a `2026-10-08T10:34:56.123456Z`. Los writers anteriores podían guardar la hora local del offset y conservar ese offset en el historial tipado. Actualizar evita nuevos errores del writer, pero no identifica ni reescribe filas antiguas. Nunca deduzcas la zona original de la hora almacenada. + +Actualiza primero todos los writers de proyecciones y respalda la base de datos del workflow. Usa el **ID exacto del run**, no el de la instancia de workflow. Empieza con una vista previa: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` es una comprobación de igualdad exacta; usa el namespace real del run. Omítelo solo si basta el ID exacto, incluidos namespaces null antiguos; un valor explícito vacío se rechaza. Sin `--key`, se seleccionan los atributos datetime de ese run. Repite la opción para claves conocidas, como `--key=SubmittedAt --key=ApprovedAt`. + +La vista previa es el modo predeterminado. Revisa `examined`, `would_repair` y la selección exacta de run/claves antes de aplicar explícitamente esa misma selección: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +Vuelve a leer los atributos seleccionados y el resumen del run; repite después la vista previa. Con evidencia sin cambios y valores correctos, repetir apply informa cero reparaciones. Reparar un subconjunto no demuestra que las claves no seleccionadas sean correctas. + +Cada clave exige el último upsert retenido y explícitamente tipado `SearchAttributesUpserted`, cuya secuencia lógica original del comando coincida con la proyección. Historial podado, evidencia ausente/obsoleta, zona horaria ambigua, namespace incorrecto o claves que ya no se conservan como datetime rechazan la operación. Una clave sin prueba rechaza toda la selección; inspecciona el historial y selecciona solo claves demostrables, sin adivinar un offset. + +El comando bloquea y valida toda la selección antes de actualizar atributos derivados y su resumen en una transacción de almacenamiento. No cambia historial autoritativo, comandos de negocio, identidades de run/tarea ni leases. Los fallos JSON distinguen `refused` y `unverified`: tras un error inesperado de almacenamiento, inspecciona las filas antes de reintentar porque un commit incierto no garantiza rollback. + +Repara atributos derivados y su resumen; no restaura historial podado ni cambia input autoritativo. El binding de consultas de visibilidad del Server y la adopción en su imagen requieren su propia entrega cualificada; un tag Core no demuestra una corrección HTTP. Consulta el [procedimiento canónico](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes). + ## Continuar como nueva ejecución {#continue-as-new} Los atributos actuales pasan automáticamente a la nueva ejecución. Esta comienza con el mapa combinado completo de la anterior y puede seguir actualizándolo. diff --git a/i18n/es/source-hashes.json b/i18n/es/source-hashes.json index c384bb21231..47391867d2d 100644 --- a/i18n/es/source-hashes.json +++ b/i18n/es/source-hashes.json @@ -44,7 +44,7 @@ "features/queries.md": "c66dd9542a062edd8158a46cebc9f1bf926aaf3599dca4a3122bd9860df6e2a2", "features/sagas.md": "8dae955491a54bcbf545ce6972928df59f3885e00f98bf3a57b14dad98f89161", "features/schedules.md": "73dd4d49bfb61d5ecafc0fb799136fc170d8cd33781ff00f40893efe4e0de0d6", - "features/search-attributes.md": "74bd53d45dcde40597d7eb2f6bda6cd88c3a773ccf6beed08cd3eeb542d39b0d", + "features/search-attributes.md": "607a37a0ff8ffcb111d07f33de7b9d2797d24567fb4da37014f604a62ce709b5", "features/service-operations.md": "912131c0a8ef393040a933fb4a66e68abcb9d475a3ebd47c85287d4032f45a0e", "features/side-effects.md": "abdccab8d6fc1a12b3eff8a4ccc58730ac36f523559b4ad89c5c2a8d201a3b86", "features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822", diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/features/search-attributes.md b/i18n/fr/docusaurus-plugin-content-docs/current/features/search-attributes.md index cae16295f62..83f47f50a30 100644 --- a/i18n/fr/docusaurus-plugin-content-docs/current/features/search-attributes.md +++ b/i18n/fr/docusaurus-plugin-content-docs/current/features/search-attributes.md @@ -137,6 +137,35 @@ L’API de liste qualifiée de Server 2.11.0 **n’a pas de prédicat intégré Examinez la filiation de l’exécution pour connaître sa relation parent/enfant réelle. Le filtrage partagé plus large reste un [travail produit](https://github.com/durable-workflow/.github/issues/224) ; cette limitation et une convention de métadonnées définie par l’utilisateur ne livrent pas cette capacité. La [vérification](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504) conserve le résultat contenant parent et enfant ainsi que les prédicats refusés. +## Réparer les attributs de recherche datetime {#repair-datetime-search-attributes} + +La commande de réparation fondée sur l’historique exige **Workflow 2.12.0 ou ultérieur réellement installé**. Vérifiez `composer.lock` et `php artisan help workflow:v2:repair-search-datetimes` dans l’application Laravel qui l’exécutera. Un checkout des sources ou une contrainte Composer ne prouve pas que la commande est installée. + +Les projections datetime stockent des instants UTC avec microsecondes : `2026-10-08T12:34:56.123456+02:00` représente `2026-10-08T10:34:56.123456Z`. Les anciens writers pouvaient enregistrer l’heure locale du décalage tout en conservant celui-ci dans l’historique typé. La mise à niveau évite de nouvelles erreurs du writer, mais n’identifie ni ne réécrit les anciennes lignes. Ne déduisez jamais le fuseau initial de l’heure stockée. + +Mettez d’abord à niveau tous les writers de projections et sauvegardez la base du workflow. Utilisez l’**ID exact du run**, pas celui de l’instance de workflow. Commencez par un aperçu : + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` impose une égalité exacte ; indiquez le vrai namespace du run. Omettez-le seulement lorsque l’ID exact suffit, y compris pour les anciens namespaces null ; une valeur explicite vide est refusée. Sans `--key`, la sélection couvre les attributs datetime du run. Répétez l’option pour les clés connues, comme `--key=SubmittedAt --key=ApprovedAt`. + +L’aperçu est le mode par défaut. Examinez `examined`, `would_repair` et la sélection exacte run/clés avant d’appliquer explicitement cette même sélection : + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +Relisez les attributs sélectionnés et le résumé du run, puis relancez l’aperçu. Si les preuves sont inchangées et les valeurs correctes, répéter apply indique zéro réparation. Un sous-ensemble réparé ne prouve pas que les clés non sélectionnées sont correctes. + +Chaque clé nécessite le dernier upsert conservé et explicitement typé `SearchAttributesUpserted`, dont la séquence logique initiale de commande correspond à la projection. Historique purgé, preuves absentes/périmées, fuseau ambigu, mauvais namespace ou clés qui ne sont plus conservées comme datetime entraînent un refus. Une seule clé non démontrable refuse toute la sélection ; inspectez l’historique et sélectionnez uniquement les clés prouvées, sans deviner de décalage. + +La commande verrouille et valide toute la sélection avant de mettre à jour les attributs dérivés et leur résumé dans une transaction de stockage. Historique faisant autorité, commandes métier, identités run/tâche et leases restent inchangés. Les échecs JSON distinguent `refused` et `unverified` : après une erreur de stockage inattendue, inspectez les lignes avant de réessayer, car un commit incertain ne garantit pas un rollback. + +Cette procédure répare les attributs dérivés et leur résumé ; elle ne restaure pas l’historique purgé et ne modifie pas l’input faisant autorité. Le binding des requêtes de visibilité du Server et l’adoption dans son image exigent leur propre livraison qualifiée ; un tag Core ne prouve pas une correction HTTP. Consultez la [procédure canonique](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes). + ## Continuation dans une nouvelle exécution {#continue-as-new} Lors d’une continuation, les attributs courants sont automatiquement transmis à la nouvelle exécution. Celle-ci démarre avec la table fusionnée complète de la précédente et peut continuer à la modifier. diff --git a/i18n/fr/source-hashes.json b/i18n/fr/source-hashes.json index c384bb21231..47391867d2d 100644 --- a/i18n/fr/source-hashes.json +++ b/i18n/fr/source-hashes.json @@ -44,7 +44,7 @@ "features/queries.md": "c66dd9542a062edd8158a46cebc9f1bf926aaf3599dca4a3122bd9860df6e2a2", "features/sagas.md": "8dae955491a54bcbf545ce6972928df59f3885e00f98bf3a57b14dad98f89161", "features/schedules.md": "73dd4d49bfb61d5ecafc0fb799136fc170d8cd33781ff00f40893efe4e0de0d6", - "features/search-attributes.md": "74bd53d45dcde40597d7eb2f6bda6cd88c3a773ccf6beed08cd3eeb542d39b0d", + "features/search-attributes.md": "607a37a0ff8ffcb111d07f33de7b9d2797d24567fb4da37014f604a62ce709b5", "features/service-operations.md": "912131c0a8ef393040a933fb4a66e68abcb9d475a3ebd47c85287d4032f45a0e", "features/side-effects.md": "abdccab8d6fc1a12b3eff8a4ccc58730ac36f523559b4ad89c5c2a8d201a3b86", "features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822", diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/features/search-attributes.md b/i18n/ja/docusaurus-plugin-content-docs/current/features/search-attributes.md index 2697ced7cd4..64297aeeb7b 100644 --- a/i18n/ja/docusaurus-plugin-content-docs/current/features/search-attributes.md +++ b/i18n/ja/docusaurus-plugin-content-docs/current/features/search-attributes.md @@ -137,6 +137,35 @@ upsertSearchAttributes(['temporary_flag' => null]); 実際の親子関係が必要なときは、実行の系譜を確認してください。より広い共通の可視性フィルターは引き続き[製品側の作業](https://github.com/durable-workflow/.github/issues/224)です。この制限の説明や利用者独自のメタデータ規約が、その機能の提供に代わるものではありません。[検証記録](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504)には、親子の両方が返る結果と拒否された述語を残しています。 +## datetime 検索属性の修復 {#repair-datetime-search-attributes} + +履歴に基づく修復コマンドには、**実際にインストールされた Workflow 2.12.0 以降**が必要です。実行する Laravel アプリケーションで `composer.lock` と `php artisan help workflow:v2:repair-search-datetimes` を確認してください。ソースの checkout や Composer の制約だけでは、コマンドがインストール済みとは確認できません。 + +datetime の projection は、マイクロ秒精度の UTC 時点を保存します。`2026-10-08T12:34:56.123456+02:00` は `2026-10-08T10:34:56.123456Z` です。旧 writer は型付き履歴に offset を残しながら、offset のローカル時刻を保存することがありました。更新は新たな writer の誤りを防ぎますが、既存行を特定したり書き換えたりはしません。保存済み時刻から元のタイムゾーンを推測しないでください。 + +先にすべての projection writer を更新し、workflow のデータベースをバックアップしてください。ワークフローのインスタンス ID ではなく、**正確な run ID** を使います。まずプレビューします。 + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` は完全一致のガードです。run の実際の namespace を指定してください。旧来の null namespace も含め、正確な run ID だけで十分な場合に限って省略します。明示的な空 namespace は拒否されます。`--key` を省略すると、その run の datetime 属性が対象です。既知のキーを複数選ぶ場合は `--key=SubmittedAt --key=ApprovedAt` のように繰り返します。 + +既定はプレビューです。`examined`、`would_repair`、正確な run とキーの選択を確認してから、同じ選択を明示的に適用します。 + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +選択した属性と run summary を読み直し、再びプレビューしてください。根拠が変わらず値が正しければ、apply を繰り返しても修復数はゼロです。一部を修復できても、未選択のキーが正しいとは限りません。 + +各キーについて、保持されている最新の明示的に型付けされた `SearchAttributesUpserted` が必要で、その元の論理コマンドシーケンスが projection と一致しなければなりません。履歴の削除、根拠の欠落・古さ、曖昧なタイムゾーン、namespace の不一致、datetime 属性として残っていないキーは拒否されます。1つでも証明できないキーがあれば選択全体を拒否します。offset を推測せず、履歴を調べ、証明できるキーだけを選んでください。 + +コマンドは選択全体をロックして検証した後、派生属性と summary を1つのストレージトランザクションで更新します。正本の履歴、業務コマンド、run/task の識別子、lease は変更しません。JSON の失敗は `refused` と `unverified` を区別します。予期しないストレージエラー後は、再試行前に行を確認してください。不確かな commit は rollback を保証しません。 + +修復対象は派生検索属性と summary です。削除された履歴は復元せず、正本の input も変えません。Server の別の visibility query binding 処理とイメージへの採用には、それぞれ検証済みの提供が必要です。Core の tag だけでは HTTP の修正を確認できません。[正規の復旧手順](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes)を参照してください。 + ## 新しい実行への継続 {#continue-as-new} continue-as-new 時、現在の検索属性は自動で引き継がれます。新しい実行は前の結合済みマップ全体で開始し、引き続き upsert できます。 diff --git a/i18n/ja/source-hashes.json b/i18n/ja/source-hashes.json index c384bb21231..47391867d2d 100644 --- a/i18n/ja/source-hashes.json +++ b/i18n/ja/source-hashes.json @@ -44,7 +44,7 @@ "features/queries.md": "c66dd9542a062edd8158a46cebc9f1bf926aaf3599dca4a3122bd9860df6e2a2", "features/sagas.md": "8dae955491a54bcbf545ce6972928df59f3885e00f98bf3a57b14dad98f89161", "features/schedules.md": "73dd4d49bfb61d5ecafc0fb799136fc170d8cd33781ff00f40893efe4e0de0d6", - "features/search-attributes.md": "74bd53d45dcde40597d7eb2f6bda6cd88c3a773ccf6beed08cd3eeb542d39b0d", + "features/search-attributes.md": "607a37a0ff8ffcb111d07f33de7b9d2797d24567fb4da37014f604a62ce709b5", "features/service-operations.md": "912131c0a8ef393040a933fb4a66e68abcb9d475a3ebd47c85287d4032f45a0e", "features/side-effects.md": "abdccab8d6fc1a12b3eff8a4ccc58730ac36f523559b4ad89c5c2a8d201a3b86", "features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822", diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/search-attributes.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/search-attributes.md index 796429883de..3a644eb3660 100644 --- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/search-attributes.md +++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/features/search-attributes.md @@ -137,6 +137,35 @@ A API de listagem do Server 2.11.0 qualificada **não tem um predicado nativo pa Inspecione a linhagem da execução quando precisar da relação real pai/filho. A filtragem compartilhada mais ampla continua sendo [trabalho de produto](https://github.com/durable-workflow/.github/issues/224); esta limitação e uma convenção de metadados criada pelo usuário não entregam essa capacidade. A [verificação](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504) preserva o resultado com pai e filho e os predicados recusados. +## Reparar atributos de busca datetime {#repair-datetime-search-attributes} + +O comando de reparo baseado no histórico exige **Workflow 2.12.0 ou posterior realmente instalado**. Confira `composer.lock` e `php artisan help workflow:v2:repair-search-datetimes` na aplicação Laravel que o executará. Checkout de fontes ou restrição Composer não comprovam que o comando está instalado. + +Projeções datetime armazenam instantes UTC com microssegundos: `2026-10-08T12:34:56.123456+02:00` equivale a `2026-10-08T10:34:56.123456Z`. Writers antigos podiam gravar a hora local do offset, preservando esse offset no histórico tipado. Atualizar evita novos erros do writer, mas não identifica nem reescreve linhas antigas. Nunca deduza o fuso original da hora armazenada. + +Atualize todos os writers de projeções e faça backup do banco do workflow primeiro. Use o **ID exato do run**, não o da instância de workflow. Comece pela prévia: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` verifica igualdade exata; use o namespace real do run. Omita apenas quando o ID exato bastar, inclusive para namespaces null legados; valor explícito vazio é recusado. Sem `--key`, a seleção abrange os atributos datetime desse run. Repita a opção para chaves conhecidas, como `--key=SubmittedAt --key=ApprovedAt`. + +A prévia é o padrão. Revise `examined`, `would_repair` e a seleção exata de run/chaves antes de aplicar explicitamente a mesma seleção: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +Leia novamente os atributos selecionados e o resumo do run; depois repita a prévia. Com evidências inalteradas e valores corretos, repetir apply informa zero reparos. Reparar um subconjunto não comprova que as chaves não selecionadas estejam corretas. + +Cada chave exige o último upsert retido e explicitamente tipado `SearchAttributesUpserted`, com a sequência lógica original do comando correspondendo à projeção. Histórico podado, evidência ausente/obsoleta, fuso ambíguo, namespace incorreto ou chaves não mais retidas como datetime recusam a operação. Uma chave sem prova recusa toda a seleção; inspecione o histórico e selecione só chaves comprovadas, sem adivinhar offsets. + +O comando bloqueia e valida toda a seleção antes de atualizar atributos derivados e seu resumo em uma transação de armazenamento. Histórico autoritativo, comandos de negócio, identidades de run/tarefa e leases não mudam. Falhas JSON distinguem `refused` e `unverified`: após erro inesperado de armazenamento, inspecione as linhas antes de repetir, pois commit incerto não garante rollback. + +O reparo cobre atributos derivados e seu resumo; não restaura histórico podado nem altera input autoritativo. O binding de consultas de visibilidade do Server e a adoção na imagem exigem entrega qualificada própria; um tag Core não comprova correção HTTP. Veja o [procedimento canônico](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes). + ## Continuar como novo {#continue-as-new} Quando um workflow continua como novo, os atributos de busca atuais são transferidos automaticamente para a nova execução. Ela inicia com o mapa mesclado completo da execução anterior e pode continuar inserindo e atualizando atributos a partir dele. diff --git a/i18n/pt-BR/source-hashes.json b/i18n/pt-BR/source-hashes.json index c384bb21231..47391867d2d 100644 --- a/i18n/pt-BR/source-hashes.json +++ b/i18n/pt-BR/source-hashes.json @@ -44,7 +44,7 @@ "features/queries.md": "c66dd9542a062edd8158a46cebc9f1bf926aaf3599dca4a3122bd9860df6e2a2", "features/sagas.md": "8dae955491a54bcbf545ce6972928df59f3885e00f98bf3a57b14dad98f89161", "features/schedules.md": "73dd4d49bfb61d5ecafc0fb799136fc170d8cd33781ff00f40893efe4e0de0d6", - "features/search-attributes.md": "74bd53d45dcde40597d7eb2f6bda6cd88c3a773ccf6beed08cd3eeb542d39b0d", + "features/search-attributes.md": "607a37a0ff8ffcb111d07f33de7b9d2797d24567fb4da37014f604a62ce709b5", "features/service-operations.md": "912131c0a8ef393040a933fb4a66e68abcb9d475a3ebd47c85287d4032f45a0e", "features/side-effects.md": "abdccab8d6fc1a12b3eff8a4ccc58730ac36f523559b4ad89c5c2a8d201a3b86", "features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822", diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/features/search-attributes.md b/i18n/uk/docusaurus-plugin-content-docs/current/features/search-attributes.md index 9996cf6b14d..6c42de4da40 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/features/search-attributes.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/features/search-attributes.md @@ -137,6 +137,35 @@ upsertSearchAttributes(['temporary_flag' => null]); Переглядайте lineage запуску, коли потрібен його фактичний батьківський/дочірній зв’язок. Ширша спільна фільтрація видимості залишається [продуктовою роботою](https://github.com/durable-workflow/.github/issues/224); опис обмеження чи власна домовленість про метадані не реалізують цю можливість. [Перевірка](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504) зберігає результат із батьком і дитиною та відхилені предикати. +## Виправлення datetime search attributes {#repair-datetime-search-attributes} + +Команда відновлення з історії потребує фактично встановленого **Workflow 2.12.0 або новішого**. Перевірте `composer.lock` і `php artisan help workflow:v2:repair-search-datetimes` у Laravel-застосунку, що виконуватиме її. Checkout вихідного коду чи обмеження Composer самі по собі не доводять наявності встановленої команди. + +Datetime-проєкції зберігають UTC-моменти з мікросекундами: `2026-10-08T12:34:56.123456+02:00` — це `2026-10-08T10:34:56.123456Z`. Старіші writers могли записати локальний час offset, зберігши сам offset у типізованій історії. Оновлення запобігає новим помилкам writer, але не визначає й не переписує старі рядки. Не вгадуйте початковий часовий пояс зі збереженого локального часу. + +Спершу оновіть усі writers проєкцій і створіть резервну копію workflow-БД. Використовуйте точний **ID run**, а не екземпляра workflow. Почніть із preview: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` перевіряє точну рівність; вкажіть справжній namespace run. Пропускайте параметр лише коли достатньо точного ID run, зокрема для старих null namespace; явне порожнє значення відхиляється. Без `--key` вибираються datetime-атрибути цього run. Повторюйте параметр для відомих ключів: `--key=SubmittedAt --key=ApprovedAt`. + +Типово виконується preview. Перегляньте `examined`, `would_repair` та точну вибірку run/ключів, перш ніж явно застосувати ту саму вибірку: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +Повторно прочитайте вибрані атрибути та summary run, потім знову виконайте preview. За незмінних доказів і вже правильних значень повторний apply повідомляє нуль виправлень. Виправлена підмножина не доводить правильності невибраних ключів. + +Потрібна остання збережена явно типізована подія `SearchAttributesUpserted` для кожного ключа з початковою логічною послідовністю команди, що збігається з проєкцією. Pruned history, відсутні/застарілі докази, неоднозначний часовий пояс, неправильний namespace і ключі, що більше не збережені як datetime, спричиняють відмову. Один недоведений ключ відхиляє всю вибірку; дослідіть історію й вибирайте лише доведені ключі, не вгадуйте offset. + +Команда блокує та перевіряє всю вибірку перед оновленням похідних атрибутів і summary в одній транзакції сховища. Авторитетна історія, бізнес-команди, ідентичність run/task та leases не змінюються. JSON відрізняє `refused` від `unverified`: після неочікуваної помилки сховища перевірте рядки до повтору, бо невизначений commit не гарантує rollback. + +Виправляються похідні search attributes та summary; pruned history не відновлюється й авторитетний input не змінюється. Окремий шлях binding visibility-запитів Server та його образ потребують власної кваліфікованої доставки; тег Core не доводить виправлення HTTP. Див. [канонічну процедуру відновлення](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes). + ## Continue-as-New {#continue-as-new} Під час continue-as-new поточні атрибути пошуку автоматично переносяться до нового запуску. Новий запуск починається з повної об’єднаної мапи атрибутів попереднього запуску й може продовжувати її оновлення. diff --git a/i18n/uk/source-hashes.json b/i18n/uk/source-hashes.json index c384bb21231..47391867d2d 100644 --- a/i18n/uk/source-hashes.json +++ b/i18n/uk/source-hashes.json @@ -44,7 +44,7 @@ "features/queries.md": "c66dd9542a062edd8158a46cebc9f1bf926aaf3599dca4a3122bd9860df6e2a2", "features/sagas.md": "8dae955491a54bcbf545ce6972928df59f3885e00f98bf3a57b14dad98f89161", "features/schedules.md": "73dd4d49bfb61d5ecafc0fb799136fc170d8cd33781ff00f40893efe4e0de0d6", - "features/search-attributes.md": "74bd53d45dcde40597d7eb2f6bda6cd88c3a773ccf6beed08cd3eeb542d39b0d", + "features/search-attributes.md": "607a37a0ff8ffcb111d07f33de7b9d2797d24567fb4da37014f604a62ce709b5", "features/service-operations.md": "912131c0a8ef393040a933fb4a66e68abcb9d475a3ebd47c85287d4032f45a0e", "features/side-effects.md": "abdccab8d6fc1a12b3eff8a4ccc58730ac36f523559b4ad89c5c2a8d201a3b86", "features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822", diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/search-attributes.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/search-attributes.md index b93d8520a55..d5b4af229dd 100644 --- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/search-attributes.md +++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/features/search-attributes.md @@ -137,6 +137,35 @@ upsertSearchAttributes(['temporary_flag' => null]); 需要实际父子关系时,请检查运行的谱系。更广泛的共享可见性筛选仍属于[产品工作](https://github.com/durable-workflow/.github/issues/224);说明此限制或采用用户自定义元数据约定并不等于交付该能力。[验证记录](https://github.com/durable-workflow/durable-workflow.github.io/issues/368#issuecomment-6362355504)保留了同时返回父子运行的结果和被拒绝的谓词。 +## 修复 datetime 搜索属性 {#repair-datetime-search-attributes} + +基于历史的修复命令要求**实际安装 Workflow 2.12.0 或更新版本**。请在将执行命令的 Laravel 应用中检查 `composer.lock` 和 `php artisan help workflow:v2:repair-search-datetimes`。源码 checkout 或 Composer 约束本身不能证明已安装该命令。 + +datetime 投影以微秒精度保存 UTC 时刻:`2026-10-08T12:34:56.123456+02:00` 表示 `2026-10-08T10:34:56.123456Z`。旧 writer 可能保存偏移量对应的本地时间,同时在有类型历史中保留偏移量。升级可以阻止新的 writer 错误,但不会识别或重写旧行。不要从已存储的本地时间猜测原始时区。 + +先升级所有投影 writer,并备份工作流数据库。使用**精确的 run ID**,而不是工作流实例 ID。先预览: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --json +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --json +``` + +`--namespace=production` 是精确相等检查,应使用 run 的实际命名空间。仅当精确 run ID 已足够时才省略,包括旧的 null 命名空间;显式空命名空间会被拒绝。不传 `--key` 时选择该 run 的 datetime 属性。可重复选项选择已知键,例如 `--key=SubmittedAt --key=ApprovedAt`。 + +默认为预览。检查 `examined`、`would_repair` 和精确的 run/键选择后,再显式应用同一选择: + +```sh +php artisan workflow:v2:repair-search-datetimes RUN_ID --namespace=production --key=SubmittedAt --apply --json +``` + +重新读取所选属性和 run summary,再次预览。证据未变且值已正确时,重复 apply 会报告零修复。修复一个子集并不能证明未选键也正确。 + +每个键都需要最新保留的、显式有类型的 `SearchAttributesUpserted` 证据,其原始逻辑命令序号必须与投影一致。历史已清理、证据缺失或过期、时区不明确、命名空间错误、键不再作为 datetime 属性保留时,操作会被拒绝。任一键无法证明就拒绝整个选择;应检查历史并只选择可证明的键,不要猜测偏移量。 + +命令先锁定并验证整个选择,再在一个存储事务中更新派生属性及其 summary。权威历史、业务命令、run/task 标识和 lease 均不改变。JSON 失败区分 `refused` 与 `unverified`:出现意外存储错误后,应先检查行再重试,因为结果不确定的 commit 不保证已 rollback。 + +此命令修复派生搜索属性及其 summary,不恢复已清理历史,也不改变权威 input。Server 独立的可见性查询绑定路径和镜像采用都需要各自经过验证的交付;Core tag 本身不能证明 HTTP 已修复。请参阅[规范恢复流程](https://github.com/durable-workflow/workflow/blob/b3bbfdb5258c68546ae38ca1fde52818e4b05d12/docs/architecture/projection-timestamp-storage.md#datetime-search-attributes)。 + ## 继续为新运行 {#continue-as-new} 工作流继续为新运行时,当前搜索属性自动继承到新运行。新运行从上一运行的完整合并属性映射开始,可继续插入或更新。 diff --git a/i18n/zh-Hans/source-hashes.json b/i18n/zh-Hans/source-hashes.json index c384bb21231..47391867d2d 100644 --- a/i18n/zh-Hans/source-hashes.json +++ b/i18n/zh-Hans/source-hashes.json @@ -44,7 +44,7 @@ "features/queries.md": "c66dd9542a062edd8158a46cebc9f1bf926aaf3599dca4a3122bd9860df6e2a2", "features/sagas.md": "8dae955491a54bcbf545ce6972928df59f3885e00f98bf3a57b14dad98f89161", "features/schedules.md": "73dd4d49bfb61d5ecafc0fb799136fc170d8cd33781ff00f40893efe4e0de0d6", - "features/search-attributes.md": "74bd53d45dcde40597d7eb2f6bda6cd88c3a773ccf6beed08cd3eeb542d39b0d", + "features/search-attributes.md": "607a37a0ff8ffcb111d07f33de7b9d2797d24567fb4da37014f604a62ce709b5", "features/service-operations.md": "912131c0a8ef393040a933fb4a66e68abcb9d475a3ebd47c85287d4032f45a0e", "features/side-effects.md": "abdccab8d6fc1a12b3eff8a4ccc58730ac36f523559b4ad89c5c2a8d201a3b86", "features/signal+timer.md": "65b4a78b9e90a845297b1cb12591dd26a6573f76c75717e1e4ba02211c590822",