# Recently Viewed 模組使用指南

> ⚠️ **內部使用套件** - 此套件僅供 Astral Web 內部使用，未經授權不得用於其他用途。

## 概覽

Recently Viewed 是一個 Nuxt 3 模組，提供完整的最近瀏覽商品追蹤與管理功能。模組採用 Nuxt Module 架構設計，支援本地儲存與伺服器同步、訪客與會員資料自動合併，並提供靈活的配置選項。

## 安裝與設定

### 1. 安裝套件

#### 在 apps/web 和 apps/server 安裝

```bash
yarn add @astralweb/nova-recently-viewed
```

### 2. Middleware 擴充

```typescript
// apps/server/extendApiMethods/index.ts

export {
  recentlyViewedProducts,
  addRecentlyViewedProducts,
} from '@astralweb/nova-recently-viewed/api';
```

### 3. 註冊模組

```typescript
// apps/web/nuxt.config.ts

export default defineNuxtConfig({
  modules: [
    '@astralweb/nova-recently-viewed',
  ],
})
```

## 架構設計

### 三層架構

1. **API Layer** (`useRecentlyViewedApi`)
   - 處理與 GraphQL 後端的通信
   - 提供 `syncToServer` 和 `fetchFromServer` 方法

2. **Storage Layer** (`useRecentlyViewedStorage`)
   - 管理本地儲存與核心業務邏輯
   - 處理訪客/會員資料合併
   - 提供完整的 CRUD 操作

3. **List Layer** (`useRecentlyViewedList`)
   - 高階封裝，適用於產品詳情頁
   - 自動處理初始化、登入狀態變化、SKU 更新
   - 提供開箱即用的體驗

## 使用方式

適合產品詳情頁，自動處理所有邏輯。

```vue
<template>
  <ProductSlider :products-sku="recentlyViewedSkus" />
</template>

<script setup lang="ts">
const { recentlyViewedSkus } = useRecentlyViewedList({
  currentSku: computed(() => product.value?.sku ?? ''),
  isLoggedIn: computed(() => !!user.value),
  enableServerSync: true,
});
</script>
```

**自動處理：**
- ✅ 組件掛載時初始化
- ✅ SKU 變化時更新列表
- ✅ 登入狀態變化時合併資料
- ✅ 本地緩存優化


## API 參考

### useRecentlyViewedList

```typescript
const { recentlyViewedSkus } = useRecentlyViewedList({
  currentSku: Ref<string> | ComputedRef<string>,
  isLoggedIn: ComputedRef<boolean>,
  maxItems?: number,              // 預設：20
  guestStorageKey?: string,       // 預設：'recently-viewed-guest'
  customerStorageKey?: string,    // 預設：'recently-viewed-customer'
  enableServerSync?: boolean,     // 預設：true
  autoInit?: boolean,             // 預設：true
});
```

**返回值：**
- `recentlyViewedSkus`: `Ref<string[]>` - 最近瀏覽商品的 SKU 列表

### useRecentlyViewedStorage

核心 composable，提供完整的儲存管理功能。

```typescript
const {
  addRecentlyViewed,
  getRecentlyViewedSkus,
  getSkusFromLocalStorage,
  clearAllRecentlyViewed,
  mergeGuestToCustomer,
  isLoggedIn,
} = useRecentlyViewedStorage(config, isLoggedIn);
```

**配置選項：**
```typescript
interface RecentlyViewedConfig {
  maxItems?: number;              // 最多儲存數量（預設：20）
  guestStorageKey?: string;       // 訪客 localStorage key
  customerStorageKey?: string;    // 會員 localStorage key
  enableServerSync?: boolean;     // 啟用伺服器同步（預設：true）
}
```

**方法：**
- `addRecentlyViewed(sku: string): Promise<void>` - 添加商品到最近瀏覽
- `getRecentlyViewedSkus(excludeSku?: string): Promise<string[]>` - 獲取 SKU 列表（伺服器優先）
- `getSkusFromLocalStorage(excludeSku?: string): string[]` - 從本地儲存獲取 SKU 列表
- `clearAllRecentlyViewed(): void` - 清除所有記錄
- `mergeGuestToCustomer(): Promise<void>` - 合併訪客資料到會員帳戶

### useRecentlyViewedApi

API 層 composable，處理與後端的通信。

```typescript
const {
  syncToServer,
  fetchFromServer,
} = useRecentlyViewedApi();
```

**方法：**
- `syncToServer(input: AddRecentlyViewedInputItem[]): Promise<void>` - 同步資料到伺服器
- `fetchFromServer(): Promise<AddRecentlyViewedInputItem[]>` - 從伺服器獲取資料

## 工作原理

### 訪客模式

- 資料保存在 `localStorage`（key: `recently-viewed-guest`）
- 不進行伺服器同步
- 本地去重與數量限制

### 登入模式

- 主要資料來源：伺服器
- 本地緩存：加速 UI 更新
- 新增時：同步到伺服器 → 更新本地緩存

### 登入時資料合併

1. 讀取訪客 `localStorage` 資料
2. 同步到伺服器（合併到會員帳戶）
3. 清除訪客資料
4. 從伺服器獲取最新資料

## 授權

此套件僅供 Astral Web 內部使用，未經授權不得用於其他用途。
