create-mercato-app 0.8.1-develop.7296.1.2111d779db → 0.9.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/agentic/shared/ai/skills/om-auto-upgrade-0.8.0-to-0.9.0/SKILL.md +112 -0
- package/agentic/shared/ai/skills/om-data-model-design/references/sensitive-data.md +1 -1
- package/agentic/shared/ai/skills/tiers.json +2 -1
- package/dist/agentic/guides/module-facts.json +7612 -848
- package/dist/agentic/guides/module-facts.v2.json +7612 -848
- package/dist/agentic/guides/modules/agent_orchestrator/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/agent_orchestrator/index.md +1 -1
- package/dist/agentic/guides/modules/ai_assistant/encryption.md +13 -0
- package/dist/agentic/guides/modules/ai_assistant/exact-override-targets.md +3 -0
- package/dist/agentic/guides/modules/ai_assistant/index.md +4 -3
- package/dist/agentic/guides/modules/api_docs/index.md +1 -1
- package/dist/agentic/guides/modules/api_keys/domain-commands.md +12 -0
- package/dist/agentic/guides/modules/api_keys/index.md +3 -2
- package/dist/agentic/guides/modules/attachments/index.md +1 -1
- package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
- package/dist/agentic/guides/modules/auth/index.md +1 -1
- package/dist/agentic/guides/modules/availability/acl-features.md +13 -0
- package/dist/agentic/guides/modules/availability/backend-pages.md +14 -0
- package/dist/agentic/guides/modules/availability/di-registrations-rich.md +11 -0
- package/dist/agentic/guides/modules/availability/domain-commands.md +13 -0
- package/dist/agentic/guides/modules/availability/entities.md +11 -0
- package/dist/agentic/guides/modules/availability/events.md +13 -0
- package/dist/agentic/guides/modules/availability/exact-override-targets.md +19 -0
- package/dist/agentic/guides/modules/availability/host-extension-points.md +10 -0
- package/dist/agentic/guides/modules/availability/index.md +22 -0
- package/dist/agentic/guides/modules/availability/owned-contract-module-metadata.md +11 -0
- package/dist/agentic/guides/modules/availability/setup.md +11 -0
- package/dist/agentic/guides/modules/availability/umes-hosts.md +14 -0
- package/dist/agentic/guides/modules/business_rules/index.md +1 -1
- package/dist/agentic/guides/modules/catalog/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/catalog/di-registrations-rich.md +1 -0
- package/dist/agentic/guides/modules/catalog/exact-override-targets.md +3 -0
- package/dist/agentic/guides/modules/catalog/index.md +1 -1
- package/dist/agentic/guides/modules/catalog/workers.md +2 -0
- package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
- package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
- package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
- package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
- package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
- package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
- package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
- package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
- package/dist/agentic/guides/modules/checkout/index.md +1 -1
- package/dist/agentic/guides/modules/communication_channels/acl-features.md +2 -1
- package/dist/agentic/guides/modules/communication_channels/contribution-resolutions.md +1 -0
- package/dist/agentic/guides/modules/communication_channels/di-registrations-rich.md +11 -10
- package/dist/agentic/guides/modules/communication_channels/domain-commands.md +1 -0
- package/dist/agentic/guides/modules/communication_channels/events.md +2 -1
- package/dist/agentic/guides/modules/communication_channels/exact-override-targets.md +12 -10
- package/dist/agentic/guides/modules/communication_channels/incoming-installed-contributions.md +1 -0
- package/dist/agentic/guides/modules/communication_channels/index.md +2 -2
- package/dist/agentic/guides/modules/communication_channels/umes-contributions.md +1 -0
- package/dist/agentic/guides/modules/communication_channels/umes-hosts.md +1 -0
- package/dist/agentic/guides/modules/configs/index.md +1 -1
- package/dist/agentic/guides/modules/content/index.md +1 -1
- package/dist/agentic/guides/modules/currencies/index.md +1 -1
- package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
- package/dist/agentic/guides/modules/customer_groups/acl-features.md +16 -0
- package/dist/agentic/guides/modules/customer_groups/active-extension-bindings.md +13 -0
- package/dist/agentic/guides/modules/customer_groups/backend-pages.md +14 -0
- package/dist/agentic/guides/modules/customer_groups/cli-commands.md +11 -0
- package/dist/agentic/guides/modules/customer_groups/contribution-resolutions.md +13 -0
- package/dist/agentic/guides/modules/customer_groups/di-registrations-rich.md +13 -0
- package/dist/agentic/guides/modules/customer_groups/di-service-tokens.md +11 -0
- package/dist/agentic/guides/modules/customer_groups/domain-commands.md +11 -0
- package/dist/agentic/guides/modules/customer_groups/entities.md +13 -0
- package/dist/agentic/guides/modules/customer_groups/events.md +17 -0
- package/dist/agentic/guides/modules/customer_groups/exact-override-targets.md +27 -0
- package/dist/agentic/guides/modules/customer_groups/index.md +26 -0
- package/dist/agentic/guides/modules/customer_groups/owned-contract-module-metadata.md +11 -0
- package/dist/agentic/guides/modules/customer_groups/setup.md +11 -0
- package/dist/agentic/guides/modules/customer_groups/umes-contributions.md +13 -0
- package/dist/agentic/guides/modules/customer_groups/umes-hosts.md +21 -0
- package/dist/agentic/guides/modules/customers/acl-features.md +2 -1
- package/dist/agentic/guides/modules/customers/active-extension-bindings.md +8 -7
- package/dist/agentic/guides/modules/customers/contribution-resolutions.md +1 -0
- package/dist/agentic/guides/modules/customers/domain-commands.md +1 -0
- package/dist/agentic/guides/modules/customers/entities.md +1 -0
- package/dist/agentic/guides/modules/customers/events.md +2 -1
- package/dist/agentic/guides/modules/customers/exact-override-targets.md +2 -0
- package/dist/agentic/guides/modules/customers/index.md +3 -3
- package/dist/agentic/guides/modules/customers/umes-contributions.md +1 -0
- package/dist/agentic/guides/modules/customers/umes-hosts.md +3 -0
- package/dist/agentic/guides/modules/dashboards/index.md +1 -1
- package/dist/agentic/guides/modules/data_sync/index.md +1 -1
- package/dist/agentic/guides/modules/design_system/index.md +1 -1
- package/dist/agentic/guides/modules/devices/index.md +1 -1
- package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
- package/dist/agentic/guides/modules/directory/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/directory/index.md +1 -1
- package/dist/agentic/guides/modules/documents/index.md +1 -1
- package/dist/agentic/guides/modules/entities/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/entities/index.md +1 -1
- package/dist/agentic/guides/modules/eudr/index.md +1 -1
- package/dist/agentic/guides/modules/events/index.md +1 -1
- package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
- package/dist/agentic/guides/modules/forms/acl-features.md +16 -0
- package/dist/agentic/guides/modules/forms/active-extension-bindings.md +14 -0
- package/dist/agentic/guides/modules/forms/backend-pages.md +17 -0
- package/dist/agentic/guides/modules/forms/contribution-resolutions.md +21 -0
- package/dist/agentic/guides/modules/forms/di-registrations-rich.md +27 -0
- package/dist/agentic/guides/modules/forms/di-service-tokens.md +19 -0
- package/dist/agentic/guides/modules/forms/domain-commands.md +30 -0
- package/dist/agentic/guides/modules/forms/encryption.md +11 -0
- package/dist/agentic/guides/modules/forms/entities.md +21 -0
- package/dist/agentic/guides/modules/forms/events.md +28 -0
- package/dist/agentic/guides/modules/forms/exact-override-targets.md +59 -0
- package/dist/agentic/guides/modules/forms/frontend-pages.md +16 -0
- package/dist/agentic/guides/modules/forms/index.md +28 -0
- package/dist/agentic/guides/modules/forms/owned-contract-module-metadata.md +11 -0
- package/dist/agentic/guides/modules/forms/setup.md +11 -0
- package/dist/agentic/guides/modules/forms/umes-contributions.md +21 -0
- package/dist/agentic/guides/modules/forms/umes-hosts.md +43 -0
- package/dist/agentic/guides/modules/forms/workers.md +12 -0
- package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
- package/dist/agentic/guides/modules/generators/index.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
- package/dist/agentic/guides/modules/integrations/di-registrations-rich.md +8 -8
- package/dist/agentic/guides/modules/integrations/di-service-tokens.md +4 -4
- package/dist/agentic/guides/modules/integrations/exact-override-targets.md +8 -8
- package/dist/agentic/guides/modules/integrations/index.md +1 -1
- package/dist/agentic/guides/modules/messages/index.md +1 -1
- package/dist/agentic/guides/modules/notifications/index.md +1 -1
- package/dist/agentic/guides/modules/onboarding/index.md +1 -1
- package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
- package/dist/agentic/guides/modules/perspectives/index.md +1 -1
- package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
- package/dist/agentic/guides/modules/planner/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/planner/index.md +1 -1
- package/dist/agentic/guides/modules/portal/index.md +1 -1
- package/dist/agentic/guides/modules/progress/index.md +1 -1
- package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
- package/dist/agentic/guides/modules/query_index/index.md +1 -1
- package/dist/agentic/guides/modules/record_locks/index.md +1 -1
- package/dist/agentic/guides/modules/resources/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/resources/index.md +1 -1
- package/dist/agentic/guides/modules/sales/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/sales/exact-override-targets.md +4 -4
- package/dist/agentic/guides/modules/sales/index.md +1 -1
- package/dist/agentic/guides/modules/sales/setup.md +1 -1
- package/dist/agentic/guides/modules/scheduler/index.md +1 -1
- package/dist/agentic/guides/modules/search/index.md +1 -1
- package/dist/agentic/guides/modules/security/index.md +1 -1
- package/dist/agentic/guides/modules/seeds/index.md +1 -1
- package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
- package/dist/agentic/guides/modules/sso/index.md +1 -1
- package/dist/agentic/guides/modules/staff/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/staff/index.md +1 -1
- package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
- package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
- package/dist/agentic/guides/modules/sync_excel/active-extension-bindings.md +11 -0
- package/dist/agentic/guides/modules/sync_excel/index.md +3 -2
- package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
- package/dist/agentic/guides/modules/telemetry/index.md +1 -1
- package/dist/agentic/guides/modules/tillio/index.md +1 -1
- package/dist/agentic/guides/modules/translations/index.md +1 -1
- package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
- package/dist/agentic/guides/modules/webhooks/index.md +1 -1
- package/dist/agentic/guides/modules/wms/active-extension-bindings.md +1 -1
- package/dist/agentic/guides/modules/wms/contribution-resolutions.md +3 -0
- package/dist/agentic/guides/modules/wms/di-registrations-rich.md +8 -8
- package/dist/agentic/guides/modules/wms/exact-override-targets.md +11 -8
- package/dist/agentic/guides/modules/wms/index.md +3 -3
- package/dist/agentic/guides/modules/wms/umes-contributions.md +3 -0
- package/dist/agentic/guides/modules/workflows/active-extension-bindings.md +3 -3
- package/dist/agentic/guides/modules/workflows/index.md +1 -1
- package/dist/agentic/guides/reference-module-facts.json +1 -1
- package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +73 -1
- package/dist/agentic/guides/upstream/manifest.json +2 -2
- package/dist/agentic/shared/ai/skills/om-auto-upgrade-0.8.0-to-0.9.0/SKILL.md +112 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/sensitive-data.md +1 -1
- package/dist/agentic/shared/ai/skills/tiers.json +2 -1
- package/dist/index.js +1 -1
- package/package.json +4 -5
- package/template/.env.example +42 -1
- package/template/docker/otel-collector-config.yaml +27 -0
- package/template/docker-compose.fullapp.yml +17 -0
- package/template/package.json.template +2 -2
- package/template/scripts/dev-runtime-probe.mjs +19 -0
- package/template/scripts/dev.mjs +6 -5
- package/template/src/__tests__/instrumentation-telemetry-bootstrap.test.ts +44 -0
- package/template/src/app/api/[...slug]/route.ts +25 -2
- package/template/src/i18n/de.json +9 -0
- package/template/src/i18n/en.json +9 -0
- package/template/src/i18n/es.json +9 -0
- package/template/src/i18n/ko.json +9 -0
- package/template/src/i18n/pl.json +9 -0
- package/template/src/instrumentation.ts +9 -2
- package/template/src/modules/example/__integration__/TC-UMES-003.spec.ts +5 -4
- package/template/src/modules/example_customers_sync/api/example-customers-sync/__tests__/scope-routes.test.ts +93 -0
- package/template/src/modules/example_customers_sync/api/example-customers-sync/mappings/route.ts +9 -3
- package/template/src/modules/example_customers_sync/api/example-customers-sync/reconcile/route.ts +10 -4
- package/template/src/modules.ts +34 -0
- package/template/tsconfig.json +3 -1
- package/template/yarn.lock.template +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: om-auto-upgrade-0.8.0-to-0.9.0
|
|
3
|
+
description: Migrate downstream Open Mercato code from 0.8.0 to 0.9.0 — enable progress before customers in src/modules.ts, and audit catalog bulk-delete job scope, redoInput for secret-bearing commands, thrown CrudHttpError statuses, resolveAttachmentRequestScope, directory organization parentId/childIds omission, SUB_WORKFLOW output ports, accent-insensitive search helpers, OpenAI-compatible preset apiMode, snapshot date revival, Gmail oauthClient, host locale overrides, CrudForm injected field ids, ChannelScope null organizations, duplicate ai_assistant encryption maps, WRONG_KEY encryption errors, the telemetry bootstrap, SSE API-key consumers, empty organization scopes, and the route-identity header; validate the app; and report manual work. Use for "upgrade Open Mercato to 0.9.0", "migrate 0.8.0 to 0.9.0", "apply the 0.9.0 upgrade notes", or "zaktualizuj Open Mercato do 0.9.0".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Auto upgrade 0.8.0 to 0.9.0
|
|
7
|
+
|
|
8
|
+
Apply the mechanical parts of the Open Mercato `0.8.0 → 0.9.0` upgrade to a downstream app. Treat the matching section of `UPGRADE_NOTES.md` as the source of truth and leave every intent-sensitive change as an explicit manual finding.
|
|
9
|
+
|
|
10
|
+
## Scope
|
|
11
|
+
|
|
12
|
+
Operate on a standalone app or downstream repository that depends on `@open-mercato/*`. Never modify the framework monorepo, framework-owned `packages/`, dependency pins, lockfiles, generated output, vendored dependencies, or secrets. Run after the user has selected and installed `0.9.0`.
|
|
13
|
+
|
|
14
|
+
## Arguments
|
|
15
|
+
|
|
16
|
+
- `--path <dir>`: downstream repository root; defaults to the current directory.
|
|
17
|
+
- `--dry-run`: detect, classify, and report without editing files or running mutating commands.
|
|
18
|
+
- `--only <id[,id...]>`: limit work to named checks.
|
|
19
|
+
- `--skip <id[,id...]>`: omit named checks and record the omission in the report.
|
|
20
|
+
|
|
21
|
+
Reject unknown flags and combining `--only` with `--skip`.
|
|
22
|
+
|
|
23
|
+
## Upgrade checks
|
|
24
|
+
|
|
25
|
+
| ID | Classification | Detect | Action |
|
|
26
|
+
| --- | --- | --- | --- |
|
|
27
|
+
| `catalog-bulk-delete-job-scope` | Detect and report | Enqueues on `CATALOG_PRODUCT_BULK_DELETE_QUEUE` or direct calls to `deleteCatalogProductsWithProgress` from `@open-mercato/core/modules/catalog/lib/bulkDelete` | Report that `scope.tenantId`, `scope.organizationId` and `scope.userId` are now all required — a job missing any of them fails before deleting anything; callers that only use `POST /api/catalog/bulk-delete` need nothing |
|
|
28
|
+
| `command-redo-input-secrets` | Detect and report | App command handlers whose `buildLog` returns `replayable: false`, or whose input carries a `password`/`secret`/`token`/`apiKey` field persisted through `buildLog` | Recommend returning a redacted `redoInput` projection on the log metadata instead of `replayable: false` (which also drops the undo token); keep `replayable: false` only where replay can never be made safe; never rewrite a `buildLog` automatically |
|
|
29
|
+
| `user-create-redo-password-reset` | No code action | N/A — operator procedure | Explain that redoing an `auth.users.create` restores the account without a credential; the operator must send a password reset afterwards |
|
|
30
|
+
| `crud-http-error-status` | Detect and report | Tests or clients that assert a `500` from an app route guard, and API route `catch` blocks that convert every error into a `500` without `isCrudHttpError` from `@open-mercato/shared/lib/crud/errors` | Report that the `/api/[...slug]` dispatcher now answers an escaped `CrudHttpError` with its own status; a handler may `throw forbidden()` / `notFound()` / `conflict()` directly; update assertions that expected `500` |
|
|
31
|
+
| `attachment-request-scope` | Detect and report | Imports of `resolveAttachmentOrganizationId` from `@open-mercato/core/modules/attachments/lib/requestScope` | Report the deprecation and that it now throws `forbidden()` for a denied scope instead of returning `null`; recommend `resolveAttachmentRequestScope(container, auth, request)` and answering `{ denied }` with the route's documented status; never rewrite the call automatically since the return shape changes |
|
|
32
|
+
| `directory-organization-hierarchy-omission` | Detect and report | Callers of `PUT /api/directory/organizations`, `PUT /api/directory/organization-branding`, or the `directory.organizations.update` command that omit `parentId`/`childIds` expecting the hierarchy to be cleared | Report that omitted fields are now left untouched; a caller that relied on omission must send `parentId: null` / `childIds: []`; flag payloads sending `childIds` without `parentId`, which can now return `400 Child cannot equal parent`. Also remind operators to audit the action log for trees already flattened by the old behavior |
|
|
33
|
+
| `subworkflow-output-ports` | Detect and report | Workflow definitions (code or seeded JSON) with a `SUB_WORKFLOW` step whose child declares `definition.io.outputs` | Report that every declared child output port is now validated and coerced before `config.outputMapping`; a required port missing from the child context or an uncoercible value now fails with `OUTPUT_VALIDATION`; require the author to satisfy or relax (`required: false`, broader type) each declared port; never edit a workflow definition automatically |
|
|
34
|
+
| `catalog-unaccent-extensions` | No code action | N/A — database operation | Explain that the migration installs `unaccent` and `pg_trgm`; the migrating role needs `CREATE` on the database (and a managed provider may need the extensions allowlisted); deploy the migration before the new code, otherwise product search fails with `function om_immutable_unaccent(text) does not exist` |
|
|
35
|
+
| `accent-insensitive-contains-pattern` | Detect and report | Calls to the deprecated `buildAccentInsensitivePatternSql` from `@open-mercato/shared/lib/db/accentInsensitiveSearch`, and any hand-written accent-insensitive predicate on `catalog_products` | Recommend `buildAccentInsensitiveContainsPatternSql()` bound to the **raw** search term (it unaccents, escapes, and adds the surrounding `%` itself), dropping any prior `escapeLikePattern`/`%` wrapping; recommend building custom `catalog_products` predicates from the same module so they match the trigram index; never rewrite SQL automatically |
|
|
36
|
+
| `openai-compatible-preset-api-mode` | Detect and report | Calls to `createOpenAICompatibleProvider` from `@open-mercato/ai-assistant/modules/ai_assistant/lib/llm-adapters/openai` with a preset that has no `apiMode` | Report that a preset without `apiMode` now calls `POST {baseURL}/chat/completions`; add `apiMode: 'responses'` only if the backend implements the Responses API and the app relies on it |
|
|
37
|
+
| `snapshot-date-revival` | Detect and report | Calls to `reviveSnapshotSeed` (`@open-mercato/shared/lib/commands/redo`) and `extractUndoPayload` (`@open-mercato/shared/lib/commands/undo`) in app undo handlers that assign snapshot date fields to entities | Report that `reviveSnapshotSeed` now throws `[internal] Invalid <field> snapshot date` for an unparsable date; recommend passing `{ datePaths }` or `{ dateFields }` to `extractUndoPayload` where snapshot dates are assigned to entities |
|
|
38
|
+
| `gmail-oauth-client-required` | Detect and report | Custom callers or test fixtures that invoke `refreshCredentials` on the Gmail adapter without `oauthClient`, or that place a `_client` key on Gmail credentials | Report that the `credentials._client` fallback is removed — a missing `oauthClient` now throws and `_client` is ignored; require passing `oauthClient: { clientId, clientSecret, scopes? }` |
|
|
39
|
+
| `host-locale-overrides-module-keys` | Detect and report | Keys in the app's `src/i18n/<locale>.json` that also exist in an installed `@open-mercato/*` module dictionary with a different value | Report every collision: the host value now wins over the module value; require the user to keep intended overrides and delete stale duplicates; never delete a locale key automatically |
|
|
40
|
+
| `crudform-injected-field-id-reuse` | Detect and report | `crud-form:<entityId>:fields` widgets whose injected field `id` equals a field the host form declares | Report that the injected value now reaches host schema validation and `onSubmit`; if the reuse is deliberate, make the value match the host schema; if accidental and the widget persists the value in `onSave`, rename the injected id |
|
|
41
|
+
| `channel-scope-nullable-organization` | Detect and report | Communication channel adapter implementations whose `fetchHistory`, `applyPushNotification`, `sendReaction`, or `removeReaction` read `input.scope.organizationId` | Report that `scope` is now `ChannelScope` (`{ tenantId: string; organizationId: string \| null }`, exported from `@open-mercato/core/modules/communication_channels/lib/adapter`) and `null` means a tenant-wide channel; typecheck flags passing it where a `string` is required; never pick a fallback organization automatically |
|
|
42
|
+
| `customers-requires-progress` | Automatic when exact; otherwise report | `src/modules.ts` enables `customers` from `@open-mercato/core` and has no `progress` entry | Insert `{ id: 'progress', from: '@open-mercato/core' },` immediately before the exact single-line `customers` entry; otherwise report the line to add. `yarn generate` now fails with `Module "customers" requires: progress` without it |
|
|
43
|
+
| `ai-assistant-duplicate-encryption-maps` | Detect and report | App `encryption.ts` files whose `defaultEncryptionMaps` declare `ai_assistant:ai_chat_message`, `ai_assistant:ai_chat_conversation`, or `ai_assistant:ai_pending_action` | Report that the app now fails to start with `Duplicate default encryption map for "ai_assistant:…"`; require deleting those entries, or moving a deliberately different field set to `overrides.encryption.maps['ai_assistant:…']` in `src/modules.ts`; recommend `yarn mercato entities seed-encryption --tenant <tenantId>` for existing tenants |
|
|
44
|
+
| `encryption-wrong-key-error` | Detect and report | Direct calls to `encryptEntityPayload` or `encryptFields` in app code | Report that a value sealed under a different key now raises `TenantDataEncryptionError` with code `WRONG_KEY` instead of being double-encrypted; flag call sites that swallow errors so the failure reaches an operator |
|
|
45
|
+
| `company-create-form-spot` | No code action | Widgets targeting `crud-form:customers.company` or `crud-form:customers.customer_entity` | Explain that the company create page now publishes `crud-form:customers.company` and still dual-publishes the legacy spot; widgets on the declared host now also render in create mode (no `recordId`) |
|
|
46
|
+
| `telemetry-otlp-startup` | Detect and report | `TELEMETRY_BACKEND` set to `otlp`, `signoz`, or `newrelic` (report name and file only, never the value), and a `src/instrumentation.ts` with a bare `await registerTelemetryForNextjs()` outside `try`/`catch` | Report that a missing optional `@opentelemetry/*` dependency now fails startup with `OtlpDependencyUnavailableError`; recommend running `yarn mercato telemetry init --dry-run` and then `yarn mercato telemetry init`, applying the printed snippet by hand when it reports `manual`; check Docker Compose `.env` values for an enabled backend |
|
|
47
|
+
| `sse-stream-api-key-consumers` | Detect and report | Non-browser clients of `GET /api/events/stream` that send `x-api-key` or `Authorization: ApiKey`, or that assume a stream never closes | Report that API-key callers now get `401` and every stream closes after `OM_EVENTS_SSE_CONNECTION_MAX_AGE_MS` (±15%); require switching server consumers to webhooks and reconnecting non-browser clients |
|
|
48
|
+
| `empty-organization-scope-deny` | Detect and report | App code that widens an empty `filterIds`/`allowedIds` back to a home organization, or that resolves a single organization without `resolveSingleOrganizationIdOrDeny` / `isExplicitlyEmptyOrganizationScope` from `@open-mercato/shared/lib/auth/organizationScope` | Report that an explicitly empty scope now means deny-all everywhere; recommend the shared helpers and letting a thrown `CrudHttpError` propagate; remind operators that users seeing empty lists or `403` need organization visibility granted |
|
|
49
|
+
| `progress-api-organization-scope` | No code action | N/A — runtime behavior | Explain that `/api/progress/*` now follows the selected organization; users expecting other organizations' jobs should switch to **All organizations** |
|
|
50
|
+
| `route-identity-header` | Detect and report | App or client code that sets `x-open-mercato-route-identity`, or builds malformed percent-encoded API paths | Report that the header is internal — a forged value now returns `400` — and that a malformed percent escape returns `404` before the handler runs |
|
|
51
|
+
| `encryption-map-uniqueness-migration` | No code action | N/A — deployment ordering | Explain that `Migration20261004120000_encryption_map_scope_uniqueness` must run (`yarn db:migrate` or the deployment migration step) before the new version serves traffic; until then saving an encryption map fails |
|
|
52
|
+
|
|
53
|
+
## Workflow
|
|
54
|
+
|
|
55
|
+
### 1. Gate the target
|
|
56
|
+
|
|
57
|
+
Resolve `--path`, require a regular `package.json`, and confirm at least one dependency or development dependency starts with `@open-mercato/`. Refuse to run when the target has the framework monorepo signature, including its core and shared workspace packages.
|
|
58
|
+
|
|
59
|
+
Inspect installed and pinned Open Mercato versions. Continue when they resolve to `0.9.0`; otherwise warn with the detected versions and require explicit user confirmation before edits. A dry run may continue without confirmation.
|
|
60
|
+
|
|
61
|
+
Exclude `.git/`, `node_modules/`, `.yarn/`, `.next/`, `dist/`, `build/`, `coverage/`, `.mercato/generated/`, generated registries, vendor directories, and framework-owned packages from every scan. The single exception is `host-locale-overrides-module-keys`, which reads installed `@open-mercato/*` module dictionaries under `node_modules/` as a read-only reference and never edits them. Follow symlinks neither while scanning nor editing. Never print environment-variable values or other secret-bearing content.
|
|
62
|
+
|
|
63
|
+
### 2. Build and show the plan
|
|
64
|
+
|
|
65
|
+
Run every selected detection before editing. Report each match as `{checkId, file, line, classification, proposedAction}`. Distinguish exact automatic matches from detect-and-report candidates, and list every no-code-action reminder even when no file match applies.
|
|
66
|
+
|
|
67
|
+
For `customers-requires-progress`, an automatic match requires a regular `src/modules.ts` containing exactly one single-line object literal with `id: 'customers'` (or the double-quoted equivalent) and `from: '@open-mercato/core'`, and no `progress` module id anywhere in the file. A customers entry spread across lines, built conditionally, pushed at runtime, or loaded from another file is a detect-and-report candidate. If `progress` is already present but listed after `customers`, report it — order does not affect the generator check, so do not move it.
|
|
68
|
+
|
|
69
|
+
With `--dry-run`, print the complete plan, all no-code-action reminders, and unresolved manual work, then stop without edits, package-manager commands, generation, tests, or builds.
|
|
70
|
+
|
|
71
|
+
### 3. Apply bounded edits
|
|
72
|
+
|
|
73
|
+
Ask for confirmation of the displayed plan. Apply one minimal, idempotent edit per exact match:
|
|
74
|
+
|
|
75
|
+
- Insert `{ id: 'progress', from: '@open-mercato/core' },` on its own line immediately before the exact `customers` entry in `src/modules.ts`, copying that line's indentation, quote style, and trailing-comma convention.
|
|
76
|
+
|
|
77
|
+
Preserve file encoding, line endings, and unrelated formatting. Re-scan after editing: `src/modules.ts` must contain exactly one `progress` entry, while every manual candidate remains listed. Never perform repository-wide string replacement, and never run `yarn mercato telemetry init` without the user's explicit go-ahead (it can also edit `package.json` and `.env`).
|
|
78
|
+
|
|
79
|
+
### 4. Verify
|
|
80
|
+
|
|
81
|
+
Use the package manager and scripts declared by the downstream app; do not assume monorepo-only commands exist. Run, in order when present:
|
|
82
|
+
|
|
83
|
+
1. the configured generation script (this is what proves the `customers` → `progress` dependency is satisfied);
|
|
84
|
+
2. the configured typecheck script (this surfaces `ChannelScope` null-organization mismatches);
|
|
85
|
+
3. the smallest affected test script, otherwise the configured test script;
|
|
86
|
+
4. the configured build script.
|
|
87
|
+
|
|
88
|
+
Stop at the first new failure caused by an automatic edit, revert only that edit, and move the match to manual follow-up. Preserve and report pre-existing failures rather than rewriting unrelated code or weakening checks.
|
|
89
|
+
|
|
90
|
+
### 5. Report
|
|
91
|
+
|
|
92
|
+
Report:
|
|
93
|
+
|
|
94
|
+
- the target path and detected Open Mercato versions;
|
|
95
|
+
- the complete pre-edit plan and user confirmation;
|
|
96
|
+
- every edited file grouped by automatic check ID;
|
|
97
|
+
- every detect-and-report finding, with exact file and line;
|
|
98
|
+
- every no-code-action reminder, no-match check, and skipped check;
|
|
99
|
+
- validation commands and outcomes;
|
|
100
|
+
- unresolved operational work: granting the migrating role `CREATE` for `unaccent`/`pg_trgm` and migrating before deploying (catalog search and the encryption-map uniqueness index), `yarn mercato entities seed-encryption` for the new `ai_assistant` maps, the telemetry bootstrap refresh and optional-dependency check for an enabled OTLP backend, password resets after redoing a user create, re-parenting organization trees already flattened by the old `directory.organizations.update`, moving API-key SSE consumers to webhooks, and granting organization visibility to users with an empty scope.
|
|
101
|
+
|
|
102
|
+
If no code changes were required, still report that all twenty-five upgrade categories ran. Recommend reviewing the complete `0.8.0 → 0.9.0` section of `UPGRADE_NOTES.md` before deployment.
|
|
103
|
+
|
|
104
|
+
## Rules
|
|
105
|
+
|
|
106
|
+
- Every automatic edit must be exact, bounded, minimal, and idempotent.
|
|
107
|
+
- Never change dependency versions, lockfiles, generated output, vendor files, framework-owned packages, or secrets.
|
|
108
|
+
- Never rewrite a command's `buildLog`, a workflow definition, an organization-scope resolver, SQL search predicates, or an adapter's scope handling automatically — every such match in this window is intent-sensitive.
|
|
109
|
+
- Never delete a locale key or an encryption-map entry automatically — report the exact entries instead.
|
|
110
|
+
- Never display `TELEMETRY_BACKEND`, OTLP endpoint/header, or any other environment value; report only the variable name, file, and line.
|
|
111
|
+
- Never weaken typecheck, tests, or build to make the upgrade appear green.
|
|
112
|
+
- Always show the edit plan before mutation and the exact changed-file list afterward.
|
|
@@ -6,5 +6,5 @@ Load this reference when records contain PII, credentials, addresses, contact in
|
|
|
6
6
|
2. In module `encryption.ts`, import `ModuleEncryptionMap` from `@open-mercato/shared/modules/encryption`, declare `defaultEncryptionMaps: ModuleEncryptionMap[] = [{ entityId: '<module>:<entity>', fields: [{ field: '<database_field>' }] }]`, then `export default defaultEncryptionMaps` for generated registry compatibility. The entries are field-rule objects, not string names. Use a sibling `hashField` only for deterministic equality lookup. Let `TenantDataEncryptionService` populate it during encrypted writes, and query it with `lookupHashCandidates(value)` from `@open-mercato/shared/lib/encryption/aes`; use `hashForLookup(value)` from the same import only when the installed write contract explicitly requires a single keyed value. Never use raw SHA-256 for low-entropy PII such as email or phone values.
|
|
7
7
|
3. Import `findWithDecryption`, `findOneWithDecryption`, or `findAndCountWithDecryption` from `@open-mercato/shared/lib/encryption/find` and make a concrete call in every implemented direct sensitive-record read path; an unused import or encryption map alone is not a decrypted read. For `makeCrudRoute`, its `entityId` + `fields` factory QueryEngine owns list decryption and `list` has no `findAndCount` override key—do not insert a decryption helper as an unsupported option. Put trusted tenant/organization constraints in each direct helper query `where` **and** pass `{ tenantId, organizationId }` as the fifth-argument decryption scope. The scope selects keys; it does not authorize or scope the ORM query. Use a null/global scope only when the installed contract explicitly permits it. Audit detail/export/search/worker/CLI and other direct ORM paths.
|
|
8
8
|
4. Keep secrets out of responses, logs, errors, events, snapshots, cache keys, search documents, vector sources, and test artifacts. Exclude encrypted source values from `search.ts` field policies and indexes; index only an explicitly approved hash-only sibling for exact equality. Never sort or fuzzy-filter ciphertext.
|
|
9
|
-
5. Seed/update encryption configuration through the supported command; never hand-roll KMS/AES. For every new or changed map, use an isolated initialized test tenant to reconcile the map, read back its registration, insert a fixture through the real write path, and assert the sensitive database columns are ciphertext before claiming runtime coverage.
|
|
9
|
+
5. Seed/update encryption configuration through the supported command; never hand-roll KMS/AES. For every new or changed map, use an isolated initialized test tenant to reconcile the map, read back its registration, insert a fixture through the real write path, and assert the sensitive database columns are ciphertext before claiming runtime coverage. A fresh test tenant does not prove existing tenants are covered: maps are seeded only when a tenant is created, and nothing re-seeds tenants that already exist. When you add a map, or a field to an existing map, in a module that may already be deployed, ship a backfill migration in the same module: `this.addSql(buildEncryptionMapBackfillSql({ entityId, fields }))` from `@open-mercato/shared/lib/encryption/migration-backfill`. It inserts the map for every existing (tenant, organization) scope that already has active maps (`NOT EXISTS` guard) and appends missing fields to existing maps. Write the entity id and fields literally in the migration and leave `down()` empty. `yarn db:generate` warns when the local database shows an unbackfilled field. Plaintext rows written before the backfill are encrypted by `yarn mercato entities rotate-encryption-key --tenant <id>` without `--old-key`.
|
|
10
10
|
6. Test authorized decryption, cross-scope denial, redaction, missing keys, export/search behavior, and cleanup/retention.
|