SuperAPI AI Directory

secondme-nextjs

Frontend & websites

View repository

Updated 10-15 17:29

About this skill

SecondMe Next.js Project Generation

Based on the configuration of /secondme-init and the requirement definition of /secondme-prd , generate a complete Next.js project.


Prerequisite Checks

1. Check state.json

First check whether .secondme/state.json exists:

  • Does not exist → Prompt:请先运行 /secondme-init 初始化项目配置
  • Exists → Continue

2. Check execution mode

Check whether the parameters include --quick:

Fast mode (--quick):

  • Skip stage check
  • Use default PRD configuration
  • Start generating the project directly

Standard mode:

  • Check stage >= "prd"
  • If stage == "init" → Prompt:请先运行 /secondme-prd 定义需求,或使用 /secondme-nextjs --quick 快速生成
  • If stage >= "prd" → Continue

Read configuration

Read from .secondme/state.json :

const state = {
  app_name: "secondme-tinder",  // 应用名称
  modules: ["auth", "chat", "profile"],  // 已选模块
  config: {
    client_id: "71658da7-659c-414a-abdf-cb6472037fc2",
    client_secret: "xxx",
    redirect_uri: "http://localhost:3000/api/auth/callback",
    redirect_uris: [...],
    database_url: "postgresql://...",
    allowed_scopes: [...]
  },
  api: {
    base_url: "https://api.mindverse.com/gate/lab",
    oauth_url: "https://go.second.me/oauth/",
    token_endpoint: "https://api.mindverse.com/gate/lab/api/oauth/token/code",
    refresh_endpoint: "https://api.mindverse.com/gate/lab/api/oauth/token/refresh",
    access_token_ttl: 7200,
    refresh_token_ttl: 2592000
  },
  docs: {
    quickstart: "https://develop-docs.second.me/zh/docs",
    oauth2: "...",
    api_reference: "...",
    errors: "..."
  },
  prd: {
    summary: "应用概要",
    features: ["功能1", "功能2"],
    design_preference: "简约现代"
  }
}

Important: All API endpoints and documentation links are read from state.api and state.docs , do not hardcode them.


Frontend design requirements

Important: When building the frontend interface, you must use the frontend-design:frontend-design skill to generate high-quality UI components.

Design principles:

  • Light theme: Use only light/bright themes, do not use dark themes
  • Simple and elegant: Follow a minimalist design philosophy, reduce visual noise
  • Product feature driven: UI design should be closely integrated with the features to be implemented
  • Modern feel: Adopt current popular design trends, avoid outdated UI patterns
  • Consistency: Maintain a unified overall visual style
  • Responsive: Adapt to various screen sizes
  • Chinese interface: All user-visible text (buttons, prompts, labels, descriptions, etc.) must be in Chinese
  • Stability first: Avoid complex animation effects, use only simple transition animations (such as hover, fade) to ensure a stable and smooth interface

Project generation process

1. Initialize Next.js project

Initialize the Next.js project directly in the current directory:

npx create-next-app@latest . --typescript --tailwind --app --src-dir --import-alias "@/*" --yes

2. Install dependencies

npm install prisma @prisma/client
npx prisma init

3. Generate .env.local

Generate environment variables from state.config and state.api :

# SecondMe OAuth2 配置
SECONDME_CLIENT_ID=[config.client_id]
SECONDME_CLIENT_SECRET=[config.client_secret]
SECONDME_REDIRECT_URI=[config.redirect_uri]

# 数据库
DATABASE_URL=[config.database_url]

# SecondMe API(从 state.api 读取)
SECONDME_API_BASE_URL=[api.base_url]
SECONDME_OAUTH_URL=[api.oauth_url]
SECONDME_TOKEN_ENDPOINT=[api.token_endpoint]
SECONDME_REFRESH_ENDPOINT=[api.refresh_endpoint]

4. Generate Prisma Schema

Dynamically generate based on the selected modules prisma/schema.prisma。

auth module (required) - fields that the User table must contain

The User table must contain Token-related fields for storing and refreshing user credentials:

model User {
  id                String   @id @default(cuid())
  secondmeUserId    String   @unique @map("secondme_user_id")
  accessToken       String   @map("access_token")
  refreshToken      String   @map("refresh_token")
  tokenExpiresAt    DateTime @map("token_expires_at")
  createdAt         DateTime @default(now()) @map("created_at")
  updatedAt         DateTime @updatedAt @map("updated_at")
  // 其他字段根据模块需求自行添加

  @@map("users")
}

Other modules

Based on the actual requirements of the selected modules (profile, chat, note), design the corresponding database table structures and relationships yourself.

5. Generate code

Generate the corresponding code based on the selected modules:

auth module

File Description
src/app/api/auth/login/route.ts OAuth login redirect
src/app/api/auth/callback/route.ts OAuth callback handling
src/app/api/auth/logout/route.ts Logout handling
src/lib/auth.ts Authentication utility functions
src/components/LoginButton.tsx Login button component

profile module

File Description
src/app/api/user/info/route.ts Get user information
src/app/api/user/shades/route.ts Get interest tags
src/components/UserProfile.tsx User profile component

chat module

File Description
src/app/api/chat/route.ts Streaming chat API
src/app/api/sessions/route.ts Session list API
src/components/ChatWindow.tsx Chat interface component

act module

File Description
src/app/api/act/route.ts Streaming action determination API (structured JSON output)
src/lib/act.ts Act API utility functions (send actionControl, parse SSE JSON results)

note module

File Description
src/app/api/note/route.ts Add note API

6. Update state.json

{
  "stage": "ready",
  ...
}

Tech stack

  • Framework: Next.js 14+ (App Router)
  • Language: TypeScript
  • Styling: Tailwind CSS
  • Database ORM: Prisma
  • Frontend design: Use frontend-design:frontend-design skill to generate
  • API calls: fetch
  • State management: React hooks
  • Running port: Must use port 3000

Common issues and notes

CSS @import order issue

Problem: In globals.css using @import url(...) to import Google Fonts causes the build to fail.

Error message:

@import rules must precede all rules aside from @charset and @layer statements

Cause: Tailwind CSS's @import "tailwindcss" expands to generate a large number of rules, causing the subsequent @import url(...) to no longer be the first.

Correct approach:

  1. Use the <link> tag (recommended): In layout.tsx import

    <head>
      <link rel="preconnect" href="https://fonts.googleapis.com" />
      <link href="https://fonts.googleapis.com/css2?family=..." rel="stylesheet" />
    </head>
    
  2. Use next/font(best practice):

    import { Noto_Sans_SC } from 'next/font/google'
    const notoSans = Noto_Sans_SC({ subsets: ['latin'], weight: ['400', '500'] })
    

Build verification

Important: After each code modification, you must run the following command to verify the build:

npm run build

Pay special attention to:

  • CSS parsing errors
  • TypeScript type errors
  • Import path errors

WebView OAuth authentication issue

Problem: In a WebView environment (such as pages embedded in mobile apps, WeChat Mini Programs, etc.), OAuth state verification may fail because storage is not shared between the WebView and the system browser.

Solution: Use lenient state verification; when verification fails, log a warning but continue processing the login flow.

// 之前:验证失败直接拒绝
if (!isValidState) {
  return NextResponse.redirect('/?error=invalid_state');
}

// 之后:验证失败记录警告,继续处理
if (!isValidState) {
  console.warn('OAuth state 验证失败,可能是跨 WebView 场景');
  // 继续处理,不阻止登录
}

Note: This approach reduces CSRF protection and is only recommended for use in trusted WebView environments


Output results

✅ Next.js 项目已生成!

已生成模块: auth, chat, profile
数据库: PostgreSQL

启动步骤:
1. npm install
2. npx prisma db push
3. npm run dev

项目将在 http://localhost:3000 启动

API response format

Important: All SecondMe API responses follow a unified format:

{
  "code": 0,
  "data": { ... }
}

Relationship between local routes and upstream API: Next.js local routes (such as /api/secondme/user/shades) act as a proxy layer, forwarding requests to the upstream SecondMe API ({state.api.base_url}/api/secondme/...), andpass through the upstream response format. Frontend code only needs to call the local routes; there is no need to access the upstream API directly.

Frontend code must correctly extract data:

// ✅ 正确写法(调用 Next.js 本地路由,响应格式与上游一致)
const response = await fetch('/api/secondme/user/shades');
const result = await response.json();
if (result.code === 0) {
  const shades = result.data.shades;
  shades.map(item => ...)
}

Official documentation

From state.docs read the documentation link:

Documentation Configuration key
Quick Start docs.quickstart
OAuth2 Guide docs.oauth2
API Reference docs.api_reference
Error Codes docs.errors