# Node Agent 设计文档

> **定位**: Win Node Agent - 无 API 平台执行代理  
> **更新日期**: 2026-03-20  
> **最高优先级参考**: [Business_ClosedLoops.md](../00_Business/Business_ClosedLoops.md)

---

## 1. 概述

### 1.1 背景

Extension (浏览器插件) 方案存在以下局限性：
- Manifest V3 权限限制
- 反检测能力不足
- 无法多实例并发
- 任务调度不可靠

**Node Agent** 基于 Playwright 构建，提供更强大的自动化能力。

### 1.2 核心能力

| 能力 | 说明 |
|------|------|
| **无 API 平台采集** | TikTok Shop, Temu, 1688 等 |
| **自动化操作** | 刊登、订单处理、广告投放 |
| **反检测** | 指纹隔离、代理 IP、浏览器上下文隔离 |
| **多实例并发** | 支持多店铺同时运行 |

---

## 2. 技术栈

| 层级 | 技术 | 版本 | 用途 |
|------|------|------|------|
| **Runtime** | Node.js | 18+ | 运行环境 |
| **Automation** | Playwright | 1.58+ | 浏览器自动化 |
| **Language** | TypeScript | 5.x | 开发语言 |
| **Communication** | Axios | - | HTTP 通信 |

---

## 3. 架构设计

### 3.1 系统架构

```
┌─────────────────────────────────────────────────────────────┐
│                        Crawlful Hub                         │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────────┐     ┌──────────────┐     ┌──────────────┐ │
│  │   Server     │     │     Hub      │     │  Dashboard   │ │
│  │  (业务逻辑)   │◄───►│  (任务调度)   │◄───►│   (控制台)    │ │
│  └──────────────┘     └──────┬───────┘     └──────────────┘ │
│                              │                              │
│                              ▼                              │
│                    ┌──────────────────┐                     │
│                    │   Node Agent     │                     │
│                    │   (Playwright)   │                     │
│                    └────────┬─────────┘                     │
│                             │                               │
│         ┌───────────────────┼───────────────────┐          │
│         ▼                   ▼                   ▼          │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐   │
│  │  Browser #1  │   │  Browser #2  │   │  Browser #N  │   │
│  │  (店铺A)      │   │  (店铺B)      │   │  (店铺N)      │   │
│  └──────────────┘   └──────────────┘   └──────────────┘   │
│                                                              │
└─────────────────────────────────────────────────────────────┘
```

### 3.2 核心类设计

```typescript
export class NodeAgent {
  private hubUrl: string;
  private nodeId: string;
  private heartbeatInterval: number = 30000;
  private pollInterval: number = 10000;

  async start(): Promise<void>;
  async register(): Promise<void>;
  async heartbeat(): Promise<void>;
  async pollTasks(): Promise<void>;
  async executeTask(task: NodeTask): Promise<void>;
  async reportReceipt(receipt: any): Promise<void>;
}
```

### 3.3 任务类型

```typescript
export enum TaskType {
  COLLECT_PRODUCT = 'COLLECT_PRODUCT',
  COLLECT_ORDER = 'COLLECT_ORDER',
  PUBLISH_PRODUCT = 'PUBLISH_PRODUCT',
  PROCESS_ORDER = 'PROCESS_ORDER',
  SYNC_INVENTORY = 'SYNC_INVENTORY',
  MANAGE_AD = 'MANAGE_AD',
}
```

---

## 4. 核心功能

### 4.1 节点注册

```typescript
private async register() {
  await axios.post(`${this.hubUrl}/api/v1/nodes/register`, {
    nodeId: this.nodeId,
    version: '1.0.0',
    os: os.type(),
    hostname: os.hostname(),
    shops: []
  });
}
```

### 4.2 任务轮询

```typescript
private async pollTasks() {
  const response = await axios.get(
    `${this.hubUrl}/api/v1/nodes/pull-task?nodeId=${this.nodeId}`
  );
  
  if (response.data?.task) {
    await this.executeTask(response.data.task);
  }
}
```

### 4.3 任务执行

```typescript
private async executeTask(task: NodeTask) {
  try {
    const browser = await chromium.launch({
      headless: false,
      proxy: { server: task.proxyUrl }
    });
    
    const context = await browser.newContext({
      viewport: { width: 1920, height: 1080 }
    });
    
    const page = await context.newPage();
    
    // 执行具体任务...
    
    await browser.close();
    
    await this.reportReceipt({
      taskId: task.id,
      traceId: task.traceId,
      status: 'success',
      resultData: {}
    });
  } catch (err) {
    await this.reportReceipt({
      taskId: task.id,
      traceId: task.traceId,
      status: 'failed',
      errorMessage: err.message
    });
  }
}
```

---

## 5. 店铺隔离策略

### 5.1 一店一上下文

```typescript
interface ShopContext {
  shopId: string;
  profileDir: string;
  proxy: ProxyConfig;
  fingerprintPolicy: FingerprintConfig;
}
```

### 5.2 同店任务串行

```typescript
class TaskQueue {
  private queues: Map<string, TaskQueue> = new Map();
  
  async addTask(shopId: string, task: Task) {
    if (!this.queues.has(shopId)) {
      this.queues.set(shopId, new TaskQueue());
    }
    await this.queues.get(shopId).add(task);
  }
}
```

---

## 6. 反检测策略

| 策略 | 说明 |
|------|------|
| **指纹隔离** | 每个店铺独立浏览器指纹 |
| **代理 IP** | 每个店铺独立代理 |
| **行为模拟** | 随机延迟、鼠标轨迹 |
| **User-Agent** | 随机 UA 轮换 |

---

## 7. 目录结构

```
node-agent/
├── src/
│   ├── main.ts              # 入口
│   ├── index.ts             # NodeAgent 类
│   ├── tasks/               # 任务处理器
│   │   ├── collectProduct.ts
│   │   ├── publishProduct.ts
│   │   └── processOrder.ts
│   ├── platforms/           # 平台适配器
│   │   ├── tiktok.ts
│   │   ├── temu.ts
│   │   └── ali1688.ts
│   └── utils/               # 工具函数
│       ├── logger.ts
│       └── fingerprint.ts
├── package.json
└── tsconfig.json
```

---

## 8. 配置

```typescript
interface AgentConfig {
  hubUrl: string;
  nodeId: string;
  heartbeatInterval: number;
  pollInterval: number;
  maxConcurrentBrowsers: number;
  proxyPool: ProxyConfig[];
}
```

---

## 9. 相关文档

- [DOM Interaction](02_DOM_Interaction.md)
- [Backend Design](../02_Backend/Backend_Design.md)
- [Business ClosedLoops](../00_Business/Business_ClosedLoops.md)

---

*本文档基于业务闭环设计，最后更新: 2026-03-20*
