# 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

```typescript
// 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**
1. Export Webflow CMS as JSON/CSV
2. Export all media files
3. Document field mappings

**Phase 2: Build Migration Script**
```typescript
// 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**
1. Download all images/documents
2. Upload to Cloudflare R2
3. Update references in Payload CMS

---

### API Integration Strategy

#### Astro → Payload CMS

```typescript
// 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

```typescript
// 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:**
```javascript
// 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: `camelCase` with `_` prefix (`_internalFunction`)
- Booleans: `is/has/should` prefix (`isLoading`, `hasError`)

### Coding Standards

**TypeScript Configuration:**
```json
{
  "compilerOptions": {
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  }
}
```

**ESLint Rules:**
- `@typescript-eslint/recommended`
- `astro/recommended`
- Custom rules:
  - Max line length: 100
  - No console.log in production
  - Require explicit return types

**Import Order:**
```typescript
// 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:**
```json
{
  "scripts": {
    "dev": "turbo run dev --parallel",
    "build": "turbo run build",
    "lint": "turbo run lint",
    "test": "turbo run test"
  }
}
```

**Build Flow:**
1. **Frontend Build:**
   ```bash
   cd apps/frontend
   pnpm build
   # Output: dist/
   ```

2. **Backend Build:**
   ```bash
   cd apps/backend
   pnpm build
   # Output: .next/ or build/
   ```

### Deployment Strategy

**Cloudflare Pages Configuration:**
```toml
# wrangler.toml
name = "enchun-frontend"
compatibility_date = "2024-01-01"

[env.production]
routes = [
  { pattern = "/api/*", zone_name = "enchuntw-admin.anlstudio.cc" }
]
```

**CI/CD Pipeline:**
1. Push to `main` branch → Auto-trigger deployment
2. Run tests → Stop deployment if failed
3. Build → Generate optimized production version
4. Deploy to Cloudflare Pages

**Environment Variables:**
```bash
# .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 Pages
- `enchuntw-admin.anlstudio.cc` → Payload CMS admin

### Monitoring and Logging

**Cloudflare Analytics:**
- Page views
- Response times
- Error rates
- Geographic distribution

**Logging Strategy:**
```typescript
// 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](./05-epic-stories.md)
