@purposeinplay/payload-ai-translate 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +714 -0
- package/dist/alerts-collection.d.ts +21 -0
- package/dist/alerts-collection.js +159 -0
- package/dist/api.d.ts +4 -0
- package/dist/api.js +918 -0
- package/dist/bulk-translate-batches-collection.d.ts +29 -0
- package/dist/bulk-translate-batches-collection.js +404 -0
- package/dist/bulk-translate-units-collection.d.ts +35 -0
- package/dist/bulk-translate-units-collection.js +310 -0
- package/dist/client/estimated-cost-cell.d.ts +6 -0
- package/dist/client/estimated-cost-cell.js +12 -0
- package/dist/client/excluded-fields-field.d.ts +45 -0
- package/dist/client/excluded-fields-field.js +553 -0
- package/dist/client/field-translate-button.d.ts +6 -0
- package/dist/client/field-translate-button.js +199 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +6 -0
- package/dist/client/lib/use-global-kill-switches.d.ts +20 -0
- package/dist/client/lib/use-global-kill-switches.js +58 -0
- package/dist/client/translate-button.d.ts +2 -0
- package/dist/client/translate-button.js +228 -0
- package/dist/client/translate-modal.d.ts +16 -0
- package/dist/client/translate-modal.js +549 -0
- package/dist/client/translation-progress.d.ts +10 -0
- package/dist/client/translation-progress.js +297 -0
- package/dist/components/TranslationNavGroup.d.ts +45 -0
- package/dist/components/TranslationNavGroup.js +104 -0
- package/dist/defaults.d.ts +11 -0
- package/dist/defaults.js +16 -0
- package/dist/endpoints/client-config.d.ts +44 -0
- package/dist/endpoints/client-config.js +145 -0
- package/dist/endpoints/estimate.d.ts +5 -0
- package/dist/endpoints/estimate.js +237 -0
- package/dist/endpoints/progress.d.ts +2 -0
- package/dist/endpoints/progress.js +314 -0
- package/dist/endpoints/translate.d.ts +11 -0
- package/dist/endpoints/translate.js +376 -0
- package/dist/endpoints/translation-hub/_helpers.d.ts +140 -0
- package/dist/endpoints/translation-hub/_helpers.js +297 -0
- package/dist/endpoints/translation-hub/active.d.ts +21 -0
- package/dist/endpoints/translation-hub/active.js +220 -0
- package/dist/endpoints/translation-hub/cancel.d.ts +22 -0
- package/dist/endpoints/translation-hub/cancel.js +233 -0
- package/dist/endpoints/translation-hub/enqueue.d.ts +70 -0
- package/dist/endpoints/translation-hub/enqueue.js +529 -0
- package/dist/endpoints/translation-hub/failures.d.ts +12 -0
- package/dist/endpoints/translation-hub/failures.js +67 -0
- package/dist/endpoints/translation-hub/force-reset.d.ts +20 -0
- package/dist/endpoints/translation-hub/force-reset.js +144 -0
- package/dist/endpoints/translation-hub/index.d.ts +21 -0
- package/dist/endpoints/translation-hub/index.js +20 -0
- package/dist/endpoints/translation-hub/list.d.ts +40 -0
- package/dist/endpoints/translation-hub/list.js +182 -0
- package/dist/endpoints/translation-hub/preflight.d.ts +19 -0
- package/dist/endpoints/translation-hub/preflight.js +141 -0
- package/dist/endpoints/translation-hub/retry-failed.d.ts +38 -0
- package/dist/endpoints/translation-hub/retry-failed.js +235 -0
- package/dist/endpoints/translation-hub/revert.d.ts +88 -0
- package/dist/endpoints/translation-hub/revert.js +405 -0
- package/dist/endpoints/translation-hub/status.d.ts +45 -0
- package/dist/endpoints/translation-hub/status.js +391 -0
- package/dist/endpoints/translation-hub/usage-summary.d.ts +114 -0
- package/dist/endpoints/translation-hub/usage-summary.js +481 -0
- package/dist/exports/client.d.ts +6 -0
- package/dist/exports/client.js +6 -0
- package/dist/exports/components.d.ts +6 -0
- package/dist/exports/components.js +5 -0
- package/dist/exports/index.d.ts +8 -0
- package/dist/exports/index.js +7 -0
- package/dist/exports/providers.d.ts +9 -0
- package/dist/exports/providers.js +5 -0
- package/dist/exports/views-client.d.ts +23 -0
- package/dist/exports/views-client.js +22 -0
- package/dist/exports/views.d.ts +30 -0
- package/dist/exports/views.js +29 -0
- package/dist/hooks/after-change-global.d.ts +4 -0
- package/dist/hooks/after-change-global.js +109 -0
- package/dist/hooks/after-change.d.ts +16 -0
- package/dist/hooks/after-change.js +205 -0
- package/dist/hooks/after-delete.d.ts +30 -0
- package/dist/hooks/after-delete.js +95 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/jobs-collection.d.ts +17 -0
- package/dist/jobs-collection.js +139 -0
- package/dist/lexical/classifier.d.ts +3 -0
- package/dist/lexical/classifier.js +108 -0
- package/dist/lexical/deserializer.d.ts +4 -0
- package/dist/lexical/deserializer.js +263 -0
- package/dist/lexical/placeholder-integrity.d.ts +6 -0
- package/dist/lexical/placeholder-integrity.js +21 -0
- package/dist/lexical/placeholders.d.ts +21 -0
- package/dist/lexical/placeholders.js +117 -0
- package/dist/lexical/serializer.d.ts +21 -0
- package/dist/lexical/serializer.js +233 -0
- package/dist/lexical/types.d.ts +32 -0
- package/dist/lexical/types.js +1 -0
- package/dist/lib/auth-diagnostics.d.ts +14 -0
- package/dist/lib/auth-diagnostics.js +19 -0
- package/dist/lib/batch-counts.d.ts +58 -0
- package/dist/lib/batch-counts.js +105 -0
- package/dist/lib/bulk-translate-migrations.d.ts +92 -0
- package/dist/lib/bulk-translate-migrations.js +153 -0
- package/dist/lib/coalescing-queue.d.ts +38 -0
- package/dist/lib/coalescing-queue.js +69 -0
- package/dist/lib/content-extractor.d.ts +16 -0
- package/dist/lib/content-extractor.js +410 -0
- package/dist/lib/content-hash.d.ts +1 -0
- package/dist/lib/content-hash.js +19 -0
- package/dist/lib/content-patcher.d.ts +15 -0
- package/dist/lib/content-patcher.js +293 -0
- package/dist/lib/cost-guards.d.ts +2 -0
- package/dist/lib/cost-guards.js +18 -0
- package/dist/lib/daily-spend-cap.d.ts +58 -0
- package/dist/lib/daily-spend-cap.js +233 -0
- package/dist/lib/effective-locales.d.ts +181 -0
- package/dist/lib/effective-locales.js +302 -0
- package/dist/lib/error-messages.d.ts +245 -0
- package/dist/lib/error-messages.js +626 -0
- package/dist/lib/events.d.ts +39 -0
- package/dist/lib/events.js +146 -0
- package/dist/lib/exclude-fields.d.ts +3 -0
- package/dist/lib/exclude-fields.js +64 -0
- package/dist/lib/field-breadcrumb.d.ts +31 -0
- package/dist/lib/field-breadcrumb.js +227 -0
- package/dist/lib/field-diff.d.ts +1 -0
- package/dist/lib/field-diff.js +25 -0
- package/dist/lib/field-empty.d.ts +2 -0
- package/dist/lib/field-empty.js +68 -0
- package/dist/lib/field-resolver.d.ts +3 -0
- package/dist/lib/field-resolver.js +164 -0
- package/dist/lib/group-soft-skips.d.ts +39 -0
- package/dist/lib/group-soft-skips.js +45 -0
- package/dist/lib/locale-merge.d.ts +44 -0
- package/dist/lib/locale-merge.js +357 -0
- package/dist/lib/locale-row-check.d.ts +30 -0
- package/dist/lib/locale-row-check.js +64 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +97 -0
- package/dist/lib/manual-edit-guard.d.ts +128 -0
- package/dist/lib/manual-edit-guard.js +393 -0
- package/dist/lib/output-validation.d.ts +48 -0
- package/dist/lib/output-validation.js +148 -0
- package/dist/lib/payload-read.d.ts +16 -0
- package/dist/lib/payload-read.js +51 -0
- package/dist/lib/per-doc-claim.d.ts +90 -0
- package/dist/lib/per-doc-claim.js +140 -0
- package/dist/lib/per-doc-lock.d.ts +94 -0
- package/dist/lib/per-doc-lock.js +119 -0
- package/dist/lib/persist-usage.d.ts +91 -0
- package/dist/lib/persist-usage.js +116 -0
- package/dist/lib/progress-store.d.ts +103 -0
- package/dist/lib/progress-store.js +314 -0
- package/dist/lib/rate-limiter.d.ts +3 -0
- package/dist/lib/rate-limiter.js +53 -0
- package/dist/lib/snapshot-select.d.ts +43 -0
- package/dist/lib/snapshot-select.js +108 -0
- package/dist/lib/translate-prompt.d.ts +31 -0
- package/dist/lib/translate-prompt.js +66 -0
- package/dist/lib/translation-token-bucket.d.ts +57 -0
- package/dist/lib/translation-token-bucket.js +365 -0
- package/dist/lib/truncate-source-value.d.ts +1 -0
- package/dist/lib/truncate-source-value.js +27 -0
- package/dist/manual-edit-collection.d.ts +22 -0
- package/dist/manual-edit-collection.js +124 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +934 -0
- package/dist/providers/ai-sdk-adapter.d.ts +35 -0
- package/dist/providers/ai-sdk-adapter.js +100 -0
- package/dist/providers/anthropic.d.ts +31 -0
- package/dist/providers/anthropic.js +66 -0
- package/dist/providers/custom.d.ts +36 -0
- package/dist/providers/custom.js +24 -0
- package/dist/providers/gemini.d.ts +20 -0
- package/dist/providers/gemini.js +48 -0
- package/dist/providers/mock.d.ts +2 -0
- package/dist/providers/mock.js +29 -0
- package/dist/providers/openai.d.ts +28 -0
- package/dist/providers/openai.js +69 -0
- package/dist/settings-global.d.ts +74 -0
- package/dist/settings-global.js +216 -0
- package/dist/tasks/bulk-translate-coordinator.d.ts +115 -0
- package/dist/tasks/bulk-translate-coordinator.js +708 -0
- package/dist/tasks/bulk-translate-doc-task.d.ts +142 -0
- package/dist/tasks/bulk-translate-doc-task.js +1000 -0
- package/dist/tasks/bulk-translate-janitor.d.ts +87 -0
- package/dist/tasks/bulk-translate-janitor.js +311 -0
- package/dist/tasks/translate-job-task.d.ts +51 -0
- package/dist/tasks/translate-job-task.js +154 -0
- package/dist/translate.d.ts +113 -0
- package/dist/translate.js +911 -0
- package/dist/translation-daily-spend-collection.d.ts +24 -0
- package/dist/translation-daily-spend-collection.js +133 -0
- package/dist/translation-rate-limits-collection.d.ts +30 -0
- package/dist/translation-rate-limits-collection.js +144 -0
- package/dist/types.d.ts +672 -0
- package/dist/types.js +1 -0
- package/dist/usage-collection.d.ts +14 -0
- package/dist/usage-collection.js +377 -0
- package/dist/views/BulkRunsHub/BatchRow.d.ts +32 -0
- package/dist/views/BulkRunsHub/BatchRow.js +1222 -0
- package/dist/views/BulkRunsHub/BucketRow.d.ts +62 -0
- package/dist/views/BulkRunsHub/BucketRow.js +982 -0
- package/dist/views/BulkRunsHub/BulkRunsHub.client.d.ts +18 -0
- package/dist/views/BulkRunsHub/BulkRunsHub.client.js +331 -0
- package/dist/views/BulkRunsHub/EmptyState.d.ts +6 -0
- package/dist/views/BulkRunsHub/EmptyState.js +64 -0
- package/dist/views/BulkRunsHub/FilterBar.d.ts +16 -0
- package/dist/views/BulkRunsHub/FilterBar.js +284 -0
- package/dist/views/BulkRunsHub/InFlightBanner.d.ts +14 -0
- package/dist/views/BulkRunsHub/InFlightBanner.js +59 -0
- package/dist/views/BulkRunsHub/StatusBadge.d.ts +64 -0
- package/dist/views/BulkRunsHub/StatusBadge.js +248 -0
- package/dist/views/BulkRunsHub/SummaryStrip.d.ts +22 -0
- package/dist/views/BulkRunsHub/SummaryStrip.js +249 -0
- package/dist/views/BulkRunsHub/bucket-grouping.d.ts +200 -0
- package/dist/views/BulkRunsHub/bucket-grouping.js +344 -0
- package/dist/views/BulkRunsHub/bucketFailureSummary.d.ts +9 -0
- package/dist/views/BulkRunsHub/bucketFailureSummary.js +36 -0
- package/dist/views/BulkRunsHub/dedupedStatusFetch.d.ts +5 -0
- package/dist/views/BulkRunsHub/dedupedStatusFetch.js +45 -0
- package/dist/views/BulkRunsHub/index.d.ts +17 -0
- package/dist/views/BulkRunsHub/index.js +80 -0
- package/dist/views/BulkRunsHub/urlFilters.d.ts +14 -0
- package/dist/views/BulkRunsHub/urlFilters.js +50 -0
- package/dist/views/BulkRunsHub/useBulkRunsList.d.ts +26 -0
- package/dist/views/BulkRunsHub/useBulkRunsList.js +204 -0
- package/dist/views/BulkRunsHub/useUrlFilters.d.ts +10 -0
- package/dist/views/BulkRunsHub/useUrlFilters.js +88 -0
- package/dist/views/TranslationHub/ActiveJobs.d.ts +6 -0
- package/dist/views/TranslationHub/ActiveJobs.js +320 -0
- package/dist/views/TranslationHub/AdvancedPanel.d.ts +17 -0
- package/dist/views/TranslationHub/AdvancedPanel.js +996 -0
- package/dist/views/TranslationHub/AlertBanner.d.ts +6 -0
- package/dist/views/TranslationHub/AlertBanner.js +568 -0
- package/dist/views/TranslationHub/AuditPanel.d.ts +6 -0
- package/dist/views/TranslationHub/AuditPanel.helpers.d.ts +44 -0
- package/dist/views/TranslationHub/AuditPanel.helpers.js +71 -0
- package/dist/views/TranslationHub/AuditPanel.js +1367 -0
- package/dist/views/TranslationHub/BulkTranslate.types.d.ts +242 -0
- package/dist/views/TranslationHub/BulkTranslate.types.js +36 -0
- package/dist/views/TranslationHub/BulkTranslateFailureDrawer.d.ts +19 -0
- package/dist/views/TranslationHub/BulkTranslateFailureDrawer.js +332 -0
- package/dist/views/TranslationHub/BulkTranslateMonitor.d.ts +28 -0
- package/dist/views/TranslationHub/BulkTranslateMonitor.js +305 -0
- package/dist/views/TranslationHub/BulkTranslateNarrowViewportBanner.d.ts +3 -0
- package/dist/views/TranslationHub/BulkTranslateNarrowViewportBanner.js +42 -0
- package/dist/views/TranslationHub/BulkTranslatePostEnqueueTransition.d.ts +26 -0
- package/dist/views/TranslationHub/BulkTranslatePostEnqueueTransition.js +95 -0
- package/dist/views/TranslationHub/BulkTranslatePreflightModal.d.ts +22 -0
- package/dist/views/TranslationHub/BulkTranslatePreflightModal.js +879 -0
- package/dist/views/TranslationHub/BulkTranslateTerminalCard.d.ts +29 -0
- package/dist/views/TranslationHub/BulkTranslateTerminalCard.js +445 -0
- package/dist/views/TranslationHub/BulkTranslateTrigger.d.ts +66 -0
- package/dist/views/TranslationHub/BulkTranslateTrigger.js +161 -0
- package/dist/views/TranslationHub/EditorRecentRunsPanel.d.ts +33 -0
- package/dist/views/TranslationHub/EditorRecentRunsPanel.js +290 -0
- package/dist/views/TranslationHub/Hub.client.d.ts +74 -0
- package/dist/views/TranslationHub/Hub.client.js +357 -0
- package/dist/views/TranslationHub/ModelCombobox.d.ts +14 -0
- package/dist/views/TranslationHub/ModelCombobox.js +415 -0
- package/dist/views/TranslationHub/PerCollectionConfig.d.ts +10 -0
- package/dist/views/TranslationHub/PerCollectionConfig.helpers.d.ts +16 -0
- package/dist/views/TranslationHub/PerCollectionConfig.helpers.js +19 -0
- package/dist/views/TranslationHub/PerCollectionConfig.js +759 -0
- package/dist/views/TranslationHub/SettingsRail.d.ts +11 -0
- package/dist/views/TranslationHub/SettingsRail.js +382 -0
- package/dist/views/TranslationHub/StatusStrip.d.ts +6 -0
- package/dist/views/TranslationHub/StatusStrip.js +451 -0
- package/dist/views/TranslationHub/UsageTable.d.ts +6 -0
- package/dist/views/TranslationHub/UsageTable.helpers.d.ts +69 -0
- package/dist/views/TranslationHub/UsageTable.helpers.js +49 -0
- package/dist/views/TranslationHub/UsageTable.js +1240 -0
- package/dist/views/TranslationHub/alertGrouping.d.ts +70 -0
- package/dist/views/TranslationHub/alertGrouping.js +99 -0
- package/dist/views/TranslationHub/index.d.ts +20 -0
- package/dist/views/TranslationHub/index.js +109 -0
- package/dist/views/TranslationHub/tabNavigation.d.ts +53 -0
- package/dist/views/TranslationHub/tabNavigation.js +74 -0
- package/dist/views/TranslationHub/terminalBannerVisibility.d.ts +33 -0
- package/dist/views/TranslationHub/terminalBannerVisibility.js +124 -0
- package/dist/views/TranslationHub/useBulkTranslateActive.d.ts +49 -0
- package/dist/views/TranslationHub/useBulkTranslateActive.js +251 -0
- package/dist/views/TranslationHub/useFocusTrap.d.ts +6 -0
- package/dist/views/TranslationHub/useFocusTrap.js +81 -0
- package/dist/views/TranslationHub/useTranslationHubUsageSummary.d.ts +77 -0
- package/dist/views/TranslationHub/useTranslationHubUsageSummary.js +267 -0
- package/dist/views/shared/EditorError.d.ts +97 -0
- package/dist/views/shared/EditorError.js +205 -0
- package/dist/views/shared/ModelCell.d.ts +18 -0
- package/dist/views/shared/ModelCell.js +31 -0
- package/dist/views/shared/docHref.d.ts +16 -0
- package/dist/views/shared/docHref.js +26 -0
- package/dist/views/shared/fetch-error-body.d.ts +25 -0
- package/dist/views/shared/fetch-error-body.js +42 -0
- package/dist/views/shared/filterPillStyle.d.ts +35 -0
- package/dist/views/shared/filterPillStyle.js +40 -0
- package/dist/views/shared/format.d.ts +75 -0
- package/dist/views/shared/format.js +131 -0
- package/package.json +141 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Access, CollectionConfig } from 'payload';
|
|
2
|
+
export declare const DEFAULT_BULK_TRANSLATE_BATCHES_COLLECTION_SLUG = "bulk-translate-batches";
|
|
3
|
+
/**
|
|
4
|
+
* Sidecar collection for the bulk-translate feature (plugin v1.2.0+).
|
|
5
|
+
* One row per bulk run. Persists the trigger context (who, when, scope,
|
|
6
|
+
* model snapshot), aggregate counts (total / running / completed /
|
|
7
|
+
* failed / skipped), and lifecycle timestamps (queued, started,
|
|
8
|
+
* completed, cancelled, reverted) so admins can reconstruct any bulk
|
|
9
|
+
* operation after the fact.
|
|
10
|
+
*
|
|
11
|
+
* `read` access defaults to `admin` role explicitly (Decision #31 in
|
|
12
|
+
* the bulk-translate design doc) — the `triggeredByEmail`,
|
|
13
|
+
* `triggerReason`, and `failures` fields can carry sensitive
|
|
14
|
+
* operational context that editor-role users should not see.
|
|
15
|
+
*
|
|
16
|
+
* Status semantics:
|
|
17
|
+
* - `queued` : row exists, coordinator task enqueued but not started
|
|
18
|
+
* - `running` : coordinator is enumerating / fan-out in progress
|
|
19
|
+
* - `completed` : every unit reached `success`
|
|
20
|
+
* - `partial` : terminal — some succeeded, some failed
|
|
21
|
+
* - `failed` : terminal — no successes
|
|
22
|
+
* - `cancelled` : terminal — cancel endpoint hit before completion
|
|
23
|
+
* - `reverted` : terminal — revert endpoint replayed pre-run snapshots
|
|
24
|
+
*
|
|
25
|
+
* Model/provider/sourceLocale are snapshotted at enqueue time
|
|
26
|
+
* (Decision #5) so an admin toggling settings mid-run does not bisect
|
|
27
|
+
* the batch across configurations.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createBulkTranslateBatchesCollection(readAccess?: Access, slug?: string): CollectionConfig;
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
export const DEFAULT_BULK_TRANSLATE_BATCHES_COLLECTION_SLUG = 'bulk-translate-batches';
|
|
2
|
+
/**
|
|
3
|
+
* Sidecar collection for the bulk-translate feature (plugin v1.2.0+).
|
|
4
|
+
* One row per bulk run. Persists the trigger context (who, when, scope,
|
|
5
|
+
* model snapshot), aggregate counts (total / running / completed /
|
|
6
|
+
* failed / skipped), and lifecycle timestamps (queued, started,
|
|
7
|
+
* completed, cancelled, reverted) so admins can reconstruct any bulk
|
|
8
|
+
* operation after the fact.
|
|
9
|
+
*
|
|
10
|
+
* `read` access defaults to `admin` role explicitly (Decision #31 in
|
|
11
|
+
* the bulk-translate design doc) — the `triggeredByEmail`,
|
|
12
|
+
* `triggerReason`, and `failures` fields can carry sensitive
|
|
13
|
+
* operational context that editor-role users should not see.
|
|
14
|
+
*
|
|
15
|
+
* Status semantics:
|
|
16
|
+
* - `queued` : row exists, coordinator task enqueued but not started
|
|
17
|
+
* - `running` : coordinator is enumerating / fan-out in progress
|
|
18
|
+
* - `completed` : every unit reached `success`
|
|
19
|
+
* - `partial` : terminal — some succeeded, some failed
|
|
20
|
+
* - `failed` : terminal — no successes
|
|
21
|
+
* - `cancelled` : terminal — cancel endpoint hit before completion
|
|
22
|
+
* - `reverted` : terminal — revert endpoint replayed pre-run snapshots
|
|
23
|
+
*
|
|
24
|
+
* Model/provider/sourceLocale are snapshotted at enqueue time
|
|
25
|
+
* (Decision #5) so an admin toggling settings mid-run does not bisect
|
|
26
|
+
* the batch across configurations.
|
|
27
|
+
*/ export function createBulkTranslateBatchesCollection(readAccess, slug = DEFAULT_BULK_TRANSLATE_BATCHES_COLLECTION_SLUG) {
|
|
28
|
+
const isAdminDefault = ({ req })=>{
|
|
29
|
+
const user = req.user;
|
|
30
|
+
const roles = user?.roles;
|
|
31
|
+
if (Array.isArray(roles) && roles.includes('admin')) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
};
|
|
36
|
+
// 1.2.8: read opened to editor+admin so the Translation Hub's Recent
|
|
37
|
+
// translations table can fetch batches for editors. Cost / model /
|
|
38
|
+
// token fields are masked at the field level below so editors see
|
|
39
|
+
// attribution + status but not provider economics. Delete / update
|
|
40
|
+
// stay admin-only — mutations route through the hub endpoints
|
|
41
|
+
// (cancel / retry / revert) which layer ownership checks on top.
|
|
42
|
+
const isEditorOrAdminDefault = ({ req })=>{
|
|
43
|
+
const user = req.user;
|
|
44
|
+
const roles = user?.roles;
|
|
45
|
+
if (!Array.isArray(roles)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return roles.includes('admin') || roles.includes('editor');
|
|
49
|
+
};
|
|
50
|
+
// Field-level read access for the cost / model surface. Admins see
|
|
51
|
+
// everything; editors see nothing on these fields. Returning `false`
|
|
52
|
+
// here strips the field from the API response (Payload contract) —
|
|
53
|
+
// not just hides it client-side.
|
|
54
|
+
const fieldAdminOnlyRead = ({ req })=>{
|
|
55
|
+
// Field access is boolean-only (a `Where` clause cannot scope a field),
|
|
56
|
+
// so coerce the collection-level Access result to a strict boolean here.
|
|
57
|
+
// Matches the documented intent: only literal admin access reveals the
|
|
58
|
+
// field; anything else strips it from the API response.
|
|
59
|
+
return isAdminDefault({
|
|
60
|
+
req
|
|
61
|
+
}) === true;
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
slug,
|
|
65
|
+
// System rows are never edited in the admin document view, so
|
|
66
|
+
// Payload's document-locking buys nothing here — and its lock check
|
|
67
|
+
// costs a second pool connection inside every update transaction
|
|
68
|
+
// (core's checkDocumentLockStatus runs a find without `req`). Under
|
|
69
|
+
// concurrent updates (e.g. dismiss-all on alerts) that exhausted the
|
|
70
|
+
// pool and deadlocked a consumer in prod on 2026-06-10.
|
|
71
|
+
lockDocuments: false,
|
|
72
|
+
labels: {
|
|
73
|
+
singular: 'Bulk Translate Batch',
|
|
74
|
+
plural: 'Bulk Translate Batches'
|
|
75
|
+
},
|
|
76
|
+
admin: {
|
|
77
|
+
group: 'Translation',
|
|
78
|
+
useAsTitle: 'id',
|
|
79
|
+
defaultColumns: [
|
|
80
|
+
'id',
|
|
81
|
+
'status',
|
|
82
|
+
'mode',
|
|
83
|
+
'totalUnits',
|
|
84
|
+
'completedUnits',
|
|
85
|
+
'failedUnits',
|
|
86
|
+
'estimatedCostUsd',
|
|
87
|
+
'actualCostUsd',
|
|
88
|
+
'startedAt'
|
|
89
|
+
],
|
|
90
|
+
hidden: ({ user })=>{
|
|
91
|
+
const roles = user?.roles;
|
|
92
|
+
return !(Array.isArray(roles) && roles.includes('admin'));
|
|
93
|
+
},
|
|
94
|
+
description: 'One row per bulk-translation run. Persists scope, snapshotted model/provider, cost estimates, and aggregate progress. Use this to audit who ran a bulk operation, when, and what the outcome was. Per-(doc, locale) detail lives in `Bulk Translate Units`.'
|
|
95
|
+
},
|
|
96
|
+
access: {
|
|
97
|
+
// 1.2.8: defaults to editor+admin so the Hub Recent translations
|
|
98
|
+
// table populates for editors. Consumers can still override via
|
|
99
|
+
// `readAccess` if they want a stricter policy.
|
|
100
|
+
read: readAccess ?? isEditorOrAdminDefault,
|
|
101
|
+
create: ()=>false,
|
|
102
|
+
update: ()=>false,
|
|
103
|
+
delete: isAdminDefault
|
|
104
|
+
},
|
|
105
|
+
fields: [
|
|
106
|
+
{
|
|
107
|
+
name: 'scope',
|
|
108
|
+
type: 'json',
|
|
109
|
+
required: true,
|
|
110
|
+
admin: {
|
|
111
|
+
readOnly: true,
|
|
112
|
+
description: 'Scope filter resolved at enqueue: `{ collections, globals, locales, excludeCollections, documentIds }`. Used by retry-failed / revert to re-resolve membership.'
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'mode',
|
|
117
|
+
type: 'select',
|
|
118
|
+
required: true,
|
|
119
|
+
options: [
|
|
120
|
+
{
|
|
121
|
+
label: 'Changed (diff-only)',
|
|
122
|
+
value: 'changed'
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
label: 'Force re-translate',
|
|
126
|
+
value: 'force'
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
label: 'Canary (limited sample)',
|
|
130
|
+
value: 'canary'
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
admin: {
|
|
134
|
+
readOnly: true
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'canaryLimit',
|
|
139
|
+
type: 'number',
|
|
140
|
+
admin: {
|
|
141
|
+
readOnly: true,
|
|
142
|
+
condition: (data)=>data?.mode === 'canary',
|
|
143
|
+
description: 'Number of (doc, locale) units the canary fan-out is capped at. Selection is random-stratified across configured collections.'
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
// Snapshotted provider/model/source-locale at enqueue time
|
|
147
|
+
// (Decision #5 + F-DA-MODEL-SWAP). The active OpenRouter model
|
|
148
|
+
// can change while a batch drains; snapshotting here pins the
|
|
149
|
+
// batch's behavior to what the admin saw in the pre-flight modal.
|
|
150
|
+
{
|
|
151
|
+
name: 'snapshotProviderKey',
|
|
152
|
+
type: 'text',
|
|
153
|
+
required: true,
|
|
154
|
+
admin: {
|
|
155
|
+
readOnly: true
|
|
156
|
+
},
|
|
157
|
+
// 1.2.8: provider key is operational telemetry — admins only.
|
|
158
|
+
access: {
|
|
159
|
+
read: fieldAdminOnlyRead
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: 'snapshotModelId',
|
|
164
|
+
type: 'text',
|
|
165
|
+
required: true,
|
|
166
|
+
admin: {
|
|
167
|
+
readOnly: true
|
|
168
|
+
},
|
|
169
|
+
// 1.2.8: model is operational telemetry — admins only.
|
|
170
|
+
access: {
|
|
171
|
+
read: fieldAdminOnlyRead
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'snapshotSourceLocale',
|
|
176
|
+
type: 'text',
|
|
177
|
+
required: true,
|
|
178
|
+
admin: {
|
|
179
|
+
readOnly: true
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'estimatedCostUsd',
|
|
184
|
+
type: 'number',
|
|
185
|
+
required: true,
|
|
186
|
+
admin: {
|
|
187
|
+
readOnly: true
|
|
188
|
+
},
|
|
189
|
+
// 1.2.8: USD figures hidden from editors — cost is admin-only.
|
|
190
|
+
access: {
|
|
191
|
+
read: fieldAdminOnlyRead
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: 'actualCostUsd',
|
|
196
|
+
type: 'number',
|
|
197
|
+
defaultValue: 0,
|
|
198
|
+
admin: {
|
|
199
|
+
readOnly: true
|
|
200
|
+
},
|
|
201
|
+
access: {
|
|
202
|
+
read: fieldAdminOnlyRead
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'status',
|
|
207
|
+
type: 'select',
|
|
208
|
+
required: true,
|
|
209
|
+
index: true,
|
|
210
|
+
defaultValue: 'queued',
|
|
211
|
+
options: [
|
|
212
|
+
{
|
|
213
|
+
label: 'Queued',
|
|
214
|
+
value: 'queued'
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
label: 'Running',
|
|
218
|
+
value: 'running'
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
label: 'Cancelling',
|
|
222
|
+
value: 'cancelling'
|
|
223
|
+
},
|
|
224
|
+
// Terminal success vocab is `'success'` (matches units
|
|
225
|
+
// collection + BulkTranslateBatchStatus type union). Pre-1.2.4
|
|
226
|
+
// wrote `'completed'` here; lib/bulk-translate-migrations.ts
|
|
227
|
+
// ships an idempotent data migration helper.
|
|
228
|
+
{
|
|
229
|
+
label: 'Completed',
|
|
230
|
+
value: 'success'
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
label: 'Partial (some failed)',
|
|
234
|
+
value: 'partial'
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
label: 'Failed',
|
|
238
|
+
value: 'failed'
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
label: 'Cancelled',
|
|
242
|
+
value: 'cancelled'
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
label: 'Reverted',
|
|
246
|
+
value: 'reverted'
|
|
247
|
+
}
|
|
248
|
+
],
|
|
249
|
+
admin: {
|
|
250
|
+
readOnly: true
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: 'totalUnits',
|
|
255
|
+
type: 'number',
|
|
256
|
+
defaultValue: 0,
|
|
257
|
+
admin: {
|
|
258
|
+
readOnly: true
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'completedUnits',
|
|
263
|
+
type: 'number',
|
|
264
|
+
defaultValue: 0,
|
|
265
|
+
admin: {
|
|
266
|
+
readOnly: true
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: 'failedUnits',
|
|
271
|
+
type: 'number',
|
|
272
|
+
defaultValue: 0,
|
|
273
|
+
admin: {
|
|
274
|
+
readOnly: true
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: 'skippedUnits',
|
|
279
|
+
type: 'number',
|
|
280
|
+
defaultValue: 0,
|
|
281
|
+
admin: {
|
|
282
|
+
readOnly: true
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
// Identity carried as `(userId, email)` rather than a relation so
|
|
286
|
+
// the audit trail survives user-record deletion. F-BIZ-07.
|
|
287
|
+
{
|
|
288
|
+
name: 'triggeredByUserId',
|
|
289
|
+
type: 'text',
|
|
290
|
+
required: true,
|
|
291
|
+
index: true,
|
|
292
|
+
admin: {
|
|
293
|
+
readOnly: true
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
name: 'triggeredByEmail',
|
|
298
|
+
type: 'text',
|
|
299
|
+
admin: {
|
|
300
|
+
readOnly: true
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: 'triggerReason',
|
|
305
|
+
type: 'textarea',
|
|
306
|
+
admin: {
|
|
307
|
+
readOnly: true,
|
|
308
|
+
description: 'Optional admin-supplied rationale for the run. Surfaces in audit and helps reconstruct intent post-hoc.'
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: 'cancelledByUserId',
|
|
313
|
+
type: 'text',
|
|
314
|
+
admin: {
|
|
315
|
+
readOnly: true
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: 'cancelledAt',
|
|
320
|
+
type: 'date',
|
|
321
|
+
admin: {
|
|
322
|
+
readOnly: true
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: 'revertedByUserId',
|
|
327
|
+
type: 'text',
|
|
328
|
+
admin: {
|
|
329
|
+
readOnly: true
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: 'revertedAt',
|
|
334
|
+
type: 'date',
|
|
335
|
+
admin: {
|
|
336
|
+
readOnly: true
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
// Two distinct timestamps:
|
|
340
|
+
// - enqueuedAt: when the batch row was created (always set)
|
|
341
|
+
// - startedAt: when the coordinator task first ran (may
|
|
342
|
+
// lag the enqueue by up to the cron tick interval; null
|
|
343
|
+
// until then). Both readonly in admin; written by the
|
|
344
|
+
// enqueue endpoint and coordinator respectively.
|
|
345
|
+
{
|
|
346
|
+
name: 'enqueuedAt',
|
|
347
|
+
type: 'date',
|
|
348
|
+
required: true,
|
|
349
|
+
index: true,
|
|
350
|
+
admin: {
|
|
351
|
+
readOnly: true
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: 'startedAt',
|
|
356
|
+
type: 'date',
|
|
357
|
+
admin: {
|
|
358
|
+
readOnly: true
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: 'completedAt',
|
|
363
|
+
type: 'date',
|
|
364
|
+
admin: {
|
|
365
|
+
readOnly: true
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
// Coordinator's enumeration cursor — persists across cron ticks so
|
|
369
|
+
// a crash mid-enumeration resumes from the last persisted point
|
|
370
|
+
// rather than re-enqueueing every doc (which would deduplicate
|
|
371
|
+
// via the partial unique index but waste cron cycles).
|
|
372
|
+
{
|
|
373
|
+
name: 'lastEnumerationCursor',
|
|
374
|
+
type: 'json',
|
|
375
|
+
admin: {
|
|
376
|
+
readOnly: true,
|
|
377
|
+
description: 'Internal coordinator state. Pagination cursor for the per-collection enumeration loop.'
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
// Soft lease lock: a coordinator updates this at the start of
|
|
381
|
+
// every tick (and clears it at finishTick when finished=true).
|
|
382
|
+
// If a second coordinator starts a tick and finds the lock
|
|
383
|
+
// updated within the lease window, it exits early — prevents
|
|
384
|
+
// the exponential trampoline fan-out that Round-5 pr-reviewer
|
|
385
|
+
// flagged when admin retries + queue duplicate-delivery race.
|
|
386
|
+
{
|
|
387
|
+
name: 'coordinatorActiveAt',
|
|
388
|
+
type: 'date',
|
|
389
|
+
admin: {
|
|
390
|
+
readOnly: true,
|
|
391
|
+
description: 'Internal lock. Coordinator heartbeat — updated each tick. A second coordinator finding this fresh within the lease window exits to avoid duplicate trampoline fan-out.'
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
name: 'failures',
|
|
396
|
+
type: 'json',
|
|
397
|
+
admin: {
|
|
398
|
+
readOnly: true,
|
|
399
|
+
description: 'Aggregated failure summary: `{ errorClass: count }`. Per-unit detail lives in `Bulk Translate Units`.'
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
]
|
|
403
|
+
};
|
|
404
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Access, CollectionConfig } from 'payload';
|
|
2
|
+
export declare const DEFAULT_BULK_TRANSLATE_UNITS_COLLECTION_SLUG = "bulk-translate-units";
|
|
3
|
+
/**
|
|
4
|
+
* Per-(collection, documentId, locale) work item for a bulk translate
|
|
5
|
+
* batch. Plugin v1.2.0+.
|
|
6
|
+
*
|
|
7
|
+
* Source of truth for unit-level state in a bulk run. Read by:
|
|
8
|
+
* 1. The `shouldSkipDocument`-equivalent check at task-entry and the
|
|
9
|
+
* per-doc retry endpoint (Decision #19 v2): "is there already a
|
|
10
|
+
* pending/running unit for this (collection, doc, locale) in some
|
|
11
|
+
* other in-flight batch?". A partial unique index on
|
|
12
|
+
* `(collection, document_id, locale) WHERE status IN
|
|
13
|
+
* ('pending','running')` enforces the invariant in Postgres
|
|
14
|
+
* regardless of application-layer races (F-DA-TOCTOU).
|
|
15
|
+
* 2. The revert action: paginates over `success` units, reads
|
|
16
|
+
* `preRunSnapshot` + `schemaHash`, restores the pre-run value.
|
|
17
|
+
* 3. The Hub monitor UI's drill-down view of failed units.
|
|
18
|
+
*
|
|
19
|
+
* `preRunSnapshot` is jsonb and stores ONLY the localized translatable
|
|
20
|
+
* fields, captured via Payload `select` (Decision #30 + F-SEC-SNAPSHOT).
|
|
21
|
+
* Never the full document — that would leak `password` / `email` /
|
|
22
|
+
* `roles` and other `excludeFields` content into a queryable
|
|
23
|
+
* collection.
|
|
24
|
+
*
|
|
25
|
+
* Read access is locked to `admin` role only (Decision #31, unchanged
|
|
26
|
+
* in 1.2.8). The snapshot column contains pre-translation source
|
|
27
|
+
* content which, even scoped to translatable fields, may include
|
|
28
|
+
* unpublished drafts editor-role users should not see. Editors who
|
|
29
|
+
* need unit-level drill-down (e.g., per-locale outcomes, failure
|
|
30
|
+
* reasons) read through the shaped `/api/translation-hub/bulk-translate/:id`
|
|
31
|
+
* (`status` endpoint, 1.2.8 opened to editor+admin) and `/failures`
|
|
32
|
+
* endpoints — those serialize a redacted view that excludes
|
|
33
|
+
* `preRunSnapshot` entirely.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createBulkTranslateUnitsCollection(readAccess?: Access, slug?: string, batchesCollectionSlug?: string): CollectionConfig;
|