From 1b0d8324fb6c446097b9eb6a55fe66e10505e98f Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Sun, 30 Nov 2025 12:47:17 +0100 Subject: [PATCH] move seeding back into backend --- backend/src/seeds/factory/user.ts | 17 +++- backend/src/seeds/index.ts | 127 ++++++++++++++---------------- backend/turbo.json | 6 +- database/src/seeds/seed.ts | 98 ----------------------- database/turbo.json | 4 - 5 files changed, 82 insertions(+), 170 deletions(-) delete mode 100644 database/src/seeds/seed.ts diff --git a/backend/src/seeds/factory/user.ts b/backend/src/seeds/factory/user.ts index f174df39a..5308518cb 100644 --- a/backend/src/seeds/factory/user.ts +++ b/backend/src/seeds/factory/user.ts @@ -1,4 +1,4 @@ -import { User, userFactory as userFactoryDb } from 'database' +import { User, userFactory as userFactoryDb, userFactoryBulk as userFactoryBulkDb, Community } from 'database' import { writeHomeCommunityEntry } from '@/seeds/community' import { UserInterface } from '@/seeds/users/UserInterface' @@ -18,3 +18,18 @@ export const userFactory = async ( } return dbUser } + +export async function userFactoryBulk(users: UserInterface[], homeCommunity?: Community | null) { + if (!homeCommunity) { + homeCommunity = await writeHomeCommunityEntry() + } + const dbUsers = await userFactoryBulkDb(users, homeCommunity) + for (const dbUser of dbUsers) { + if (dbUser.emailContact.emailChecked) { + const passwortHash = await encryptPassword(dbUser, 'Aa12345_') + dbUser.password = passwortHash + await dbUser.save() + } + } + return dbUsers +} \ No newline at end of file diff --git a/backend/src/seeds/index.ts b/backend/src/seeds/index.ts index 3a1504262..4cc352ec7 100644 --- a/backend/src/seeds/index.ts +++ b/backend/src/seeds/index.ts @@ -1,10 +1,13 @@ -import { createTestClient } from 'apollo-server-testing' -import { entities } from 'database' -import { datatype, internet, name } from 'faker' +import { + AppDatabase, + User, + UserInterface, + creationFactoryBulk, + transactionLinkFactoryBulk +} from 'database' +import { internet, name } from 'faker' import { CONFIG } from '@/config' -import { CONFIG as CORE_CONFIG } from 'core' -import { createServer } from '@/server/createServer' import { initLogging } from '@/server/logger' import { getLogger } from 'log4js' @@ -12,95 +15,87 @@ import { writeHomeCommunityEntry } from './community' import { contributionLinks } from './contributionLink/index' import { creations } from './creation/index' import { contributionLinkFactory } from './factory/contributionLink' -import { creationFactory } from './factory/creation' -import { transactionLinkFactory } from './factory/transactionLink' -import { userFactory } from './factory/user' +import { userFactoryBulk } from './factory/user' import { transactionLinks } from './transactionLink/index' import { users } from './users/index' -CORE_CONFIG.EMAIL = false +const RANDOM_USER_COUNT = 100 const logger = getLogger('seed') -const context = { - token: '', - setHeaders: { - push: (value: { key: string; value: string }): void => { - context.token = value.value - }, - - forEach: (): void => { - // do nothing - }, - }, - clientTimezoneOffset: 0, -} - -export const cleanDB = async () => { - // this only works as long we do not have foreign key constraints - for (const entity of entities) { - if (entity.name !== 'Migration') { - await resetEntity(entity) - } - } -} - -const resetEntity = async (entity: any) => { - const items = await entity.find({ withDeleted: true }) - if (items.length > 0) { - const ids = items.map((e: any) => e.id) - await entity.delete(ids) - } -} - const run = async () => { initLogging() - const server = await createServer(getLogger('apollo'), context) - const seedClient = createTestClient(server.apollo) - const { con } = server - await cleanDB() - logger.info('##seed## clean database successful...') + const db = AppDatabase.getInstance() + await db.init() + await clearDatabase(db) + logger.info('clean database successful...') logger.info(`crypto worker enabled: ${CONFIG.USE_CRYPTO_WORKER}`) // seed home community - await writeHomeCommunityEntry() + const homeCommunity = await writeHomeCommunityEntry() // seed the standard users - for (const user of users) { - await userFactory(seedClient, user) + // put into map for later direct access + const userCreationIndexedByEmail = new Map() + const defaultUsers = await userFactoryBulk(users, homeCommunity) + for (const dbUser of defaultUsers) { + userCreationIndexedByEmail.set(dbUser.emailContact.email, dbUser) } - logger.info('##seed## seeding all standard users successful...') + logger.info('seeding all standard users successful...') // seed 100 random users - for (let i = 0; i < 100; i++) { - await userFactory(seedClient, { + const randomUsers = new Array(RANDOM_USER_COUNT) + for (let i = 0; i < RANDOM_USER_COUNT; i++) { + randomUsers[i] = { firstName: name.firstName(), lastName: name.lastName(), email: internet.email(), - language: datatype.boolean() ? 'en' : 'de', - }) - logger.info(`##seed## seed ${i}. random user`) + language: Math.random() < 0.5 ? 'en' : 'de', + } } - logger.info('##seed## seeding all random users successful...') + await userFactoryBulk(randomUsers, homeCommunity) + logger.info('seeding all random users successful...') // create GDD - for (const creation of creations) { - await creationFactory(seedClient, creation) - } - logger.info('##seed## seeding all creations successful...') + const moderatorUser = userCreationIndexedByEmail.get('peter@lustig.de')! + await creationFactoryBulk(creations, userCreationIndexedByEmail, moderatorUser) + logger.info('seeding all creations successful...') // create Transaction Links - for (const transactionLink of transactionLinks) { - await transactionLinkFactory(seedClient, transactionLink) - } - logger.info('##seed## seeding all transactionLinks successful...') + const movedTransactionLinks = transactionLinks.map(transactionLink => { + let createdAt = new Date(new Date().getTime() + 1000) + if (transactionLink.createdAt) { + createdAt = transactionLink.createdAt + } + return { + ...transactionLink, + createdAt: createdAt, + } + }) + await transactionLinkFactoryBulk(movedTransactionLinks, userCreationIndexedByEmail) + logger.info('seeding all transactionLinks successful...') // create Contribution Links for (const contributionLink of contributionLinks) { - await contributionLinkFactory(seedClient, contributionLink) + await contributionLinkFactory(null, contributionLink) } - logger.info('##seed## seeding all contributionLinks successful...') + logger.info('seeding all contributionLinks successful...') - await con.destroy() + await db.destroy() +} + +async function clearDatabase(db: AppDatabase) { + await db.getDataSource().transaction(async trx => { + await trx.query(`SET FOREIGN_KEY_CHECKS = 0`) + await trx.query(`TRUNCATE TABLE contributions`) + await trx.query(`TRUNCATE TABLE contribution_links`) + await trx.query(`TRUNCATE TABLE users`) + await trx.query(`TRUNCATE TABLE user_contacts`) + await trx.query(`TRUNCATE TABLE user_roles`) + await trx.query(`TRUNCATE TABLE transactions`) + await trx.query(`TRUNCATE TABLE transaction_links`) + await trx.query(`TRUNCATE TABLE communities`) + await trx.query(`SET FOREIGN_KEY_CHECKS = 1`) + }) } run().catch((err) => { diff --git a/backend/turbo.json b/backend/turbo.json index 9ba2f9dad..fb847307f 100644 --- a/backend/turbo.json +++ b/backend/turbo.json @@ -1,12 +1,16 @@ { "extends": ["//"], "tasks": { + "seed": { + "dependsOn": ["database#up", "^build"], + "cache": false + }, "locales": {}, "locales:fix": {}, "lint": { }, "lint:fix": { - }, + }, "test": { "dependsOn": ["database#up:backend_test", "^build"] }, diff --git a/database/src/seeds/seed.ts b/database/src/seeds/seed.ts deleted file mode 100644 index e551d7a61..000000000 --- a/database/src/seeds/seed.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { AppDatabase } from '../AppDatabase' -import { createCommunity } from './community' -import { userFactoryBulk } from './factory/user' -import { users } from './users' -import { internet, name } from 'faker' -import { creationFactoryBulk } from './factory/creation' -import { creations } from './creation' -import { transactionLinkFactoryBulk } from './factory/transactionLink' -import { transactionLinks } from './transactionLink' -import { contributionLinkFactory } from './factory/contributionLink' -import { contributionLinks } from './contributionLink' -import { User } from '../entity' -import { UserInterface } from './users/UserInterface' - -const RANDOM_USER_COUNT = 100 - -async function run() { - console.info('##seed## seeding started...') - - const db = AppDatabase.getInstance() - await db.init() - await clearDatabase() - - // seed home community - const homeCommunity = await createCommunity(false) - console.info(`##seed## seeding home community successful ...`) - - // seed standard users - // put into map for later direct access - const userCreationIndexedByEmail = new Map() - const defaultUsers = await userFactoryBulk(users, homeCommunity) - for (const dbUser of defaultUsers) { - userCreationIndexedByEmail.set(dbUser.emailContact.email, dbUser) - } - console.info(`##seed## seeding all standard users successful ...`) - - // seed 100 random users - const randomUsers = new Array(RANDOM_USER_COUNT) - for (let i = 0; i < RANDOM_USER_COUNT; i++) { - randomUsers[i] = { - firstName: name.firstName(), - lastName: name.lastName(), - email: internet.email(), - language: Math.random() < 0.5 ? 'en' : 'de', - } - } - await userFactoryBulk(randomUsers, homeCommunity) - console.info(`##seed## seeding ${RANDOM_USER_COUNT} random users successful ...`) - - // create GDD serial, must be called one after another because seeding don't use semaphore - const moderatorUser = userCreationIndexedByEmail.get('peter@lustig.de')! - await creationFactoryBulk(creations, userCreationIndexedByEmail, moderatorUser) - console.info(`##seed## seeding all creations successful ...`) - - // create Contribution Links - for (const contributionLink of contributionLinks) { - await contributionLinkFactory(contributionLink) - } - console.info(`##seed## seeding all contributionLinks successful ...`) - - // create Transaction Links - const movedTransactionLinks = transactionLinks.map(transactionLink => { - let createdAt = new Date(new Date().getTime() + 1000) - if (transactionLink.createdAt) { - createdAt = transactionLink.createdAt - } - return { - ...transactionLink, - createdAt: createdAt, - } - }) - await transactionLinkFactoryBulk(movedTransactionLinks, userCreationIndexedByEmail) - console.info(`##seed## seeding all transactionLinks successful ...`) - - await db.destroy() - console.info(`##seed## seeding successful...`) -} - -async function clearDatabase() { - await AppDatabase.getInstance().getDataSource().transaction(async trx => { - await trx.query(`SET FOREIGN_KEY_CHECKS = 0`) - await trx.query(`TRUNCATE TABLE contributions`) - await trx.query(`TRUNCATE TABLE contribution_links`) - await trx.query(`TRUNCATE TABLE users`) - await trx.query(`TRUNCATE TABLE user_contacts`) - await trx.query(`TRUNCATE TABLE user_roles`) - await trx.query(`TRUNCATE TABLE transactions`) - await trx.query(`TRUNCATE TABLE transaction_links`) - await trx.query(`TRUNCATE TABLE communities`) - await trx.query(`SET FOREIGN_KEY_CHECKS = 1`) - }) -} - -run().catch((err) => { - // biome-ignore lint/suspicious/noConsole: no logger present - console.error('error on seeding', err) -}) - diff --git a/database/turbo.json b/database/turbo.json index 7017e8542..a40c23229 100644 --- a/database/turbo.json +++ b/database/turbo.json @@ -1,10 +1,6 @@ { "extends": ["//"], "tasks": { - "seed": { - "dependsOn": ["database#up", "^build"], - "cache": false - }, "clear": { "cache": false },