Task 4.2: Add default data seeding on new user creation

Create seedUserDefaults() helper in src/lib/db/seed-user-defaults.ts
that inserts default annotation_types (break_up, break_down, line) and
default span_label_types (bull_flag, bear_flag, etc.) scoped to a
given user_id. Call it from POST /api/auth/register after user insert
and from src/auth.ts Google signIn callback after new Google user creation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marko Djordjevic 2026-02-20 10:16:55 +01:00
parent 9a5e325632
commit 10e4ec8648
4 changed files with 61 additions and 3 deletions

View file

@ -22,7 +22,7 @@
## 4. Registration API
- [x] 4.1 `[sonnet]` Create `POST /api/auth/register` endpoint: validate input (email required, password 8+ chars), check email uniqueness, hash password with bcryptjs, insert user, return 201
- [ ] 4.2 `[sonnet]` Add default data seeding function: on new user creation, insert default annotation_types (break_up, break_down, line) and default span_label_types for the new user
- [x] 4.2 `[sonnet]` Add default data seeding function: on new user creation, insert default annotation_types (break_up, break_down, line) and default span_label_types for the new user
## 5. Auth Middleware & Helpers

View file

@ -3,6 +3,7 @@ import bcryptjs from 'bcryptjs';
import { eq } from 'drizzle-orm';
import { db } from '@/lib/db';
import { users } from '@/lib/db/schema';
import { seedUserDefaults } from '@/lib/db/seed-user-defaults';
export async function POST(request: NextRequest) {
let body: unknown;
@ -57,6 +58,9 @@ export async function POST(request: NextRequest) {
})
.returning({ id: users.id, email: users.email, name: users.name });
// Seed default annotation types and span label types for the new user
await seedUserDefaults(newUser.id);
return NextResponse.json(
{ id: newUser.id, email: newUser.email, name: newUser.name },
{ status: 201 }

View file

@ -5,6 +5,7 @@ import bcryptjs from "bcryptjs";
import { eq } from "drizzle-orm";
import { db } from "@/lib/db";
import { users } from "@/lib/db/schema";
import { seedUserDefaults } from "@/lib/db/seed-user-defaults";
export const { handlers, auth, signIn, signOut } = NextAuth({
secret: process.env.AUTH_SECRET,
@ -72,14 +73,17 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
if (!existingUser) {
// First Google sign-in: create a new user record
await db.insert(users).values({
const [newUser] = await db.insert(users).values({
email,
name: profile?.name ?? user.name ?? null,
image: profile?.picture ?? (user.image ?? null),
provider: "google",
provider_account_id: account.providerAccountId,
password_hash: null,
});
}).returning({ id: users.id });
// Seed default annotation types and span label types for the new user
await seedUserDefaults(newUser.id);
}
// Returning Google sign-in: existing user found, allow sign-in
return true;

View file

@ -0,0 +1,50 @@
import { db } from './index';
import { annotationTypes, spanLabelTypes } from './schema';
const DEFAULT_ANNOTATION_TYPES = [
{
name: 'break_up',
display_name: 'Break Up',
color: '#10b981',
category: 'marker',
icon: 'arrowUp',
},
{
name: 'break_down',
display_name: 'Break Down',
color: '#ef4444',
category: 'marker',
icon: 'arrowDown',
},
{
name: 'line',
display_name: 'Line',
color: '#3b82f6',
category: 'line',
icon: 'line',
},
];
const DEFAULT_SPAN_LABEL_TYPES = [
{ name: 'bull_flag', display_name: 'Bull Flag', color: '#4CAF50', hotkey: '1', sort_order: 1 },
{ name: 'bear_flag', display_name: 'Bear Flag', color: '#F44336', hotkey: '2', sort_order: 2 },
{ name: 'head_and_shoulders', display_name: 'Head and Shoulders', color: '#9C27B0', hotkey: '3', sort_order: 3 },
{ name: 'double_bottom', display_name: 'Double Bottom', color: '#2196F3', hotkey: '4', sort_order: 4 },
{ name: 'wedge_up', display_name: 'Wedge Up', color: '#FF9800', hotkey: '5', sort_order: 5 },
{ name: 'wedge_down', display_name: 'Wedge Down', color: '#FF5722', hotkey: '6', sort_order: 6 },
{ name: 'custom', display_name: 'Custom', color: '#607D8B', hotkey: '7', sort_order: 7 },
];
/**
* Seeds default annotation_types and span_label_types for a newly created user.
* Safe to call on new user creation inserts rows scoped to the given user_id.
*/
export async function seedUserDefaults(userId: string): Promise<void> {
await db.insert(annotationTypes).values(
DEFAULT_ANNOTATION_TYPES.map((t) => ({ ...t, user_id: userId }))
);
await db.insert(spanLabelTypes).values(
DEFAULT_SPAN_LABEL_TYPES.map((t) => ({ ...t, user_id: userId }))
);
}