#23: users table + insert/update added

This commit is contained in:
2025-02-13 10:56:03 -06:00
parent 5eee7c9ac4
commit d180cd70e8
19 changed files with 110 additions and 33 deletions

View File

@@ -1,5 +1,6 @@
DB_FILE_NAME=file:local.db
PORT=3000
PORT=3002
FIREBASE_PROJECT_ID=haiki-452bd
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-fbsvc@haiki-452bd.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDyCsRhtPYwozBy\n60A4LguqsFzJG0WwCMhvi7PIxoh1kVenwxXBBQHvgssF/jPTkqbK6orL9r15gdRc\nZK2S73OdESYlO9xCE+gq/pop1F432DrHBA6ftQIl2NHSQfkKgTKFM6Pt85e6s5mb\neIxxHr7AzGMlqu7UJbnw8Vk2+8LP3NZXwsyCEi5vg4+8UgPFVxhLnB4HYZIM8JOj\nM3q1N/KqKgl2qGl5ekZLN7QLPs6+znlVZVIeHo1vuX9xTUaa6XUA0xeZfFO3pNUd\nKLlQNAy7OFQ6GlTFTWWHnShecLPHLQdWP15rkwBPv1q7qDmtLMy4E2XLvsoErhJM\niFsbEczxAgMBAAECggEAJqGJTn7vfDvPk8fwbAcNXaTgakisCricJRGLFFR7mygj\ncWc1paUC9hNODBrScsZJUMG2fW9YNnh+SHDZM0Z8kWkXSYIQWYuL1rDkMiDvGMKu\nPu1q2BqvyRKeCoz1DrQoOBJR67yhTu8zaRkIcVWS5Hq6qFxr2fhbgRVEQ/5SzZIG\nPh+Npxdp62Xe66MB0OzmF/A5qSrXTpOOk4/Lmpoqf6PtmrOD+SetE+Aa6ELYX3pK\n30XPLiUyDS+EFPjHLA1U7frOawLRpMP6Iobu7hUzu9ASzgLKxpzbcGRsPtbVRuAQ\nzP+iV+Nyn/wMFbnnjrjlwk/jqE+NLGJnf7Jrc9vwQQKBgQD5lfRWR6MKDezty5Qu\nPGrSlKXOM+aOoTmZiaPTutYzwWHeqzfUfYsghbgR3jl7I0BTqMaGrOnYU60IDWZi\nJeK6iu68pUe8Mme3vXm15Go55UhZD9U5/4W+x0/+AVivBPUBwKUXFdgmPFkb2jBY\np1LJmXaelx2jvPM3yMXQN+5flQKBgQD4Qy6aF3V7DIVxo/F88KCGNUpEobyXsxv6\nakSV+7WEtuSf6amXHxZyiJPtjCIwzCUL458gUd6mwiQgWRy7awdKreU6BCHgqNVf\nAE5ahjeeiLOc1uu0ocNLL+g35DbBXSgSlB+hUE0+bxAxU9xjNc9UZKqIi/kGRP/G\nlxi2ZUIQ7QKBgQDUH5Ku0evL29IGuQOT2F2h5ByXiJznlDd0Ovs2NJFhI3ae3T5y\nJtFcLsomxYxtD6TYdZVlWQjWhyeEtH7T5AczLGmDg6XYWa61ByCuaxetZSV8LGy5\nAmcVoihmZZaOCdSCTM0DNdmjhZ7mgSad8nf2R6v9VconI6xDOSyGr0K1kQKBgQCp\nuhxxIpqhzlSo9aFSfpvwRRyKQVzTBZOaJu7O7zARFIzHOxNDivBoyzD/FXAGlnq5\nXxvaF761mULjjqjTBQAOMUbm3A5hLmv5sBbhUqNR0jmhf1nTu0ft7km/dFlu5wZP\ndU8OlPzKM1oJr0Cb3xzooI3qHm/YtnF7Tq+Jez6onQKBgQCfbqG5dyTAduhPZzmp\n6m4ndzzdYVoh8KiM3fUApo/u9zF3GixUFgcKKFzP1/zmD6A6UfbVT+JVmUfIVtor\nAA42lqJyOaNH9ttQjZeDXfPpbAyAoZzH0l7/U9KSOkh+2I8tMscjWFqyQ1/DGNcY\nptIRECjQrk5jL0yea0+tbpMmJQ==\n-----END PRIVATE KEY-----\n
DATABASE_URL=postgresql://haiky:xieng7Seih@localhost:15432/haiky

View File

@@ -3,10 +3,11 @@ import { DecksController } from './decks.controller';
import { DrizzleService } from './drizzle.service';
import { ProxyController } from './proxy.controller';
import { SqlLoggerService } from './sql-logger.service';
import { UserController } from './user.controller';
@Module({
imports: [],
controllers: [DecksController, ProxyController],
controllers: [DecksController, ProxyController, UserController],
providers: [DrizzleService, SqlLoggerService],
})
export class AppModule {}

View File

@@ -3,7 +3,7 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { and, eq, sql } from 'drizzle-orm';
//import { drizzle } from 'drizzle-orm/libsql';
import { drizzle } from 'drizzle-orm/node-postgres';
import { deck, SelectDeck, User } from '../db/schema';
import { deck, InsertUser, SelectDeck, User, users } from '../db/schema';
import { SqlLoggerService } from './sql-logger.service';
@Injectable()
@@ -11,16 +11,7 @@ export class DrizzleService {
// private readonly logger = new Logger(DrizzleService.name);
private db: any;
constructor(private sqlLogger: SqlLoggerService) {
// this.db = drizzle('file:local.db', {
// logger: {
// logQuery: (query: string, params: any[]) => {
// this.sqlLogger.logQuery(query, params);
// },
// },
// });
this.db = drizzle(process.env['DATABASE_URL']!, {
//this.db = drizzle('postgresql://haiky:xieng7Seih@localhost:15432/haiky', {
logger: {
logQuery: (query: string, params: any[]) => {
this.sqlLogger.logQuery(query, params);
@@ -296,4 +287,42 @@ export class DrizzleService {
throw new HttpException(`Fehler beim Abrufen der Bild-IDs - ${error}`, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
/**
* Führt den Login-Vorgang durch:
* - Existiert der Benutzer bereits (überprüft via E-Mail), wird das Feld `lastLogin` (und ggf. weitere Felder) aktualisiert.
* - Existiert der Benutzer nicht, wird ein neuer Datensatz mit `role: 'guest'` und `lastLogin` auf den aktuellen Zeitpunkt angelegt.
*/
async logIn(createUserDto: InsertUser) {
// Prüfen, ob der Benutzer bereits existiert (hier anhand der E-Mail)
const existingUser = await this.db.select().from(users).where(eq(users.email, createUserDto.email)).limit(1);
if (existingUser.length > 0) {
// Benutzer existiert: Update des letzten Logins und ggf. weiterer Felder
const updatedUser = await this.db
.update(users)
.set({
lastLogin: new Date(), // Setzt lastLogin explizit auf den aktuellen Zeitpunkt
// Optional: Aktualisierung von Name und sign_in_provider, falls sich diese ändern sollten
name: createUserDto.name,
sign_in_provider: createUserDto.sign_in_provider,
})
.where(eq(users.email, createUserDto.email))
.returning();
return updatedUser;
} else {
// Neuer Benutzer: Insert mit role per Default 'guest' und lastLogin auf now
const insertedUser = await this.db
.insert(users)
.values({
name: createUserDto.name,
email: createUserDto.email,
sign_in_provider: createUserDto.sign_in_provider,
lastLogin: new Date(), // Setzt lastLogin auf now
role: 'guest', // Default-Wert 'guest'
})
.returning();
return insertedUser;
}
}
}

View File

@@ -0,0 +1,15 @@
// user.controller.ts
import { Body, Controller, Post } from '@nestjs/common';
import type { InsertUser } from '../db/schema';
import { DrizzleService } from './drizzle.service';
@Controller('users')
export class UserController {
constructor(private readonly drizzleService: DrizzleService) {}
@Post()
async createUser(@Body() createUserDto: InsertUser) {
// Hier kannst du zusätzliche Validierungen oder Logik einbauen.
return await this.drizzleService.logIn(createUserDto);
}
}

View File

@@ -26,6 +26,8 @@ export const deck = table(
},
table => [t.uniqueIndex('deck_idx').on(table.id)],
);
export type InsertDeck = typeof deck.$inferInsert;
export type SelectDeck = typeof deck.$inferSelect;
export const users = table(
'users',
{
@@ -34,13 +36,12 @@ export const users = table(
email: t.varchar().notNull(),
role: rolesEnum().default('guest'),
sign_in_provider: t.varchar('sign_in_provider', { length: 50 }),
inserted: t.timestamp('inserted', { mode: 'date' }).defaultNow(),
updated: t.timestamp('updated', { mode: 'date' }).defaultNow(),
lastLogin: t.timestamp('lastLogin', { mode: 'date' }).defaultNow(),
},
table => [t.uniqueIndex('users_idx').on(table.id)],
);
export type InsertDeck = typeof deck.$inferInsert;
export type SelectDeck = typeof deck.$inferSelect;
export type InsertUser = typeof users.$inferInsert;
export type SelectUser = typeof users.$inferSelect;
export interface User {
name: string;
picture: string;

View File

@@ -5,6 +5,7 @@
"module": "ES2020",
"types": ["node"],
"emitDecoratorMetadata": true,
"isolatedModules": true,
"target": "es2021",
"strictNullChecks": true
},