404 Not Found

404 Not Found


nginx

Project Design

We have now completed all the material for Phases 1-4. Charlie will now integrate all this knowledge to design a complete MegaShop e-commerce platform. From requirements analysis to architectural design, and from data models to API specifications, this is the first step in the hands-on project.

1. What You'll Learn


2. A True Story of an Architect

(1) Pain Point: Development Without Design

Charlie had previously instructed the team to start writing code right away without any design documentation. As a result, Alice's shopping cart data structure didn't match Bob's order data, API naming was chaotic, the database lacked indexes, queries were slow, and the cost of making changes later on was enormous.

(2) System Design Solutions

Design First, Then Develop—Use ER diagrams to define the data model, RESTful specifications to define the API, and architecture diagrams to define the system boundaries. Spend an extra week on the design phase, and save three weeks during development.

(3) Benefits: A Clear Roadmap

When every developer refers to the same design document—with consistent data structures, unified API specifications, and clear architectural boundaries—collaboration efficiency increases threefold.


3. Requirements Analysis

(1) User Roles and Core Needs

Role Identity Core Needs Key Metrics
Alice Consumer Browse/Search/Add to Cart/Checkout/Review First Screen < 2s, Search < 500ms
Bob Administrator Product Management/Order Processing/User Management CRUD response < 200 ms
Charlie Architect System Stability/High Performance/Scalability 99.9% availability, supports 1 million products

(2) Functional Module Division

Module Function Priority Affected Pages
Authentication Sign Up/Sign In/OAuth2/JWT P0 /login, /register
Product CRUD/Search/Categories/Filters P0 /products, /products/[id]
Shopping Cart Add to Cart/Change Quantity/Remove/Clear P0 /cart
Order Create/Pay/Check Status P0 /checkout, /orders
User Personal Information/Address/Reviews P1 /profile
Administration Backend CRUD/Statistics/Moderation P1 /admin/**
Internationalization Chinese/English/Japanese + Multiple Currencies P1 Global
SEO Dynamic meta/Sitemap/JSON-LD P0 Product Page

4. Architecture Design

(1) Overview of the MegaShop System Architecture

100%
graph TB
    subgraph Client["Client Layer"]
        Browser[Browser / Mobile]
        Bot[Search Engine Bot]
    end

    subgraph CDN["CDN Layer"]
        CF[Cloudflare / Vercel Edge]
    end

    subgraph Nuxt["Nuxt 3 Application"]
        SSR[SSR Engine]
        ISR[ISR Cache]
        API[Nitro API Routes]
        MW[Middleware / Auth]
    end

    subgraph Data["Data Layer"]
        PG[(PostgreSQL)]
        Redis[(Redis Cache)]
        S3[Object Storage / Images]
    end

    subgraph External["External Services"]
        Stripe[Stripe Payment]
        Google[Google OAuth2]
        Analytics[Analytics Service]
    end

    Browser --> CDN
    Bot --> CDN
    CDN --> SSR
    CDN --> ISR
    SSR --> API
    API --> MW
    API --> PG
    API --> Redis
    API --> S3
    API --> Stripe
    API --> Google
    API --> Analytics
    ISR --> Redis

(2) Rendering Strategy Design

Page Type Rendering Mode swr Reason
Home SSG - Stable Content
Product List ISR 3600s Updated hourly
Product Details ISR 86400s Updated Daily
Search Results SSR - Real-time Query
Cart/Checkout CSR - For Members Only
Admin Dashboard CSR - No SEO Required
API Routing Dynamic - On-Demand Caching

(3) Selecting a Technology Stack

(1) ▶ Example: nuxt.config.ts Technology Stack Integration

TYPESCRIPT
// nuxt.config.ts - Full tech stack integration
export default defineNuxtConfig({
  ssr: true,
  modules: [
    '@pinia/nuxt',
    '@nuxtjs/tailwindcss',
    '@nuxtjs/i18n',
    '@nuxtjs/sitemap',
    '@nuxt/image',
    '~/modules/analytics'
  ],
  i18n: {
    locales: [
      { code: 'en', name: 'English', file: 'en.json', currency: 'USD' },
      { code: 'zh', name: 'Chinese', file: 'zh.json', currency: 'CNY' },
      { code: 'ja', name: 'Japanese', file: 'ja.json', currency: 'JPY' }
    ],
    defaultLocale: 'en',
    lazy: true,
    langDir: 'locales/'
  },
  image: { quality: 80, format: ['webp', 'avif'] }
})

Output:

TEXT
// Execution Successful

(2) ▶ Example: Docker Compose Service Orchestration

YAML
# docker-compose.yml - Infrastructure definition
services:
  web:
    build: .
    ports: ["3000:3000"]
    depends_on: [db, redis]
  db:
    image: postgres:16-alpine
    volumes: [postgres_data:/var/lib/postgresql/data]
  redis:
    image: redis:7-alpine
    volumes: [redis_data:/data]
  nginx:
    image: nginx:alpine
    ports: ["80:80", "443:443"]
    depends_on: [web]

Output:

TEXT
CONTAINER ID   IMAGE          STATUS         PORTS
abc123         nginx:latest   Up 2 hours     0.0.0.0:80->80/tcp
Level Technology Reason for Selection
Framework Nuxt 3 SSR/ISR/CSR Hybrid Rendering
UI Vue 3 + TailwindCSS Reactive + Rapid Development
State Management Pinia Official Vue 3 Solution + SSR Support
Database PostgreSQL + Prisma Type-safe ORM + Millions of Queries
Caching Redis + Nitro KV API Caching + ISR Storage
Authentication JWT + OAuth2 Stateless + Social Login
Internationalization @nuxtjs/i18n Multilingual + SEO hreflang
Image @nuxt/image WebP/AVIF + Responsive
Testing Vitest + Playwright Unit + E2E
Deployment Docker Compose Full-Stack Service Orchestration
CI/CD GitHub Actions Automated Pipelines

5. Data Model Design

(1) ER Diagram

100%
erDiagram
    User ||--o{ Order : "places"
    User ||--o{ Review : "writes"
    User ||--o{ CartItem : "has"
    User ||--o{ Address : "owns"
    Product ||--o{ OrderItem : "included in"
    Product ||--o{ CartItem : "added to"
    Product ||--o{ Review : "receives"
    Product ||--o{ ProductImage : "has"
    Product }o--|| Category : "belongs to"
    Category ||--o{ Category : "parent-child"
    Order ||--o{ OrderItem : "contains"
    Order }o--|| Address : "ships to"

(2) Core Table Design

(1) ▶ Example: Core Prisma Schema

PRISMA
// Key models from prisma/schema.prisma
model Product {
  id          Int       @id @default(autoincrement())
  name        String
  slug        String    @unique
  price       Decimal   @db.Decimal(10, 2)
  inStock     Boolean   @default(true)
  categoryId  Int
  category    Category  @relation(fields: [categoryId], references: [id])
  orderItems  OrderItem[]
  cartItems   CartItem[]
  @@index([categoryId])
  @@index([price])
}

model Order {
  id        Int       @id @default(autoincrement())
  userId    Int
  user      User      @relation(fields: [userId], references: [id])
  total     Decimal   @db.Decimal(10, 2)
  status    OrderStatus @default(PENDING)
  items     OrderItem[]
  @@index([userId])
  @@index([status])
}

Output:

TEXT
// Execution Successful

(2) ▶ Example: API Error Code Definitions

TYPESCRIPT
// server/utils/errors.ts
export const ErrorCodes = {
  VALIDATION_ERROR: { statusCode: 400, message: 'Validation error' },
  AUTH_REQUIRED: { statusCode: 401, message: 'Authentication required' },
  TOKEN_EXPIRED: { statusCode: 401, message: 'Token expired' },
  FORBIDDEN: { statusCode: 403, message: 'Insufficient permissions' },
  NOT_FOUND: { statusCode: 404, message: 'Resource not found' },
  CONFLICT: { statusCode: 409, message: 'Resource conflict' },
  RATE_LIMITED: { statusCode: 429, message: 'Too many requests' }
} as const

export function throwError(code: keyof typeof ErrorCodes, details?: any) {
  const err = ErrorCodes[code]
  throw createError({ statusCode: err.statusCode, message: err.message, data: { errorCode: code, details } })
}

Output:

TEXT
// Execution Successful

(3) ▶ Example: Standard API Response Format

TYPESCRIPT
// server/utils/response.ts
export function successResponse(data: any, message = 'Success') {
  return { data, message, timestamp: Date.now() }
}

export function listResponse(items: any[], total: number, page: number, limit: number) {
  return { items, total, page, limit, timestamp: Date.now() }
}

export function errorResponse(statusCode: number, errorCode: string, message: string, details?: any) {
  return { statusCode, errorCode, message, details, timestamp: Date.now() }
}

Output:

TEXT
// Execution Successful

(4) ▶ Example: routeRules rendering strategy configuration

TYPESCRIPT
// nuxt.config.ts - Route-level rendering strategy
routeRules: {
  '/': { prerender: true },
  '/products': { swr: 3600 },
  '/products/**': { swr: 86400 },
  '/admin/**': { ssr: false },
  '/cart': { ssr: false },
  '/api/**': { cors: true },
  '/_nuxt/**': { headers: { 'cache-control': 'public, max-age=31536000, immutable' } }
}

Output:

TEXT
// Execution Successful

(5) ▶ Example: CI/CD Pipeline Structure

YAML
# .github/workflows/ci.yml - Core pipeline
name: CI
on: [push, pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps: [{ uses: actions/checkout@v4 }, { run: npm ci }, { run: npm run lint }]
  test:
    needs: lint
    steps: [{ run: npm run test:coverage }]
  build:
    needs: test
    steps: [{ run: npm run build }]

Output:

TEXT
CI/CD pipeline loaded
Pipeline status: passed
Tests: 12 passed, 0 failed
Table Number of Fields Primary Index Estimated Data Volume
Product 12 slug, categoryId, price 1 million
Category 6 slug, parentId 500
User 10 email, role 500,000
Order 8 userId, status, createdAt 1 million
OrderItem 6 orderId, productId 5 million
CartItem 5 userId+productId (unique) 100,000
Review 7 productId, userId 2 million
Address 8 userId 500 thousand

6. API Specifications

(1) RESTful API Design

Method Path Description Authentication
GET /api/products Product List (Pagination/Filtering) None
GET /api/products/:id Product Details None
POST /api/products Create Product Admin
PUT /api/products/:id Update Product Admin
DELETE /api/products/:id Delete Product Admin
GET /api/categories Category List None
POST /api/auth/register Register None
POST /api/auth/login Login None
POST /api/auth/refresh Refresh Token Cookie
GET /api/cart Shopping Cart User
POST /api/cart/add Add to Cart User
DELETE /api/cart/remove Remove User
POST /api/orders Create Order User
GET /api/orders Order List User
GET /api/orders/:id Order Details User

(2) Error Code Specifications

Status Code Error Code Description
400 VALIDATION_ERROR Request parameter validation failed
401 AUTH_REQUIRED Not logged in
401 TOKEN_EXPIRED Token expired
403 FORBIDDEN Insufficient permissions
404 NOT_FOUND Resource does not exist
409 CONFLICT Resource conflict (e.g., email address already registered)
429 RATE_LIMITED Request rate exceeded
500 INTERNAL_ERROR Internal server error

(3) Response Format

TYPESCRIPT
// Success response
{
  "data": { ... },
  "message": "Operation successful"
}

// List response
{
  "items": [...],
  "total": 1000000,
  "page": 1,
  "limit": 20
}

// Error response
{
  "statusCode": 400,
  "message": "Validation error",
  "errorCode": "VALIDATION_ERROR",
  "details": { "field": "email", "reason": "Invalid format" }
}

7. Comprehensive Example: MegaShop Project Structure

TEXT
megashop/
├── nuxt.config.ts
├── prisma/
│   ├── schema.prisma
│   ├── seed.ts
│   └── migrations/
├── pages/
│   ├── index.vue
│   ├── products/
│   │   ├── index.vue
│   │   └── [id].vue
│   ├── categories/
│   │   └── [slug].vue
│   ├── cart.vue
│   ├── checkout.vue
│   ├── login.vue
│   ├── register.vue
│   ├── profile/
│   │   ├── index.vue
│   │   └── orders.vue
│   └── admin/
│       ├── index.vue
│       ├── products/
│       └── orders/
├── components/
│   ├── AppHeader.vue
│   ├── AppFooter.vue
│   ├── product/
│   │   ├── ProductCard.vue
│   │   ├── ProductGrid.vue
│   │   └── ProductReview.vue
│   ├── cart/
│   │   └── CartItem.vue
│   └── common/
│       ├── LanguageSwitcher.vue
│       └── SearchBar.vue
├── composables/
│   ├── useCart.ts
│   ├── useAnalytics.ts
│   ├── useLocalizedPrice.ts
│   └── useProductSearch.ts
├── stores/
│   ├── cart.ts
│   └── user.ts
├── server/
│   ├── utils/
│   │   ├── prisma.ts
│   │   └── jwt.ts
│   ├── middleware/
│   │   └── auth.ts
│   ├── api/
│   │   ├── auth/
│   │   ├── products/
│   │   ├── categories/
│   │   ├── cart/
│   │   └── orders/
│   └── plugins/
│       └── stock.ts
├── middleware/
│   ├── 01-auth.global.ts
│   └── admin.ts
├── plugins/
│   ├── 01-config.ts
│   ├── 02-logger.ts
│   └── 03-stripe.client.ts
├── layouts/
│   ├── default.vue
│   └── sidebar.vue
├── locales/
│   ├── en.json
│   ├── zh.json
│   └── ja.json
├── modules/
│   └── analytics/
├── tests/
│   ├── composables/
│   ├── stores/
│   ├── components/
│   └── api/
├── e2e/
│   ├── cart-flow.spec.ts
│   ├── auth-flow.spec.ts
│   └── admin-flow.spec.ts
├── Dockerfile
├── docker-compose.yml
├── .github/workflows/
│   ├── ci.yml
│   ├── deploy-staging.yml
│   └── deploy-production.yml
└── public/
    ├── favicon.ico
    └── robots.txt

❓ FAQ

Q How long does the design phase take?
A Generally 1-2 weeks. Requirements analysis: 2 days; architecture design: 2 days; data modeling: 2 days; API specifications: 2 days; technology selection: 1 day. The more detailed the design, the smoother the development process.
Q How do I choose between PostgreSQL and MySQL?
A PostgreSQL is a better fit for MegaShop—it supports JSON fields (product attributes), full-text search (product search), and a wide variety of index types. Prisma offers the best support for PostgreSQL.
Q Is Redis required?
A Recommended for product pages with millions of items. Redis is used for product caching and ISR storage, with a response time of 5 ms compared to 200 ms for the database. For low-traffic scenarios, you can skip it for now.
Q How is API versioning handled?
A Add the version prefix /api/v1/products to the URL, and increment the version number for major changes. For minor changes, extend the fields in a backward-compatible manner.
Q How should the granularity of module division be determined?
A Divide by business domain—one module each for authentication, products, shopping cart, and orders. Each module should have its own API, Store, Composable, and page. Do not divide by technical layer.
Q How do you ensure consistency between the design documentation and the code?
A Use the Prisma schema as the single source of truth for the data model, and define the API specifications using TypeScript interfaces. When making design changes, update the schema and interfaces first, then update the code.

📖 Summary


📝 Exercises

  1. Basic Question (Difficulty: ⭐): Draw a diagram showing the user roles and functional modules for your project.
  2. Advanced Problem (Difficulty ⭐⭐): Design a complete Prisma schema (with at least 5 models), taking into account indexes and foreign keys.
  3. Challenge (Difficulty: ⭐⭐⭐): Design a complete API specification document, including all endpoints, request/response formats, and error codes.

---|

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏