Agent Skills › open-mercato/open-mercato › om-auto-upgrade-0.8.0-to-0.9.0

om-auto-upgrade-0.8.0-to-0.9.0

GitHub

自动将 Open Mercato 应用从 0.8.0 迁移至 0.9.0。执行代码重构与升级检查,处理 API 错误状态、加密映射、作用域逻辑等变更,并识别需人工处理的敏感修改。

.ai/skills/om-auto-upgrade-0.8.0-to-0.9.0/SKILL.md open-mercato/open-mercato

Trigger Scenarios

升级 Open Mercato 到 0.9.0 迁移 0.8.0 到 0.9.0 应用 0.9.0 升级说明

Install

npx skills add open-mercato/open-mercato --skill om-auto-upgrade-0.8.0-to-0.9.0 -g -y
More Options

Non-standard path

npx skills add https://github.com/open-mercato/open-mercato/tree/main/.ai/skills/om-auto-upgrade-0.8.0-to-0.9.0 -g -y

Use without installing

npx skills use open-mercato/open-mercato@om-auto-upgrade-0.8.0-to-0.9.0

指定 Agent (Claude Code)

npx skills add open-mercato/open-mercato --skill om-auto-upgrade-0.8.0-to-0.9.0 -a claude-code -g -y

安装 repo 全部 skill

npx skills add open-mercato/open-mercato --all -g -y

预览 repo 内 skill

npx skills add open-mercato/open-mercato --list

SKILL.md

Frontmatter
{
    "name": "om-auto-upgrade-0.8.0-to-0.9.0",
    "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\"."
}

Auto upgrade 0.8.0 to 0.9.0

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.

Scope

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.

Arguments

  • --path <dir>: downstream repository root; defaults to the current directory.
  • --dry-run: detect, classify, and report without editing files or running mutating commands.
  • --only <id[,id...]>: limit work to named checks.
  • --skip <id[,id...]>: omit named checks and record the omission in the report.

Reject unknown flags and combining --only with --skip.

Upgrade checks

ID Classification Detect Action
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
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
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
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
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
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
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
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
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
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
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
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? }
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
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
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
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
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
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
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)
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
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
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
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
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
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

Workflow

1. Gate the target

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.

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.

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.

2. Build and show the plan

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.

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.

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.

3. Apply bounded edits

Ask for confirmation of the displayed plan. Apply one minimal, idempotent edit per exact match:

  • 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.

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).

4. Verify

Use the package manager and scripts declared by the downstream app; do not assume monorepo-only commands exist. Run, in order when present:

  1. the configured generation script (this is what proves the customers → progress dependency is satisfied);
  2. the configured typecheck script (this surfaces ChannelScope null-organization mismatches);
  3. the smallest affected test script, otherwise the configured test script;
  4. the configured build script.

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.

5. Report

Report:

  • the target path and detected Open Mercato versions;
  • the complete pre-edit plan and user confirmation;
  • every edited file grouped by automatic check ID;
  • every detect-and-report finding, with exact file and line;
  • every no-code-action reminder, no-match check, and skipped check;
  • validation commands and outcomes;
  • 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.

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.

Rules

  • Every automatic edit must be exact, bounded, minimal, and idempotent.
  • Never change dependency versions, lockfiles, generated output, vendor files, framework-owned packages, or secrets.
  • 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.
  • Never delete a locale key or an encryption-map entry automatically — report the exact entries instead.
  • Never display TELEMETRY_BACKEND, OTLP endpoint/header, or any other environment value; report only the variable name, file, and line.
  • Never weaken typecheck, tests, or build to make the upgrade appear green.
  • Always show the edit plan before mutation and the exact changed-file list afterward.

Version History

  • 4374c48 Current 2026-10-19 05:03

Same Skill Collection

.ai/skills/codex/backend-ui-design/SKILL.md
.ai/skills/om-app-spec-writing/SKILL.md
.ai/skills/om-auto-continue-pr-loop/SKILL.md
.ai/skills/om-auto-create-pr-loop/SKILL.md
.ai/skills/om-auto-publish-pr/SKILL.md
.ai/skills/om-auto-qa-scenarios/SKILL.md
.ai/skills/om-auto-review-pr/SKILL.md
.ai/skills/om-auto-sec-report-pr/SKILL.md
.ai/skills/om-auto-sec-report/SKILL.md
.ai/skills/om-auto-upgrade-0.4.10-to-0.5.0/SKILL.md
.ai/skills/om-auto-upgrade-0.6.6-to-0.6.7/SKILL.md
.ai/skills/om-auto-upgrade-0.6.7-to-0.7.0/SKILL.md
.ai/skills/om-backend-ui-design/SKILL.md
.ai/skills/om-code-review/SKILL.md
.ai/skills/om-create-agents-md/SKILL.md
.ai/skills/om-dev-container-maintenance/SKILL.md
.ai/skills/om-ds-guardian/SKILL.md
.ai/skills/om-fix-specs/SKILL.md
.ai/skills/om-followup-issue-from-pr/SKILL.md
.ai/skills/om-help/SKILL.md
.ai/skills/om-implement-spec/SKILL.md
.ai/skills/om-integration-builder/SKILL.md
.ai/skills/om-integration-tests/SKILL.md
.ai/skills/om-judge-agent-session/SKILL.md
.ai/skills/om-migrate-mikro-orm/SKILL.md
.ai/skills/om-mockup-prototype/SKILL.md
.ai/skills/om-pr-autopilot/SKILL.md
.ai/skills/om-pre-implement-spec/SKILL.md
.ai/skills/om-prepare-issue/SKILL.md
.ai/skills/om-prepare-test-env/SKILL.md
.ai/skills/om-refresh-standalone-harness/SKILL.md
.ai/skills/om-share-this-session/SKILL.md
.ai/skills/om-skill-creator/SKILL.md
.ai/skills/om-smart-test/SKILL.md
.ai/skills/om-spec-writing/SKILL.md
docker/opencode/skills/deal-qualification/SKILL.md
docker/opencode/skills/resolution-playbook/SKILL.md
docker/opencode/skills/stage-playbook/SKILL.md
.ai/skills/om-auto-upgrade-0.7.0-to-0.8.0/SKILL.md
.ai/skills/om-create-ai-agent/SKILL.md
.ai/skills/om-create-web-research-adapter/SKILL.md
.ai/skills/om-figma-design-with-ds/SKILL.md
.ai/skills/om-gap-analysis/SKILL.md

Metadata

Files
0
Version
4374c48
Hash
47697267
Indexed
2026-10-19 05:03

홈 - 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-19 11:12
浙ICP备14020137号-1