Skip to main content

appfront-migrate

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.

Source facts

Repository
SAP-samples/html5-applications-migration-skills-for-sap-btp
Last source activity
September 1, 2026 at 07:51
Detected SKILL.md language
English
Stars
1
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
100 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
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
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub