Spaces:
Running
Running
| import { NextRequest, NextResponse } from 'next/server'; | |
| import { UserRepository } from '@/lib/repositories/user-repository'; | |
| import { z } from 'zod'; | |
| const teachingGradeSchema = z.enum(['kindergarten', 'elementary', 'junior_high', 'senior_high', 'other']); | |
| const positionSchema = z.enum(['homeroom', 'subject', 'administrative', 'none', 'other']); | |
| const teachingExperienceSchema = z.enum(['none', 'less_than_1', '1_to_2', '2_to_5', 'more_than_5', 'other']); | |
| const knownStrategySchema = z.enum(['satir', 'nvc', 'orid', 'sbior', 'unknown', 'other']); | |
| const registerSchema = z.object({ | |
| username: z.string() | |
| .min(3, '帳號至少需要 3 個字元') | |
| .max(50, '帳號不能超過 50 個字元') | |
| .regex(/^[a-zA-Z0-9_.]+$/, '帳號只能使用半形英文字母、數字、底線(_)和句點(.)'), | |
| teachingGrades: z.array(teachingGradeSchema).optional(), | |
| teachingGradesOther: z.string().optional(), | |
| positions: z.array(positionSchema).optional(), | |
| positionsOther: z.string().optional(), | |
| teachingExperience: teachingExperienceSchema.optional(), | |
| teachingExperienceOther: z.string().optional(), | |
| confidenceLevel: z.number().int().min(1).max(7).optional(), | |
| knownStrategies: z.array(knownStrategySchema).optional(), | |
| knownStrategiesOther: z.string().optional(), | |
| }); | |
| export async function POST(request: NextRequest) { | |
| try { | |
| const body = await request.json(); | |
| const validatedData = registerSchema.parse(body); | |
| const userRepo = new UserRepository(); | |
| // Check if username already exists | |
| const existingUser = await userRepo.findByUsername(validatedData.username); | |
| if (existingUser) { | |
| return NextResponse.json( | |
| { error: '此帳號已被使用' }, | |
| { status: 400 } | |
| ); | |
| } | |
| // Create new user | |
| const user = await userRepo.createUser(validatedData); | |
| return NextResponse.json({ | |
| user: { | |
| id: user.id, | |
| username: user.username, | |
| }, | |
| message: `User registered successfully. Use password '${process.env.BASIC_AUTH_PASSWORD || 'cz-2025'}' to login.`, | |
| }); | |
| } catch (error) { | |
| if (error instanceof z.ZodError) { | |
| const message = error.issues.map(i => i.message).join(';'); | |
| return NextResponse.json( | |
| { error: message }, | |
| { status: 400 } | |
| ); | |
| } | |
| console.error('Registration error:', error); | |
| return NextResponse.json( | |
| { error: 'Internal server error' }, | |
| { status: 500 } | |
| ); | |
| } | |
| } | |