# QSP-40680 — Summary

## Description

The `scorecard-results` App Function previously required a Backstage catalog ID (`assetID`) to look up a component's scorecard. Dynatrace app teams that only know their app's `dynatrace.io/app-identifier` annotation could not use the API directly.

This change adds `appID` as an alternative lookup key. When provided, the function resolves the annotation to a catalog `assetID` via a Smartscape query, then proceeds with the existing scorecard fetch. The `assetID` path is completely unchanged. The caller can also provide both — `assetID` is tried first, with `appID` as an automatic fallback on 404.

---

## What Changed

| File | Change |
|---|---|
| `src/api/scorecard-results.function.ts` | Added `buildAppIdLookupQuery` and `resolveAssetIdFromAppId`; extended `scorecardResults` ctx with `appID?`; implemented fallback control flow |
| `src/api/tests/scorecard-results.function.spec.ts` | Updated 2 existing tests (error message aligned to AC-6); added 13 new tests covering all new paths |
| `src/api/scorecard-results-user-doc.md` | Added `appID` field, lookup precedence section, `storage:smartscape:read` scope, HTTP example |
| `juno-documentation/.../fetch-api-results.md` | Same updates mirrored in the public-facing Juno docs |

---

## Acceptance Criteria

- [x] AC-1: Returns `ScorecardResult` for valid `assetID` + `version` (existing behaviour unchanged)
- [x] AC-2: Returns `ScorecardResult` when `appID` + `version` provided, resolving via Smartscape
- [x] AC-3: When both provided and `assetID` lookup succeeds, result is returned without a Smartscape call
- [x] AC-4: When both provided and `assetID` lookup returns 404, falls back to `appID` resolution
- [x] AC-5: When `appID` resolves to no Smartscape match, returns `404` naming the `appID`
- [x] AC-6: When neither `assetID` nor `appID` provided, returns `404` with `'assetID or appID is required'`
- [x] AC-7: Docs updated with `appID` field, fallback behaviour, and `storage:smartscape:read` scope
