From 203fe2612906c1c9a6478a1d4e1d41402f99d3d7 Mon Sep 17 00:00:00 2001 From: shaurye Date: Wed, 9 Sep 2026 16:37:21 -0400 Subject: [PATCH] =?UTF-8?q?@W-24087851:=20Correct=20CAP=20uninstall=20IMPE?= =?UTF-8?q?X=20order=20to=20credential=20=E2=86=92=20profile=20=E2=86=92?= =?UTF-8?q?=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Site Impex services.xsd requires the same element sequence as install. The old service-first guidance matched BM UI delete rules but produced invalid uninstall files. --- .claude/skills/generate-service-impex/SKILL.md | 16 +++++++++------- .../templates/services-uninstall.xml.tmpl | 5 +++-- .claude/skills/validate-app/SKILL.md | 1 + .../references/impex-validation.md | 7 +++++-- .claude/skills/validate-impex/SKILL.md | 9 ++++++--- .github/pull_request_template.md | 1 + AGENTS.md | 18 +++++++++++++++++- docs/testing.md | 2 +- 8 files changed, 43 insertions(+), 16 deletions(-) diff --git a/.claude/skills/generate-service-impex/SKILL.md b/.claude/skills/generate-service-impex/SKILL.md index cb94863..1479792 100644 --- a/.claude/skills/generate-service-impex/SKILL.md +++ b/.claude/skills/generate-service-impex/SKILL.md @@ -123,14 +123,16 @@ Read `references/service-patterns.md` for pre-built patterns: ```xml - - - + + + ``` -**CRITICAL:** Always use `mode="delete"` and reverse order. +**CRITICAL:** Always use `mode="delete"`. Site Impex `services.xsd` requires this sequence: `service-credential`, then `service-profile`, then `service`. Use the **same element order for install and uninstall**. The platform processes elements in document order; putting `` first makes the uninstall file invalid against the XSD, so services are not deleted. Impex is safe deleting credentials and profiles first because ORM nulls `SERVICE.CREDENTIALID` / `PROFILEID` when those objects are removed. + +**BM UI vs Site Impex:** Business Manager UI still requires deleting the service first (`RemoveServiceProfile` / `RemoveServiceCredential` refuse delete while a service references them). That UI rule does **not** apply to CAP uninstall IMPEX. ## Step 6: Configuration best practices @@ -222,8 +224,8 @@ Share profile across multiple endpoints: - [ ] Timeout appropriate for service type - [ ] Rate limiting configured - [ ] Circuit breaker enabled for external APIs -- [ ] Uninstall file includes all services in reverse order -- [ ] All services use `mode="delete"` in uninstall +- [ ] Uninstall file includes all credentials, profiles, and services in XSD order (credential → profile → service) +- [ ] All uninstall entries use `mode="delete"` - [ ] XML well-formed - [ ] Log prefix descriptive @@ -249,7 +251,7 @@ var result = service.call(params); |---------|-----| | Hardcoded production credentials | Use placeholders | | Missing uninstall script | Create matching uninstall | -| Wrong deletion order | Delete: service → profile → credential | +| Wrong deletion order | For CAP uninstall IMPEX, use credential → profile → service (`mode="delete"`), the same XSD order as install. BM UI still requires service-first; that rule does not apply to IMPEX. | | No rate limiting | Add rate limit config | | Timeout too short | Increase based on API response time | | No circuit breaker | Enable for external APIs | diff --git a/.claude/skills/scaffold-app/assets/templates/services-uninstall.xml.tmpl b/.claude/skills/scaffold-app/assets/templates/services-uninstall.xml.tmpl index 248bd7d..a44680e 100644 --- a/.claude/skills/scaffold-app/assets/templates/services-uninstall.xml.tmpl +++ b/.claude/skills/scaffold-app/assets/templates/services-uninstall.xml.tmpl @@ -1,6 +1,7 @@ - - + + + diff --git a/.claude/skills/validate-app/SKILL.md b/.claude/skills/validate-app/SKILL.md index 7c57477..9d8bbdd 100644 --- a/.claude/skills/validate-app/SKILL.md +++ b/.claude/skills/validate-app/SKILL.md @@ -193,6 +193,7 @@ find "$CAP_ROOT/impex/" -name "*.xml" -exec xmllint --noout {} \; See `references/impex-validation.md` for detailed rules: - Services use dotted notation - Install/uninstall pairs match +- Uninstall `services.xml` uses credential → profile → service order with `mode="delete"` (same XSD sequence as install; BM UI service-first delete does not apply to IMPEX) - Attribute IDs use camelCase with app prefix - SITEID placeholder (not actual site ID) - No hardcoded credentials diff --git a/.claude/skills/validate-app/references/impex-validation.md b/.claude/skills/validate-app/references/impex-validation.md index 44c7021..7627461 100644 --- a/.claude/skills/validate-app/references/impex-validation.md +++ b/.claude/skills/validate-app/references/impex-validation.md @@ -34,10 +34,12 @@ find commerce--app-v/impex/ -name "*.xml" -exec xmllint --noou ### Uninstall file (`impex/uninstall/services.xml`) **Required checks:** -- [ ] All services use `mode="delete"` -- [ ] Deletion order: service → profile → credential +- [ ] All credentials, profiles, and services use `mode="delete"` +- [ ] Element order matches `services.xsd` (and install): credential → profile → service - [ ] All service/profile/credential IDs match install file exactly +**BM UI vs Site Impex:** Business Manager UI refuses to delete a profile or credential while a service still references it (delete the service first). That UI rule does **not** apply to CAP uninstall IMPEX. Site Impex processes elements in document order and `services.xsd` requires credential → profile → service. + ## Site Preferences Validation ### Metadata file (`impex/install/meta/system-objecttype-extensions.xml`) @@ -101,6 +103,7 @@ Check for these frequent issues: **Structure:** - [ ] All XML files are well-formed (no unclosed tags) - [ ] All XML files use correct namespace declarations +- [ ] Uninstall `services.xml` uses credential → profile → service (XSD order). BM UI service-first delete does not apply to IMPEX. **If any validation fails:** - Report specific file path diff --git a/.claude/skills/validate-impex/SKILL.md b/.claude/skills/validate-impex/SKILL.md index b106c73..f372708 100644 --- a/.claude/skills/validate-impex/SKILL.md +++ b/.claude/skills/validate-impex/SKILL.md @@ -88,10 +88,12 @@ xmllint --schema "$(b2c docs schema preferences --path)" impex/install/preferenc ### Uninstallation file (`impex/uninstall/services.xml`) **Check:** -- [ ] All services use `mode="delete"` -- [ ] Deletion order: service → profile → credential +- [ ] All credentials, profiles, and services use `mode="delete"` +- [ ] Element order matches `services.xsd` (and install): credential → profile → service - [ ] All IDs match install file +**BM UI vs Site Impex:** Business Manager UI still requires deleting the service first (`RemoveServiceProfile` / `RemoveServiceCredential` refuse delete while a service references them). That UI rule does **not** apply to CAP uninstall IMPEX. + **Verify pairs match:** ```bash # Extract service IDs from both files @@ -154,7 +156,8 @@ diff /tmp/install-ids.txt /tmp/uninstall-ids.txt | `Service with ID already exists` | Use unique IDs | | `Attribute not defined in group` | Add to group-definitions | | `Invalid value for type` | Match default value to type | -| `Cannot delete service, profile in use` | Delete in order: service → profile → credential | +| `Cannot delete service, profile in use` | Business Manager UI: delete the service first, then the profile, then the credential. This UI rule does **not** apply to CAP uninstall IMPEX. | +| Uninstall `services.xml` fails XSD / services not deleted | Site Impex processes elements in document order. Use credential → profile → service (`mode="delete"`), the same sequence as install. | | `SITEID not found` | Use SITEID placeholder | ## Step 8: Pre-import checklist diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 34d908f..7296aa6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -67,6 +67,7 @@ ### Impex Files (if applicable) - [ ] Service install file has matching uninstall file - [ ] Uninstall files use `mode="delete"` +- [ ] Uninstall `services.xml` element order is credential → profile → service (same as install) - [ ] All attribute IDs prefixed with app name - [ ] No hardcoded production credentials in services.xml - [ ] SITEID placeholder used (not actual site ID) diff --git a/AGENTS.md b/AGENTS.md index a80a93d..ad8c247 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -155,7 +155,7 @@ Your response: ### 5. Impex Rules - Service install files MUST have matching uninstall files - Uninstall MUST use `mode="delete"` -- Deletion order: service → profile → credential +- Uninstall element order: credential → profile → service (Site Impex `services.xsd`; same order as install). BM UI still requires service-first; that rule does not apply to CAP uninstall IMPEX. - Use `SITEID` placeholder, not actual site IDs - All attribute IDs MUST be prefixed with app name @@ -346,6 +346,21 @@ tax/avalara-tax/catalog.json ``` +### ❌ Wrong Uninstall Element Order +```xml + + + + + + + + + +``` + +Business Manager UI still requires deleting the service first. That UI rule does not apply to CAP uninstall IMPEX. + ### ❌ Version Mismatch ```json // manifest.json @@ -499,6 +514,7 @@ Before suggesting `/submit-app-pr`, verify: **Impex Validation:** - [ ] XML syntax valid (no parsing errors) - [ ] Service install has matching uninstall +- [ ] Uninstall `services.xml` uses credential → profile → service order with `mode="delete"` - [ ] Attribute IDs prefixed with app name - [ ] No hardcoded production credentials - [ ] SITEID placeholder used (not actual site ID) diff --git a/docs/testing.md b/docs/testing.md index 422ed5e..2252569 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -208,7 +208,7 @@ Beyond `b2c cap validate`, validate the XML directly: - Well-formed XML for every file under `impex/` - Correct SFCC namespaces (`http://www.demandware.com/xml/impex/services/2015-07-01`, etc.) - `mode="delete"` on every entry in `impex/uninstall/` -- Service IDs in install match uninstall, deletion order is service → profile → credential +- Service IDs in install match uninstall; uninstall element order is credential → profile → service (same `services.xsd` sequence as install) - Attribute IDs are camelCase and prefixed with the app name - `SITEID` placeholder used in `preferences.xml` (not a real site ID) - No hardcoded production credentials