- name
- appfront-migrate
- description
- Migrate SAP BTP HTML5 applications to the appFront (Application Frontend) deployment model. Handles migration from SAP Neo HTML5 apps, html5-apps-repo with managed approuter, and standalone approuter (approuter.nodejs with localDir routes). Supports Cloud Foundry and Kyma runtimes with XSUAA or IAS authentication. Produces updated mta.yaml, xs-app.json, and xs-security.json files. Use when the user asks to migrate, convert, or move an HTML5 app to appFront.
- argument-hint
- [neo | html5-repo | standalone-approuter] [cf | kyma] [xsuaa | ias]
- disable-model-invocation
- true
- allowed-tools
- Bash, Read, Write, Edit, Glob, Grep, Task, WebFetch
# appFront Migration Skill
## HARD RULES (NEVER VIOLATE)
1. **Never touch the source project.** All migration work happens exclusively inside `appfront-migrated/`. The source directory is read-only — never edit, delete, or overwrite any file outside `appfront-migrated/`.
2. **Never assume the auth service.** Always read `xs-security.json` (or `ias-security.json`) and every `xs-app.json` before deciding XSUAA vs IAS. The source may mix both.
3. **Never apply html5-repo migration rules to a Neo source.** Neo uses a different MTA structure (`neo-mta.yaml`, parameters-based artifacts). Check first.
4. **`HTML5Runtime_enabled: true` on a destination-service resource must be removed.** Its presence signals html5-apps-repo usage. appFront does not use this property.
5. **The `destination-content` module must be removed entirely.** This module creates instance-level destinations with service keys — a pattern only used by html5-apps-repo. appFront's deployer module binds directly to service instances.
6. **The `app-content` module's `requires` list must include all backend service instances directly.** Not via destination mapping. Credentials injected into the running approuter come from direct `requires`.
7. **Never change `xs-app.json` `authenticationType` on any route without explicit user confirmation** of the target auth service. Wrong authenticationType = 401 in production.
8. **If the source uses `sap.cloud.service` in a destination-content module**, flag this as a WorkZone integration pattern requiring additional CDM steps. Document it clearly in the migration plan and wait for user acknowledgment before proceeding.
9. **Resource and service naming must use the `sap.cloud.service` prefix (without dots).** Given prefix `P` (dots stripped):
- Resource name: `P-<service>` (e.g. `comsapfavorites-app-front`, `comsapfavorites-xsuaa`)
- `service-name` parameter: `P-<service>-service` (e.g. `comsapfavorites-app-front-service`)
- Never invent arbitrary names. Never reuse the source app names. Always derive from the `sap.cloud.service` value extracted in Phase 1a-naming.
10. **Always ask for the backend URL when the backend exists.** Only emit `<<REPLACE_WITH_REAL_BACKEND_URL>>` when the user explicitly says the URL is not yet known. This placeholder is intentionally invalid — it will cause an MTA build error, forcing the user to replace it before deploying.
11. **Never add `redirect-uris` to generated `xs-security.json`.** appFront does not require them — omit the field entirely, even if the source had them.
---
## Source Type Identification (MANDATORY FIRST STEP)
Before anything else, identify the source type by examining the project structure:
**html5-apps-repo (managed approuter) indicators:**
- `mta.yaml` contains a module with `type: com.sap.application.content` and `parameters.content.subaccount.service-keys` or `parameters.content.subaccount.instances`
- A resource of type `org.cloudfoundry.managed-service` with service `html5-apps-repo` and plan `app-host`
- A resource of type `org.cloudfoundry.managed-service` with service `destination` (HTML5Runtime destination)
- `xs-app.json` routes reference destinations pointing to html5-apps-repo URLs
**SAP Neo HTML5 App indicators:**
- A `neo-mta.yaml` or `neoUpdated.mtar` artifact
- `parameters.json` with SAP Cloud Platform Neo-style properties
- No Cloud Foundry org/space references in the MTA
- HTML5 app zip artifact deployed to SAP Neo HTML5 Applications Runtime service
**WorkZone managed approuter indicators:**
- `xs-app.json` has routes with `service: "approuter-extension"` or similar Managed Approuter patterns
- `mta.yaml` module with `sap.cloud.service` in destination-content
- A `cdm.json` or similar CDM (Content Deployment Manifest) file
**Standalone approuter (localDir) indicators:**
- `mta.yaml` contains a module with `type: approuter.nodejs`
- The approuter module's `path` directory contains `xs-app.json` with routes that have `"localDir"` properties
- No `html5-apps-repo` resource anywhere in `mta.yaml`
- No `destination-content` module
- Backend destinations are injected via `group: destinations` in the approuter's `requires` block
- Typically co-located with a CAP backend (`type: nodejs`) and HDI deployer (`type: hdb`)
---
## Load Reference Index First
At the start of every migration session, load `references/INDEX.md`. This index tells you which reference files to load for each decision branch. Only load the specific reference files relevant to the current migration — do not load all of them.
## Fetching Live Documentation
Load `references/online-docs.md` at the start of every session. It contains a curated index of SAP Help Portal URLs mapped to migration phases.
**When to fetch a URL:**
- The local reference file for the current phase is marked `🔲 Placeholder` in `references/INDEX.md`
- A question arises that the local references do not clearly answer
- The user explicitly asks about official documentation
**How to fetch:**
- Use `WebFetch` with the relevant URL from `references/online-docs.md`
- Fetch only the page relevant to the current phase — do not fetch all URLs upfront
- Use the fetched content in-context only; do not write it to disk
- If the page returns no content (some SAP Help Portal pages require authentication), fall back to local references or training knowledge and inform the user
---
## Migration Workflow
### Phase 0 — Discovery (MANDATORY)
**0a — Locate the MTA root**
Determine the working directory for the migration:
```bash
# Check if mta.yaml exists in the current directory
ls mta.yaml neo-mta.yaml 2>/dev/null || echo "NOT_IN_ROOT"
# If not found, search subdirectories (up to 3 levels deep)
find . -maxdepth 3 \( -name "mta.yaml" -o -name "neo-mta.yaml" \) 2>/dev/null
```
- **If `mta.yaml` is found in the current directory**: the project root is `.`
- **If `mta.yaml` is found in a subdirectory** (e.g. `./my-project/mta.yaml`): the project root is that subdirectory. Inform the user: "I found `mta.yaml` at `./my-project/mta.yaml`. I will run the migration from that directory."
- **If no `mta.yaml` is found anywhere**: STOP. Ask the user — "I could not find an `mta.yaml` in this directory or any subdirectory. Please confirm the project path or navigate to the project root and retry."
**0b — Copy source to `appfront-migrated/`**
Immediately copy the entire source project into `appfront-migrated/` at the same level as the project root. Do this **without asking** — the source is never touched.
```bash
# SOURCE_ROOT = the project root identified in 0a (e.g. . or ./my-project)
# Copy everything, preserving structure, excluding any existing appfront-migrated folder
cp -r <SOURCE_ROOT>/. appfront-migrated/
```
If `appfront-migrated/` already exists, inform the user and ask whether to overwrite it before proceeding.
From this point on, **all file reads for analysis use the source**, and **all file writes and edits target `appfront-migrated/` exclusively**.
**0c — Source Type Detection**
Scan the **source** project for the indicators in the "Source Type Identification" section above.
```bash
# Find all mta.yaml files
find <SOURCE_ROOT> -name "mta.yaml" -o -name "neo-mta.yaml" 2>/dev/null
# Find all xs-app.json files
find <SOURCE_ROOT> -name "xs-app.json" 2>/dev/null
# Find all xs-security.json / ias-security.json files
find <SOURCE_ROOT> -name "xs-security.json" -o -name "ias-security.json" 2>/dev/null
# Check for html5-apps-repo resource type
grep -r "html5-apps-repo" <SOURCE_ROOT> --include="*.yaml" -l 2>/dev/null
# Check for standalone approuter
grep -r "approuter.nodejs" <SOURCE_ROOT> --include="*.yaml" -l 2>/dev/null
# Check for localDir routes in xs-app.json
grep -r '"localDir"' <SOURCE_ROOT> --include="*.json" -l 2>/dev/null
# Check for Neo indicators
find <SOURCE_ROOT> -name "neo-mta.yaml" -o -name "parameters.json" 2>/dev/null
```
Document your findings: `Source type: [neo | html5-repo | managed-approuter | standalone-approuter]`
**0d — Target Runtime and Auth Service**
Ask the user these BLOCKING questions **one at a time**. Wait for the answer before asking the next. Present choices as a numbered list so the user can reply with a number.
**Question 1 — Source type** (confirm or correct your detection from 0c):
> I detected the source type as **[detected type]**. Is that correct?
> 1. Yes, that's correct
> 2. No — it's Neo
> 3. No — it's html5-repo (managed approuter)
> 4. No — it's standalone approuter
**Question 2 — Target runtime:**
> Which runtime should the migrated app deploy to?
> 1. Cloud Foundry (CF)
> 2. Kyma
**Question 3 — Auth service:**
> Which auth service should the migrated app use?
> 1. XSUAA
> 2. IAS
> 3. Keep existing (same as source)
**Question 4 — Backend type** (ask for each backend destination found in `xs-app.json` / `neo-app.json`, one at a time — skip `ui5` and `test-resources`):
For each destination `<dest-name>`:
> What type of backend is **`<dest-name>`**?
> 1. SAP BTP backend (same BTP subaccount — CF app, CAP service, etc.)
> 2. External / on-prem backend (outside BTP, or a different BTP subaccount)
> 3. No backend (frontend-only app — skip destinations entirely)
**Destination methodology based on backend type:**
- **BTP backend (answer 1):**
- Use a **configuration destination** — defined in the deployer module's `parameters.config.destinations` block in `mta.yaml`
- **No destination service resource needed** in `mta.yaml`
- Set `forwardAuthToken: true` on the destination entry
- Ask for the backend URL:
> What is the URL for **`<dest-name>`**? (e.g. `https://myapp.cfapps.eu12.hana.ondemand.com`)
- **External / on-prem backend (answer 2):**
- Use a **destination service resource** in `mta.yaml` (`service: destination`, `service-plan: lite`)
- Define the destination in `init_data.subaccount.destinations` with `Authentication: NoAuthentication` — **do not ask for or configure authentication credentials**; the user will add them later in the BTP Cockpit
- Ask for the backend URL (use `<<REPLACE_WITH_REAL_BACKEND_URL>>` only if the user explicitly says the URL is not yet known):
> What is the URL for **`<dest-name>`**? (leave blank if not yet known)
- If blank, emit `<<REPLACE_WITH_REAL_BACKEND_URL>>` as the URL value
**Question 5 — Backend migration status** (ask only for BTP backends where the URL is not yet known):
> Has the BTP backend for **`<dest-name>`** already been deployed?
> 1. Yes — already deployed (I will provide the URL)
> 2. No — not yet deployed (use placeholder URL for now)
**Question 6 — XSUAA instance** (ask only if auth service is XSUAA):
> Should the migration create a new XSUAA service instance, or bind to an existing one?
> 1. Create a new XSUAA instance
> 2. Bind to an existing instance
If the user chooses **2 — existing instance**, ask:
> What is the name of the existing XSUAA service instance?
Then ask:
> Please list the existing scopes defined in that XSUAA instance (paste the `scopes` array from its `xs-security.json`, or list scope names). This is needed to avoid conflicts and to determine which new scopes must be added for the migrated app.
**0e — Workaround Detection**
Note any of these conditions that require special handling:
- `sap.cloud.service` in destination-content → WorkZone integration (load `references/troubleshooting/workzone-integration.md`)
- IAS-only source (`ias-security.json` present, no `xs-security.json`) → IAS migration path (load `references/services/ias-config.md`)
- Multiple `xs-app.json` files → multi-module app (document all modules)
- Kyma target → load `references/target-configs/kyma-deployment.md`
---
### Phase 1 — Baseline Analysis (MANDATORY)
Read from the **source** project and document the current state. All analysis is read-only against the source.
**1a — Read all configuration files:**
- All `mta.yaml` files (full content)
- All `xs-app.json` files (full content of each)
- `xs-security.json` or `ias-security.json` (full content)
- All `manifest.json` files (extract `sap.cloud.service` — see naming convention below)
- **For Neo sources: `neo-app.json`** (full content — extract `routes`, `welcomeFile`, and all `securityConstraints` entries)
**1a-naming — Extract `sap.cloud.service` for resource naming (MANDATORY)**
Run:
```bash
# Handles both flat "sap.cloud.service" and nested "sap.cloud": { "service": ... } formats
grep -r '"service"' . --include="manifest.json" -A2 -B2 | grep -A1 '"sap.cloud"'
# Also try:
grep -r 'sap\.cloud' . --include="manifest.json" -l
```
Read each matching `manifest.json` and locate the value at `sap.cloud.service` (either as a flat key or nested under `"sap.cloud": { "service": "..." }`).
Then:
1. Collect all `sap.cloud.service` values found across all `manifest.json` files.
2. **If multiple values differ** — STOP. All apps in the same MTA must share one `sap.cloud.service`. Report the conflict and ask the user which value to use.
3. **If no `sap.cloud.service` is found (always the case for Neo sources)** — this is expected for Neo apps. Explain the concept and ask:
> "`sap.cloud.service` does not exist in Neo. In appFront, this value defines a **business solution** — a logical grouping of one or more HTML5 apps sharing a single XSUAA instance and a single `app-front` service instance.
>
> **Are you migrating this app as part of a larger group of Neo apps that belong to the same product or team?**
> 1. No — migrate this app as a standalone solution
> 2. Yes — I want to group multiple Neo apps into one business solution (mass migration)
>
> In either case, please provide a `sap.cloud.service` value for this solution (e.g. `com.sap.myteam`, `com.company.hr`). Choose a namespace that represents the whole product, not just this single app."
If the user chooses **mass migration (option 2)**, ask:
> "Please list all the Neo app directories (or paths) you want to include in this business solution. I will create a single `mta.yaml` with one deployer module and one shared XSUAA instance for all of them."
Then follow the mass migration pattern in `references/migration-guides/neo-to-appfront.md` (Mass Migration section).
4. Strip all dots from the value to form the **naming prefix** (e.g. `com.sap.favorites` → `comsapfavorites`).
Use this prefix for ALL resource and service names in the migrated `mta.yaml` (see Hard Rule #9 below).
**1b — Build a Findings Table:**
| Item | Current Value | Migration Action Needed |
|------|--------------|------------------------|
| MTA modules | List each module name and type | |
| Resources | List each resource name and service | |
| html5-repo app-host resource | Present / Absent | Remove if present |
| destination-content module | Present / Absent | Remove if present |
| HTML5Runtime_enabled flag | Present / Absent | Remove if present |
| xs-app.json authenticationMethod | value | Keep / Change |
| Route authenticationType | List each | Keep / Change per route |
| sap.cloud.service usage | Present / Absent | Flag for WorkZone steps |
| Neo securityConstraints (Neo sources only) | List each `permission` value from all `securityConstraints` entries in `neo-app.json` | Map each to a XSUAA scope in `xs-security.json` |
**1c — Load source-type reference:**
- html5-repo source → load `references/source-types/html5-repo-app.md` (modeling type identification), `references/source-types/saas-approuter-creds-handling.md` (full credential chain details for the detected type), and `references/migration-guides/html5-repo-to-appfront.md`
- Neo source → load `references/source-types/neo-html5-app.md` and `references/migration-guides/neo-to-appfront.md`
- Standalone approuter source → load `references/source-types/standalone-approuter.md` and `references/migration-guides/standalone-approuter-to-appfront.md`
View on GitHub