## Context

首个 Fabric 视图样式。**权威设计在 SPACE，本文只引用不复制**：

- L1 API（命令式 `ATBannerView` + Fabric `ATBannerViewProps`）：SPACE **§4.9**
- Fabric 视图层 / ViewManager：SPACE **§8.6**、§9.5
- 原生模块与 Fabric / Event 通道：SPACE **§17.1**、§17.2
- callbackName（15 个）：Const.java `BannerCallback`（§17.3 Banner）
- props key：SPACE **§17.4.12**（Const.PlatformViewKeys）
- TurboModule（命令式桥）：SPACE **§7.4**
- **Fabric 落地参考**：`docs/RN-SDK-Fabric落地参考与待写文档.md` Part A（三层结构 A.1 / props 延迟 init A.2 / 生命周期 A.3 / V1 不做 A.4）

## Goals / Non-Goals

**Goals:**
- Android `<ATBannerViewComponent>` 内嵌进 RN 布局，mount 自动 load + 展示真实 banner（ADX 源）。
- 回调经唯一 `ATReactNativeEventEmitter`（callName `BannerCall`）→ `ATAdEvents` 按 placementID 分发；组件 `onAdEvent` 过滤本视图。
- 自动刷新（AutoRefresh 成功/失败）、生命周期（detach 停刷新 / unmount destroy）。
- L1 命令式 API 严格对齐 SPACE §4.9（load(ATAdRequest)/setShowConfig(ATShowConfig)/checkAdStatus·checkValidAdCaches→Promise/setLocalExtra·setTKExtra/entryAdScenario(tkExtra?)/destroy）。
- iOS 编译过 + 路由 log 可见。

**Non-Goals:**
- Native 自渲染（2e）；iOS 真实 Banner；`showInRectangle/showInPosition/hide/remove`；Direct/per-view 事件。

## Decisions

- **三层视图结构（照 Fabric 落地参考 A.1）**：
  1. **Fabric 容器**（`ATBannerViewManager` 创建的 React view）：只绑 props（placementID/sceneID/extraMap/isAdaptiveHeight/width/height）。
  2. **UIComponent 中间层**：持原生 `ATBannerView` + Listener；负责 attach/detach、加载、生命周期、回调转发。
  3. **原生 `ATBannerView`**：SDK 的 banner view。
- **props 延迟 init（A.2）**：props 逐个到达，**等关键 props（placementID + 尺寸）齐了再创建/加载**，避免半初始化。
- **codegen**：`codegenConfig.type` 改 `"all"`；新增 `src/specs/ATBannerViewNativeComponent.ts`（`codegenNativeComponent`，props 见 §17.4.12 + width/height + onAdEvent direct event 占位）。命令式桥方法（loadBannerAd 等）仍在 `NativeATBridge.ts`。
- **事件 V1 走统一通道**：Banner 回调经 `ATReactNativeEventEmitter`(BannerCall) → `ATAdEvents`。组件订阅 `ATAdEvents.setAdListener(placementID, ...)`，把本 placementID 的事件回调到 `onAdEvent` prop。**不引 per-view Direct Event**（仅"同 placement 多视图实例"才需要，V1 不做；记 future-note）。
- **生命周期（A.3，Banner 必做）**：`onDetachedFromWindow → ATBannerView.setAutoRefreshEnabled(false)`（停刷新省流量）；组件 unmount / `destroy()` → `ATBannerView.destroy()` + 移除 view + `ATAdEvents.removeAdListener`。**detach（停刷新）≠ destroy（销毁），分开**。
- **移植**：Flutter `ATAdBannerManger→ATBannerManager`（命令式路由 + `ConcurrentHashMap<pid, Helper>`）、`ATBannerHelper`（持 ATBannerView + Listener，emit BannerCall）、`ATBannerViewFactory/ATAndroidBannerView → ATBannerViewManager + view`。沿用三类已对齐：load 解析 atAdRequest、setLocalExtra/setTKExtra lazy-cache、checkAdStatus/checkValidAdCaches→Promise、scenarioId key。
- **iOS stub**：banner ViewManager + view 空实现 + NSLog；真实留 iOS 同事。

## Risks / Trade-offs

- [首次接 Fabric，codegen type=all 后双端生成视图桩] → 严格按 RN New Arch Fabric 组件规范（codegenNativeComponent + ViewManager）；编译/codegen 报错按 RN 文档 + 现有 TurboModule 经验修（用户本机编译反馈）。
- [Banner API 是否在 core] → 应在 core-taku:6.5.73.3（同 reward，grep 因混淆显示 0）；apply 编译确认，缺则加 `banner-taku:6.5.40`。
- [props 时序/半初始化] → A.2 延迟 init：关键 props 齐才加载。
- [刷新定时器泄漏] → A.3 detach 停刷新 + destroy 彻底销毁，双保险。
- [验收 callbackName 简写] → 以 Const.java 为准（load 失败 `bannerAdFailToLoadAD`、关闭 `bannerAdTapCloseButton`）。
- [tasks 偏粗] → 本 Phase 复杂，propose 后建议用 **writing-plans 技能**把三层结构 / 双端 ViewManager / props 时序细化，回填 tasks 再 apply。
