fix(db): use TEXT for user_id columns across entire codebase

Better Auth generates non-UUID user IDs (32-char base62 format like
'otUe1YrfENPdHnrF3g1vSBfpkQfambCZ'). Changed all `uuid('user_id')` to
`text('user_id')` in Drizzle schemas for consistency with auth system.

Affected packages/apps:
- apps/calendar, clock, picture, zitare
- games/figgos, voxelava
- packages/manadeck-database, news-database, uload-database
- services/mana-core-auth (feedback schema)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Wuesteon 2025-12-09 16:30:51 +01:00
parent 4e63f3f74b
commit f440ca2a8d
33 changed files with 73 additions and 53 deletions

View file

@ -1,4 +1,4 @@
import { pgTable, uuid, varchar, text, timestamp, jsonb, index, pgEnum } from 'drizzle-orm/pg-core';
import { pgTable, uuid, text, varchar, timestamp, jsonb, index, pgEnum } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
import { decks } from './decks.js';
@ -25,7 +25,7 @@ export const aiGenerations = pgTable(
'ai_generations',
{
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').notNull(),
userId: text('user_id').notNull(),
deckId: uuid('deck_id').references(() => decks.id, { onDelete: 'set null' }),
functionName: varchar('function_name', { length: 100 }).notNull(),
prompt: text('prompt').notNull(),

View file

@ -1,6 +1,7 @@
import {
pgTable,
uuid,
text,
integer,
timestamp,
index,
@ -23,7 +24,7 @@ export const cardProgress = pgTable(
'card_progress',
{
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').notNull(),
userId: text('user_id').notNull(),
cardId: uuid('card_id')
.notNull()
.references(() => cards.id, { onDelete: 'cascade' }),

View file

@ -1,10 +1,10 @@
import {
pgTable,
uuid,
text,
date,
integer,
decimal,
text,
timestamp,
index,
unique,
@ -14,7 +14,7 @@ export const dailyProgress = pgTable(
'daily_progress',
{
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').notNull(),
userId: text('user_id').notNull(),
date: date('date').notNull(),
cardsStudied: integer('cards_studied').default(0).notNull(),
timeSpentMinutes: integer('time_spent_minutes').default(0).notNull(),

View file

@ -1,8 +1,8 @@
import {
pgTable,
uuid,
varchar,
text,
varchar,
boolean,
timestamp,
jsonb,
@ -17,7 +17,7 @@ export const decks = pgTable(
'decks',
{
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').notNull(),
userId: text('user_id').notNull(),
title: varchar('title', { length: 255 }).notNull(),
description: text('description'),
coverImageUrl: text('cover_image_url'),

View file

@ -1,4 +1,4 @@
import { pgTable, uuid, integer, timestamp, index, pgEnum } from 'drizzle-orm/pg-core';
import { pgTable, uuid, text, integer, timestamp, index, pgEnum } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
import { decks } from './decks.js';
@ -12,7 +12,7 @@ export const studySessions = pgTable(
deckId: uuid('deck_id')
.notNull()
.references(() => decks.id, { onDelete: 'cascade' }),
userId: uuid('user_id').notNull(),
userId: text('user_id').notNull(),
mode: studyModeEnum('mode').notNull(),
totalCards: integer('total_cards').notNull().default(0),
completedCards: integer('completed_cards').notNull().default(0),

View file

@ -1,9 +1,9 @@
import { pgTable, uuid, integer, decimal, date, timestamp, index } from 'drizzle-orm/pg-core';
import { pgTable, text, integer, decimal, date, timestamp, index } from 'drizzle-orm/pg-core';
export const userStats = pgTable(
'user_stats',
{
userId: uuid('user_id').primaryKey(),
userId: text('user_id').primaryKey(),
totalWins: integer('total_wins').default(0).notNull(),
totalSessions: integer('total_sessions').default(0).notNull(),
totalCardsStudied: integer('total_cards_studied').default(0).notNull(),

View file

@ -29,7 +29,7 @@ export const articles = pgTable(
summary: text('summary'),
// For user-saved articles
userId: uuid('user_id').references(() => users.id, { onDelete: 'cascade' }),
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
originalUrl: text('original_url'),
parsedContent: text('parsed_content'),
isArchived: boolean('is_archived').default(false),

View file

@ -4,7 +4,7 @@ import { users } from './users';
// Better Auth Sessions
export const sessions = pgTable('sessions', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id')
userId: text('user_id')
.references(() => users.id, { onDelete: 'cascade' })
.notNull(),
token: text('token').notNull().unique(),
@ -18,7 +18,7 @@ export const sessions = pgTable('sessions', {
// Better Auth Accounts (for OAuth providers)
export const accounts = pgTable('accounts', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id')
userId: text('user_id')
.references(() => users.id, { onDelete: 'cascade' })
.notNull(),
providerId: text('provider_id').notNull(), // 'credential', 'google', 'apple', etc.

View file

@ -1,6 +1,7 @@
import {
pgTable,
uuid,
text,
timestamp,
boolean,
real,
@ -15,7 +16,7 @@ export const userArticleInteractions = pgTable(
'user_article_interactions',
{
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id')
userId: text('user_id')
.references(() => users.id, { onDelete: 'cascade' })
.notNull(),
articleId: uuid('article_id')

View file

@ -21,7 +21,7 @@ export const links = pgTable(
originalUrl: text('original_url').notNull(),
title: text('title'),
description: text('description'),
userId: uuid('user_id').references(() => users.id, { onDelete: 'cascade' }),
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
isActive: boolean('is_active').default(true),
password: text('password'), // hashed
maxClicks: integer('max_clicks'),

View file

@ -12,7 +12,7 @@ export const tags = pgTable(
icon: text('icon'),
isPublic: boolean('is_public').default(false),
usageCount: integer('usage_count').default(0),
userId: uuid('user_id').references(() => users.id),
userId: text('user_id').references(() => users.id),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
},