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-designskill 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:
-
Use the
<link>tag (recommended): Inlayout.tsximport<head> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link href="https://fonts.googleapis.com/css2?family=..." rel="stylesheet" /> </head> -
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 |