Takazudo Modular Docs

Type to search...

to open search from anywhere

Development Plan

Development Plan

Implementation plan for zpreorder (Issue #500) and Email Notifications (Issue #501).

Phase 1: Foundation

1.1 Admin API Endpoints

Add authenticated API endpoints to the main site for admin access:

EndpointPurpose
POST /api/admin/notify/listList notify subscriptions (filterable)
POST /api/admin/reservations/listList reservations (filterable)
POST /api/admin/notify/[id]/statusUpdate subscription status
POST /api/admin/reservations/[id]/statusUpdate reservation status
POST /api/admin/statsGet summary statistics

1.2 Duplicate Handling for Notify

Update notify-signup function to handle duplicates silently:

// Current behavior: Return error for duplicates
// New behavior: Return success (silent duplicate handling)

const isSubscribed = await isEmailSubscribed(productSlug, email);
if (isSubscribed) {
  // Don't create duplicate, but return success
  return {
    statusCode: 200,
    body: JSON.stringify({ success: true, message: '登録完了' }),
  };
}

Rationale: Users may not remember if they’ve signed up. Silent success provides better UX.

Phase 2: Sub-App MVP

2.1 Project Setup

# Create sub-package
mkdir -p sub-packages/zpreorder
cd sub-packages/zpreorder

# Initialize with Next.js
pnpm create next-app . --typescript --tailwind --app --no-src-dir

2.2 Core Pages

PageFeatures
Dashboard (/)Summary stats, recent activity
Notify List (/notify)Table, filtering, bulk actions
Reservations (/reservations)Table, status management, notes
Products (/products)Per-product stats, quick links

2.3 API Client

Dual-mode client supporting mock and remote data:

// lib/api-client.ts
export const apiClient = {
  notify: {
    list: (filter?: NotifyFilter) => fetchData('/notify/list', filter),
    updateStatus: (id: string, status: string) => postData(`/notify/${id}/status`, { status }),
  },
  reservations: {
    list: (filter?: ReservationFilter) => fetchData('/reservations/list', filter),
    updateStatus: (id: string, status: string, notes?: string) =>
      postData(`/reservations/${id}/status`, { status, notes }),
  },
  stats: () => fetchData('/stats'),
};

Phase 3: Email Integration (Issue #501)

3.1 Auto-Reply Emails

Registration confirmation emails (mocked initially):

EventEmail Content
Notify signup”入荷通知の登録を受け付けました”
Reservation”予約を受け付けました (予約ID: xxx)“

3.2 Product Available Notification

Manual trigger from admin dashboard:

  1. Select product in admin UI
  2. Click “入荷通知を送信”
  3. Confirm subscriber count
  4. Send emails in batches
  5. Mark subscriptions as “notified”

:::note Mock Implementation Email sending will be mocked during initial development. Console logs will show what would be sent. Real SendGrid integration comes later. :::

Implementation Order

graph TD
    A[1.1 Admin API Endpoints] --> C[2.1 Sub-App Setup]
    B[1.2 Duplicate Handling] --> C
    C --> D[2.2 Core Pages]
    D --> E[2.3 API Client Integration]
    E --> F[3.1 Auto-Reply Mocked]
    F --> G[3.2 Product Notification Mocked]
    G --> H[Real Email Integration]

Testing Strategy

Unit Tests

  • API client mock/remote switching
  • Data transformation functions
  • Filter logic

E2E Tests

  • Dashboard loads and displays stats
  • Notify list filtering works
  • Status updates persist (mock mode)

Environment Variables

# In sub-packages/zpreorder/.env for remote mode
VITE_BLOB_API_URL=https://preview--takazudomodular.netlify.app/api/admin
VITE_PREORDER_API_TOKEN=xxx