Include supplementary documentation, research notes on Lexical/UX, and setup guides.
13 KiB
13 KiB
4. Technical Constraints and Integration Requirements
Last Updated: 2025-01-29
This section defines how the migration integrates with the existing architecture and technical constraints.
Existing Technology Stack
Target System Architecture
Languages:
- TypeScript 5.x (strict mode enabled)
Frameworks:
- Frontend: Astro 6.0.x (SSR mode + Cloudflare native runtime)
- Backend/CMS: Payload CMS 3.x
- UI Components: React (for interactive components via @astrojs/react integration)
Database:
- Development: Local MongoDB or SQLite
- Production: MongoDB (Atlas or self-hosted)
- Option: PostgreSQL support available (via @payloadcms/db-postgres)
Infrastructure:
- Hosting: Cloudflare Pages (frontend)
- Serverless: Cloudflare Workers (backend API)
- Storage: Cloudflare R2 (media files)
- DNS: Cloudflare (existing)
- CDN: Cloudflare global network + native runtime
External Dependencies:
- Authentication: Payload CMS built-in authentication ✅
- Form Processing: Cloudflare Workers (contact form)
- Analytics: Google Analytics (G-DKBZWCGGZR)
- Fonts: Google Fonts (Noto Sans TC, Quicksand)
- Icons: Google Material Icons
Development Tools:
- Package Manager: pnpm 10.x (workspace)
- Build Tool: Turborepo 2.x (monorepo management)
- Code Quality: ESLint, Prettier
- Testing: Vitest (unit tests), Playwright (E2E)
- Version Control: Git
Integration Approach
Database Integration Strategy
Payload CMS Collection Design
// Users Collection (with built-in authentication)
{
email: string;
role: 'admin' | 'editor';
name?: string;
createdAt: Date;
}
// Posts Collection (migrated from "行銷放大鏡集")
{
title: string; // 文章標題
slug: string; // URL slug
excerpt?: string; // 文章簡述
content: richText; // 發文內容
category: relation; // 文章分類 (link to Categories)
publishedDate: Date; // 發文日期
featuredImage: media; // 強調圖片
ogImage?: media; // Open Graph 顯示圖片
showInFooter: boolean; // 是否放在頁尾
status: 'draft' | 'published';
}
// Categories Collection (migrated from "文章分類s")
{
name: string; // 分類名稱
slug: string; // URL slug
nameEn?: string; // 英文分類名稱
order: number; // 順序
textColor: string; // 文字顏色
backgroundColor: string; // 分類顏色
parent?: relation; // Support nested categories (optional)
}
// Portfolio Collection (migrated from "網站設計範本s")
{
title: string; // project
slug: string; // Slug
url?: string; // External link
image: media; // 圖片
description?: string; // description
websiteType: string; // 網站類型
tags?: string[]; // 標籤 (e.g., "一頁式銷售", "客戶預約")
}
// Media Collection
{
alt?: string;
caption?: string;
url: string; // R2 URL
filename: string;
mimeType: string;
filesize: number;
width?: number;
height?: number;
}
Content Migration Strategy
Phase 1: Webflow Export
- Export Webflow CMS as JSON/CSV
- Export all media files
- Document field mappings
Phase 2: Build Migration Script
// migration-script.ts
// 1. Parse Webflow export data
// 2. Transform to Payload CMS API format
// 3. Batch upload to Payload CMS
// 4. Preserve original slugs and URL structure
Phase 3: Media Migration
- Download all images/documents
- Upload to Cloudflare R2
- Update references in Payload CMS
API Integration Strategy
Astro → Payload CMS
// Fetch data from Payload API
const API_URL = import.meta.env.PAYLOAD_CMS_URL;
const API_KEY = import.meta.env.PAYLOAD_CMS_API_KEY;
async function getPosts() {
const response = await fetch(`${API_URL}/api/posts?depth=1`, {
headers: { 'Authorization': `users ${API_KEY}` }
});
return response.json();
}
Astro → Payload Authentication
// Verify Payload CMS session in Astro
// Payload sets HTTP-only cookies, Astro reads them
export async function middleware({ request, locals }) {
const user = await verifyPayloadSession(request.headers.get('cookie'));
locals.user = user;
}
Frontend Integration Strategy
Component Architecture
apps/frontend/src/
├── components/
│ ├── common/ # Shared components
│ │ ├── Header.astro
│ │ ├── Footer.astro
│ │ └── CTAButton.astro
│ ├── layout/ # Layout components
│ │ ├── MainLayout.astro
│ │ └── AdminLayout.astro
│ └── sections/ # Page sections
│ ├── Hero.astro
│ ├── FeatureCards.astro
│ └── ComparisonTable.astro
├── layouts/
│ ├── BaseLayout.astro
│ └── EmptyLayout.astro
├── pages/
│ ├── index.astro
│ ├── about.astro
│ ├── solutions.astro
│ ├── blog/
│ │ ├── index.astro
│ │ └── [slug].astro
│ └── admin/
│ ├── login.astro
│ └── dashboard.astro
└── lib/
├── payload.ts # Payload API client
├── auth.ts # Auth helpers
└── utils.ts # Utility functions
Styling Integration
Tailwind CSS Configuration:
// tailwind.config.js
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['Noto Sans TC', 'sans-serif'],
display: ['Quicksand', 'sans-serif'],
},
colors: {
// Extract brand colors from Webflow CSS
brand: { /* ... */ }
}
}
}
}
Testing Integration Strategy
Unit Tests:
- Utility functions
- Payload CMS hooks
- API route handlers
E2E Tests:
- Critical user journeys:
- Home → About → Contact
- Blog list → Article detail
- Login → Edit content
- Form submissions
- Authentication flows
Code Organization and Standards
File Structure Approach
Monorepo Structure:
website-enchun-mgr/
├── apps/
│ ├── backend/ # Payload CMS
│ │ ├── src/
│ │ │ ├── collections/
│ │ │ ├── globals/
│ │ │ ├── payload.config.ts
│ │ │ └── server.ts # Cloudflare Workers entry
│ │ └── package.json
│ └── frontend/ # Astro
│ ├── src/
│ │ ├── components/
│ │ ├── layouts/
│ │ ├── pages/
│ │ └── styles/
│ ├── astro.config.mjs
│ └── package.json
├── packages/
│ └── shared/ # Shared TypeScript utilities
│ ├── src/
│ │ ├── types/
│ │ ├── utils/
│ │ └── constants/
│ └── package.json
├── pnpm-workspace.yaml
├── turbo.json
└── package.json
Naming Conventions
Files/Folders:
- Components:
PascalCase(Header.astro,FeatureCards.astro) - Pages:
kebab-case(about.astro,marketing-solutions.astro) - Utils:
camelCase(formatDate.ts,slugify.ts) - Constants:
UPPER_SNAKE_CASE(API_URL.ts,BREAKPOINTS.ts) - Types:
PascalCase(Post.ts,User.ts)
Code Naming:
- Variables/Functions:
camelCase - Classes/Interfaces/Types:
PascalCase - Private vars:
camelCasewith_prefix (_internalFunction) - Booleans:
is/has/shouldprefix (isLoading,hasError)
Coding Standards
TypeScript Configuration:
{
"compilerOptions": {
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}
ESLint Rules:
@typescript-eslint/recommendedastro/recommended- Custom rules:
- Max line length: 100
- No console.log in production
- Require explicit return types
Import Order:
// 1. External dependencies
import React from 'react';
// 2. Internal shared
import { formatDate } from '@repo/shared/utils';
// 3. Components
import { Header } from '@/components/common/Header.astro';
// 4. Styles
import '@/styles/global.css';
Documentation Standards
- All components must have JSDoc comments
- Complex functions must explain purpose, parameters, return values
- Payload CMS collections must have field descriptions
Deployment and Operations
Build Process Integration
Turborepo Scripts:
{
"scripts": {
"dev": "turbo run dev --parallel",
"build": "turbo run build",
"lint": "turbo run lint",
"test": "turbo run test"
}
}
Build Flow:
-
Frontend Build:
cd apps/frontend pnpm build # Output: dist/ -
Backend Build:
cd apps/backend pnpm build # Output: .next/ or build/
Deployment Strategy
Cloudflare Pages Configuration:
# wrangler.toml
name = "enchun-frontend"
compatibility_date = "2024-01-01"
[env.production]
routes = [
{ pattern = "/api/*", zone_name = "enchuntw-admin.anlstudio.cc" }
]
CI/CD Pipeline:
- Push to
mainbranch → Auto-trigger deployment - Run tests → Stop deployment if failed
- Build → Generate optimized production version
- Deploy to Cloudflare Pages
Environment Variables:
# .env.production
PAYLOAD_CMS_URL=https://enchuntw-admin.anlstudio.cc
PAYLOAD_CMS_API_KEY=your-production-key
DATABASE_URI=mongodb+srv://...
R2_ACCOUNT_ID=your-account-id
R2_ACCESS_KEY_ID=your-access-key
R2_SECRET_ACCESS_KEY=your-secret-key
Domain and DNS:
www.enchun.tw→ Cloudflare Pagesenchuntw-admin.anlstudio.cc→ Payload CMS admin
Monitoring and Logging
Cloudflare Analytics:
- Page views
- Response times
- Error rates
- Geographic distribution
Logging Strategy:
// Unified logging format
import { logger } from '@/lib/logger';
logger.info('User login', { userId, timestamp });
logger.error('API request failed', { endpoint, error });
Error Tracking:
- Sentry or Cloudflare Web Analytics
- Capture frontend errors
- Track API failures
Configuration Management
Environment Variables:
.env.local- Local development.env.production- Production- All sensitive data in environment variables
Secret Management:
- Cloudflare Secrets (Workers)
- GitHub Secrets (CI/CD)
- Never commit .env files to Git
Risk Assessment and Mitigation
Technical Risks
| Risk | Impact | Probability | Mitigation |
|---|---|---|---|
| Payload CMS collection design doesn't match Webflow | High | Medium | Carefully analyze Webflow CMS structure, create complete field mapping table |
| Content migration data loss | High | Medium | Build migration validation scripts, compare source and target data |
| SEO traffic drop | High | Medium | Implement complete 301 redirects, monitor Google Analytics |
| Performance below target (Lighthouse < 95) | Medium | Low | Use WebPageTest and Lighthouse CI for continuous monitoring |
| Cloudflare Workers limits | Medium | Low | Optimize bundle size, split using edge functions |
| Payload auth security vulnerabilities | High | Low | Use tested Payload built-in auth, regular security audits |
| R2 storage cost over budget | Medium | Low | Implement image compression and lazy loading strategies |
Integration Risks
| Risk | Impact | Probability | Mitigation |
|---|---|---|---|
| Astro SSR + Payload API integration issues | High | Medium | Build dedicated API client layer, implement error handling and retry logic |
| Monorepo dependency management conflicts | Medium | Medium | Use pnpm workspace strict version control, regular dependency updates |
| Tailwind CSS vs Webflow style differences | Medium | High | Extract Webflow CSS to Tailwind config, verify with Storybook |
| Responsive design breakpoint mismatches | Medium | Low | Use same breakpoint definitions, test all device sizes |
| Font loading causing FOUT/FOIT | Low | Medium | Use font-display: swap, preload critical fonts |
Deployment Risks
| Risk | Impact | Probability | Mitigation |
|---|---|---|---|
| Deployment downtime affects SEO | Medium | Low | Use zero-downtime deployment, test staging environment first |
| Environment variable configuration errors | High | Low | Use CI/CD to validate environment variables, implement config checklist |
| R2 image loading failures | High | Medium | Implement CDN fallback mechanism, monitor R2 availability |
| DNS switch delays | Low | Low | Configure DNS in advance, gradually migrate traffic |
Next Section: Epic and Story Structure