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:
190
apps/backend/scripts/migration/README.md
Normal file
190
apps/backend/scripts/migration/README.md
Normal 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
|
||||
```
|
||||
Reference in New Issue
Block a user