feat(backend): update collections, config and migration tools

Update Payload CMS configuration, collections (Audit, Posts), and add migration scripts/reports.
This commit is contained in:
2026-02-11 11:50:23 +08:00
parent 8ca609a889
commit be7fc902fb
46 changed files with 5442 additions and 15 deletions

View File

@@ -0,0 +1,190 @@
# Webflow to Payload CMS Migration Script
Story 1.3: Content Migration Script
## Overview
This script migrates content from Webflow CMS to Payload CMS. It supports:
- **JSON export** - If you have Webflow JSON export files
- **HTML parsing** - If you only have access to the public website HTML
- **Manual entry** - You can manually edit the JSON data file
## Prerequisites
1. **MongoDB must be running** - The script connects to Payload CMS which requires MongoDB
2. **Environment variables** - Ensure `.env` file has PAYLOAD_SECRET and DATABASE_URI
3. **Source data** - Prepare your webflow-export.json file
## Quick Start
```bash
# Navigate to backend directory
cd apps/backend
# Ensure MongoDB is running (if using local)
# Or the Payload CMS dev server:
pnpm dev
# In another terminal, run dry-run (preview mode, no changes)
pnpm migrate:dry
# Run actual migration
pnpm migrate
# Migrate specific collection
pnpm migrate:posts
# Show help
tsx scripts/migration/migrate.ts --help
```
## Environment Setup
The script loads environment variables from:
- `.env` (project root)
- `.env.enchun-cms-v2` (project root)
- `apps/backend/.env`
Required variables:
```bash
PAYLOAD_SECRET=your-secret-key
DATABASE_URI=mongodb://localhost:27017/your-db
R2_ACCOUNT_ID=your-r2-account
R2_ACCESS_KEY_ID=your-access-key
R2_SECRET_ACCESS_KEY=your-secret-key
R2_BUCKET=your-bucket-name
```
## CLI Options
| Option | Short | Description |
|--------|-------|-------------|
| `--dry-run` | `-n` | Run without making changes (preview mode) |
| `--verbose` | `-v` | Show detailed logging output |
| `--force` | `-f` | Overwrite existing items (skip deduplication) |
| `--collection <name>` | `-c` | Specific collection: categories|posts|portfolio|all |
| `--source <path>` | `-s` | Path to export file (default: ./data/webflow-export.json) |
| `--batch-size <num>` | | Batch size for parallel processing (default: 5) |
| `--help` | `-h` | Show help message |
## Data Format
Create a `webflow-export.json` file in the `apps/backend/data/` directory:
```json
{
"categories": [
{
"name": "分類名稱(中文)",
"slug": "category-slug",
"colorHex": "#0066cc"
}
],
"posts": [
{
"title": "文章標題",
"slug": "post-slug",
"content": "<p>HTML content...</p>",
"publishedDate": "2024-01-15T10:00:00Z",
"postCategory": "category-slug",
"featuredImage": "https://example.com/image.jpg",
"seoTitle": "SEO Title",
"seoDescription": "SEO Description",
"excerpt": "Article excerpt..."
}
],
"portfolio": [
{
"name": "作品名稱",
"slug": "portfolio-slug",
"websiteLink": "https://example.com",
"previewImage": "https://example.com/preview.jpg",
"description": "作品描述",
"websiteType": "corporate",
"tags": "tag1, tag2, tag3"
}
]
}
```
## Field Mappings
### Categories
| Webflow Field | Payload Field |
|---------------|---------------|
| name | title |
| slug | slug (preserved) |
| color-hex | textColor + backgroundColor |
### Posts
| Webflow Field | Payload Field |
|---------------|---------------|
| title | title |
| slug | slug (preserved for SEO) |
| body | content (HTML → Lexical) |
| published-date | publishedAt |
| post-category | categories (relationship) |
| featured-image | heroImage (R2 upload) |
| seo-title | meta.title |
| seo-description | meta.description |
### Portfolio
| Webflow Field | Payload Field |
|---------------|---------------|
| Name | title |
| Slug | slug |
| website-link | url |
| preview-image | image (R2 upload) |
| description | description |
| website-type | websiteType |
| tags | tags (array) |
## Migration Order
1. **Categories** (first - no dependencies)
2. **Media** images (independent)
3. **Posts** (depends on Categories and Media)
4. **Portfolio** (depends on Media)
## Reports
After each migration, a report is generated in `apps/backend/reports/`:
- `migration-YYYY-MM-DD.json` - Machine-readable JSON
- `migration-YYYY-MM-DD.md` - Human-readable Markdown
## Troubleshooting
### Script fails to connect to Payload CMS
Ensure the Payload CMS server is running:
```bash
cd apps/backend
pnpm dev
```
### Images not uploading
Check environment variables in `.env`:
- `R2_ACCOUNT_ID`
- `R2_ACCESS_KEY_ID`
- `R2_SECRET_ACCESS_KEY`
- `R2_BUCKET_NAME`
### Duplicate entries
By default, the script skips existing items. Use `--force` to overwrite:
```bash
pnpm migrate --force
```
## Module Structure
```
scripts/migration/
├── migrate.ts # Main entry point
├── types.ts # TypeScript interfaces
├── utils.ts # Helper functions
├── transformers.ts # Data transformation
├── mediaHandler.ts # Image download/upload
├── deduplicator.ts # Duplicate checking
├── reporter.ts # Report generation
├── htmlParser.ts # HTML parsing (no JSON)
└── README.md # This file
```