Skip to main content

analyze-partner-codebase

Analyze the partner's existing codebase across all detected surfaces and write service cards into service-cards/ — one per-surface card set (backend/, plus a UI set in mobile/, web/, ios/, or android/), always the shared context in shared/, and a security/DIRECT_CALLS_AUDIT.md where applicable. Run this first, before any other skill.

Source facts

Repository
adobe/adobe-retail-partnerships-ai-kit
Last source activity
August 30, 2026 at 23:56
Detected SKILL.md language
English
Stars
0
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.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
analyze-partner-codebase
description
Analyze the partner's existing codebase across all detected surfaces and write service cards into service-cards/ — one per-surface card set (backend/, plus a UI set in mobile/, web/, ios/, or android/), always the shared context in shared/, and a security/DIRECT_CALLS_AUDIT.md where applicable. Run this first, before any other skill.
# Skill: /analyze-partner-codebase *New to this kit? Read [`manual/conceptual-guide.md`](../../manual/conceptual-guide.md) and [`manual/quick-start.md`](../../manual/quick-start.md) first — they explain the mental model this skill assumes.* Analyze the partner's existing codebase across all detected surfaces and write **service cards** (a durable, machine-readable description of one surface of your app — see [`manual/methodology/card-model.md`](../../manual/methodology/card-model.md) for the full model) into `service-cards/` — one per-surface card set (`backend/`, plus a UI set in `mobile/`, `web/`, `ios/`, or `android/`), always the shared context in `shared/`, and a `security/DIRECT_CALLS_AUDIT.md` where applicable. The card taxonomy is defined in [`../../manual/methodology/card-model.md`](../../manual/methodology/card-model.md); the blank templates live in `service-cards/_templates/`. **Run this first before any other skill.** --- ## Instructions You are analyzing a partner developer's existing codebase to understand their architecture. **First resolve the target surfaces:** read the `.target-apps` registry at the kit root and resolve `$APP_backend`, `$APP_web`, `$APP_mobile`, `$APP_ios`, `$APP_android` per the rule in manual/methodology/modes.md / [`../../manual/methodology/modes.md`](../../manual/methodology/modes.md#surface-registry-and-multi-repo-resolution) (a surface = its own entry, else `root`; absent surfaces are skipped). If neither `.target-apps` nor a legacy `.target-app` exists, **default the target to the kit's bundled feature-less base app at `base-ref-app/`** (Mode A's default — analyze `base-ref-app/` in place; the partner supplies only their Adobe credentials later). Only if `base-ref-app/` is also absent, tell the user to run `./INSTALL.sh <path(s)>` from the kit and stop. A partner may always register their own repo(s) to target instead. **Scan each resolved surface in its own repo.** Write the card sets into `service-cards/` **at the kit root** (never inside a partner repo, which must stay clean) — copy the matching template set from `service-cards/_templates/` into the surface folder, then fill it (see Step 8). When `root` resolves multiple surfaces to one path (monorepo), scan its subprojects as in Step 1. ### Step 0 — Fast path shortcut: reuse the pre-bundled cards (bundled base app only) **Before running Step 1, check whether this run even needs a live scan.** If **no partner repo is registered** (`.target-apps`/`.target-app` absent — the target has defaulted to `base-ref-app/` above) **and** [`base-ref-app/service-cards/`](../../base-ref-app/service-cards/README.md) already exists, **copy that directory's contents into the working `service-cards/` location** (backend/, mobile/, web/, shared/) instead of re-scanning the code, and report: *"Using pre-bundled cards for the base reference app — skipping full analysis."* Skip straight to Step 9 with those copied cards. This is the Fast path described in [`../../manual/methodology/workflow.md`](../../manual/methodology/workflow.md#process-depth-by-target-fast-path-vs-full-workflow) — `base-ref-app/` is fixed and Adobe-controlled, so its cards don't need live re-derivation on every run. **A real, registered partner repo always gets the full live analysis below — this shortcut never applies to one.** Steps 1–9 are unchanged and still the only path for any registered surface (or if `base-ref-app/service-cards/` is itself somehow missing, in which case fall through to Step 1 and analyze `base-ref-app/` for real, as this skill originally did to produce that pre-bundled set). ### Step 1 — Detect Surfaces Scan the project root **and common subproject directories (depth ≤ 2)** for each surface — e.g. `bff/`, `backend/`, `server/`, `api/`, `services/*`, `apps/*`, `packages/*`. A marker file (`package.json`, `pom.xml`, `build.gradle`, `pubspec.yaml`, `go.mod`, …) found in **any** of these defines a surface rooted at **that directory**, not just the repo root. Record each surface's directory — the deep dives in Steps 2–4 operate inside it. Look for these markers: **Backend service:** - `package.json` + `express`, `fastify`, `koa`, or **`@nestjs/*`** (Nest) → Node.js - `pom.xml` + `spring-boot` → Java Spring Boot - `build.gradle` + `spring-boot` → Java Spring Boot (Gradle) - Python: `requirements.txt`/`pyproject.toml` + `fastapi`/`flask`, **or `django`/`djangorestframework`/`graphene`/`strawberry`/`ariadne`** (a `manage.py`, `settings.py`, or `urls.py` is a strong Django signal — a GraphQL-only API is still a backend) - `go.mod` → Go (router is usually chi / gin / echo / stdlib `net/http`; config via INI (`app.ini`) / Viper / env) - `Gemfile` **or a `*.gemspec` declaring `rails`/`railties`**, or a `config/routes.rb` at any depth → Ruby on Rails (a JS-only root `package.json` does **not** rule out a Rails backend nested in a monorepo — Spree keeps `rails` in `*/​*.gemspec`, not a root Gemfile) - `*.csproj`/`*.sln` + `Microsoft.NET.Sdk.Web` / `Microsoft.AspNetCore.*` → **.NET / ASP.NET Core** (minimal APIs or MVC) > **Do not conclude "no backend" just because the framework isn't in this list.** These are common markers, not the whole universe (heavy real apps use NestJS, Django+GraphQL, .NET, Micronaut, Quarkus, etc.). Any package that serves HTTP/GraphQL is a backend surface — record the actual framework you find. > **Monorepo / nested backends:** the backend is frequently NOT at the repo root (e.g. this kit's reference app keeps its Express backend in `bff/`, while the root holds only `pubspec.yaml`). Search recursively (excluding `node_modules`, `build`, `.git`, `.dart_tool`) for any `package.json` whose dependencies include `express`/`fastify`/`koa`/`nest`, any `pom.xml`/`build.gradle` with `spring-boot`, any `*.gemspec`/`config/routes.rb` (Rails), or any `*.csproj` (.NET), and treat the **containing directory** as the backend surface. **Never conclude "no backend" from a root-only scan.** > **Multi-SERVICE backend (microservices):** a backend surface may contain **many services** (e.g. a Spring Cloud or .NET microservices repo with `account-service`, `ordering`, `webhooks`, …). Do **not** assume one service, and do **not** assume a service *named* `*webhook*`/`*notify*` is the Adobe receiver — inspect what it does (many "webhooks" services manage the partner's *own outbound* webhooks and are user-scoped). Identify the service that owns **subscription / order / account** state as the integration host; record the candidate services and, if ambiguous, **STOP and ask the partner** (rule 8). Note the API-gateway route that fronts the chosen service (the external path may be defined there, not in the service). > **Multi-APP mobile / workspace parents:** if a registered mobile/`ios`/`android` root is a **workspace parent** (e.g. a Flutter/Dart `pubspec.yaml` with a `workspace:` list and no `lib/`, or a repo of many sample apps), it is not itself a runnable app. Enumerate the member apps (those with a real `lib/` + `android/ios/web`) and **STOP and ask the partner which app is the integration target** (rule 8) — do not card the meta-manifest or arbitrarily pick one. **Mobile / App:** - `pubspec.yaml` → Flutter - `package.json` + `react-native` → React Native - `ios/` directory + Swift files → iOS native - `android/` directory + Kotlin files → Android native **Web / Webapp:** - `package.json` + `react` → React - `package.json` + `vue` or `nuxt` → Vue/Nuxt - `package.json` + `next` → Next.js - `package.json` + `angular` → Angular - `pubspec.yaml` + a `web/` directory → **Flutter web** (the *same* codebase as the Flutter mobile surface, compiled to web — not a separate app) **Adobe SDK (any of the following):** - `@adobe/cceverywhere` or `@adobe/express-embed-sdk` in package.json → Express Embed SDK - `AdobeCreativeSDK` in Podfile or build.gradle → Creative SDK - Any import of `adobe` SDK packages in source files ### Step 2 — Backend Deep Dive Read key backend files to understand: - **HTTP client library** — how outbound HTTP calls are made (axios, fetch, WebClient, requests, http.Client). A framework's core package may bundle **none** — record "none in core; SDKs / native fetch used in plugins/services" rather than forcing a match. **For Node backends specifically:** check `package.json` for `axios`, `got`, `node-fetch`, `undici`. If none are present, check the Node version (`engines.node` in package.json) — Node ≥18 has native `fetch` globally; if the app targets Node ≥18 and no HTTP client dep is listed, generated code may use native `fetch` without adding a dependency. Record which is appropriate and if no outbound calls exist yet, state "none yet — native fetch available (Node 20+)" rather than silently omitting the field. - **Existing auth middleware** — where user auth is validated on incoming requests - **Inbound caller auth (external system — NOT end user)** — how (or whether) the codebase authenticates an *external system* calling its endpoints. **Critically distinguish this from end-user auth:** a login/session token, member/admin JWT, or **per-user** API key authenticates a *human/account* — a third party like Adobe cannot obtain or replay it, so it is **NOT** an external-caller mechanism and must not be mapped to a Notify auth type. Recognized external-caller shapes: a static shared secret / API key compared against config; an **opaque bearer token / API key / PAT verified against a datastore (often hashed)**; OAuth/JWT issuer+JWKS validation for a *machine* client; mTLS; an API-gateway key. **Record the exact verification path** (config-equality vs datastore/hash lookup vs JWKS/introspection) — it changes how the notify handler validates. If several auth paths exist, pick the one for **machine/app callers**, not the human-login path. **Negative example (frequent trap):** a Git-host **personal-access token**, a member/admin **JWT**, or a **user OAuth grant** that resolves to a *user account* is end-user auth **even though it's a bearer token** — do NOT map it to a Notify type; if that's all the codebase has, record UNCLEAR. **Trace the actual resolver** (the dataloader/service/filter that verifies the credential — e.g. an `AppByTokenLoader`, an `ApiKey.find_by_secret_token`, a scrypt/HMAC datastore lookup), not just the outermost middleware, because the machine path is often a *different* resolver than the visible user-login one. If the backend exposes **multiple OAuth2 grant types**, record BOTH (the end-user `password`/`authorization_code` grant AND the machine `client_credentials` grant) and name which one a caller like Adobe would use. If the only inbound auth is end-user/session-scoped, or there is no external-caller mechanism at all, record **UNCLEAR — must ask partner** so the notify skill asks rather than inventing a secret or misusing the user-login filter. - **Default request authorization / security chain** — does the framework **deny unauthenticated requests by default**? Read the security config (Spring Security `SecurityFilterChain`/`authorizeHttpRequests`, a NestJS global `APP_GUARD`, DRF `DEFAULT_PERMISSION_CLASSES`, or a globally-mounted Express auth middleware). Record the **default rule** (`anyRequest().authenticated()` vs `permitAll`), the **filter/guard order**, and any **URL allow-list mechanism** (`permitAll` matchers, `secure.ignored.urls`, a `@Public`/`@Allow(Public)` decorator). A newly added inbound endpoint **inherits the default rule**, so the notify skill must permit its path through the chain. In multi-module/monorepo projects, resolve which security beans actually load in the **target module** (`@ConditionalOnBean`, active profiles) — the shared security module's full behavior may not apply. - **Config loading** — how config/secrets are accessed: dotenv, Spring `application.yml` + `@Value`/`@ConfigurationProperties`, `os.environ`, INI (`app.ini`) / Viper (Go), Rails `credentials` + `ENV`, or a **typed config object** the app constructs (e.g. a `VendureConfig`/framework config passed at bootstrap). Record the actual mechanism — new config keys must be added in that form, not assumed to be a `.env`. - **Error handling** — how errors are propagated (try/catch patterns, global error handler, middleware) - **Logging** — which logger is used and how it's called (console.log, SLF4J, structlog, slog) - **Test framework** — Jest, JUnit5, pytest, testing package - **Package/module structure** — where new services/controllers should be placed - **Existing Adobe/IMS specifics** (if any already present) — the IMS **grant type** and token URL path actually in use (`client_credentials` vs `authorization_code`; `/ims/token/v1` vs `/v3`), and the **existing env-var names** for Adobe credentials, so generated code reuses them (e.g. `IMS_*`/`RETAIL_*`) instead of inventing `ADOBE_*` names. **Always read both `.env` and `.env.example`** (if they exist) to extract actual var names — the `.env.example` often contains commented-out Adobe vars (`IMS_*`, `RETAIL_*`, `ADOBE_*`) that define the intended naming scheme even before code is written. List ALL vars found, including `IMS_SCOPE`/`IMS_SCOPES`, `ADOBE_NOTIFY_AUTH_SECRET` or similar webhook/notify secret vars. Also check `.env.example` for any commented-out `*_NOTIFY_AUTH_SECRET`, `*_WEBHOOK_SECRET`, or similar — these signal the partner's intended Notify auth mechanism even when no handler code exists yet (record them under "Inbound caller auth"). ### Step 3 — Mobile / App Deep Dive Write the result into the `service-cards/mobile/` card set for a single cross-platform `mobile` surface, or into `service-cards/ios/` and/or `service-cards/android/` when native `ios`/`android` surfaces are registered as separate repos (one card set per native stack — Swift / Kotlin; all reuse the `_templates/mobile/` UI template set). Scan each in its resolved `$APP_<surface>`. Read key mobile source files to understand: - **Navigation** — how screens are registered and navigated to - **Network layer** — existing HTTP client/service (Dio, URLSession, Retrofit, Axios) - **State management** — Riverpod, Redux, @StateObject, ViewModel, BLoC - **Existing component/widget library** — custom design system or third-party UI kit - **User session** — how the current user's identity is accessed (what field is the unique user ID) - **Deep link handling** — how the app handles incoming deep links ### Step 4 — Web / Webapp Deep Dive Read key web source files to understand: - **Build tool** — Vite, Webpack, Next.js built-in - **Routing** — React Router, Vue Router, Next.js pages, Nuxt pages - **API call pattern** — React Query, SWR, useFetch, raw fetch/axios - **State management** — Redux, Zustand, Pinia, Context API - **UI component library** — Material UI, Ant Design, custom components — where are they? - **Backend proxy** — does an API gateway / proxy already exist? ### Step 5 — SDK Detection If an Adobe SDK was detected in Step 1: - Identify which SDK, version, and which surface it's on - Read the integration file(s) to understand the usage pattern - Determine whether the SDK flow (e.g. content creation) is separate from the subscription lifecycle - Note any auth or credential sharing that could conflict with the Retail API flow ### Step 6 — Direct Calls Security Audit Search all mobile and web source files for: - `ims-na1.adobelogin.com` or `ims-na1-stg1.adobelogin.com` - `partners.adobe.io` or `partners-stage.adobe.io` - `CLIENT_SECRET`, `client_secret`, `ADOBE_SECRET` (any hardcoded credential pattern) - Any import of IMS or Retail API URLs directly in mobile/web code
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub