fix some issues with seeded datas, and fix cross group balance

This commit is contained in:
einhornimmond 2026-02-27 16:31:51 +01:00
parent bfa53d9604
commit b94d6ae89a
5 changed files with 48 additions and 68 deletions

View File

@ -86,6 +86,7 @@ async function clearDatabase(db: AppDatabase) {
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 events`)
await trx.query(`TRUNCATE TABLE users`)
await trx.query(`TRUNCATE TABLE user_contacts`)
await trx.query(`TRUNCATE TABLE user_roles`)

View File

@ -9,9 +9,8 @@ import { KeyPairCacheManager } from '../../cache/KeyPairCacheManager'
import { CONFIG } from '../../config'
import { LOG4JS_BASE_CATEGORY } from '../../config/const'
import { Uuidv4 } from '../../schemas/typeGuard.schema'
import { loadUserByGradidoId } from './database'
import { bytesToMbyte } from './utils'
import { CommunityContext, UserDb } from './valibot.schema'
import { CommunityContext } from './valibot.schema'
dotenv.config()
@ -20,21 +19,18 @@ export class Context {
public db: MySql2Database
public communities: Map<string, CommunityContext>
public cache: KeyPairCacheManager
public balanceFixGradidoUser: UserDb | null
private timeUsed: Profiler
constructor(
logger: Logger,
db: MySql2Database,
cache: KeyPairCacheManager,
balanceFixGradidoUser: UserDb | null,
cache: KeyPairCacheManager
) {
this.logger = logger
this.db = db
this.cache = cache
this.communities = new Map<string, CommunityContext>()
this.timeUsed = new Profiler()
this.balanceFixGradidoUser = balanceFixGradidoUser
}
static async create(): Promise<Context> {
@ -49,21 +45,7 @@ export class Context {
})
const db = drizzle({ client: connection })
const logger = getLogger(`${LOG4JS_BASE_CATEGORY}.migrations.db-v2.7.0_to_blockchain-v3.5`)
let balanceFixGradidoUser: UserDb | null = null
if (process.env.MIGRATION_ACCOUNT_BALANCE_FIX_GRADIDO_ID) {
balanceFixGradidoUser = await loadUserByGradidoId(
db,
process.env.MIGRATION_ACCOUNT_BALANCE_FIX_GRADIDO_ID,
)
if (!balanceFixGradidoUser) {
logger.error(
`MIGRATION_ACCOUNT_BALANCE_FIX_GRADIDO_ID was set to ${process.env.MIGRATION_ACCOUNT_BALANCE_FIX_GRADIDO_ID} but user not found`,
)
}
} else {
logger.debug(`MIGRATION_ACCOUNT_BALANCE_FIX_GRADIDO_ID was not set`)
}
return new Context(logger, db, KeyPairCacheManager.getInstance(), balanceFixGradidoUser)
return new Context(logger, db, KeyPairCacheManager.getInstance())
}
getCommunityContextByUuid(communityUuid: Uuidv4): CommunityContext {

View File

@ -1,4 +1,4 @@
import { asc, eq, isNotNull, sql } from 'drizzle-orm'
import { and, asc, eq, isNotNull, isNull, or, sql } from 'drizzle-orm'
import { MySql2Database } from 'drizzle-orm/mysql2'
import * as v from 'valibot'
import { communitiesTable, eventsTable, userRolesTable, usersTable } from './drizzle.schema'
@ -14,7 +14,7 @@ export async function loadContributionLinkModeratorCache(db: MySql2Database): Pr
user: usersTable,
})
.from(eventsTable)
.leftJoin(usersTable, eq(eventsTable.actingUserId, usersTable.id))
.innerJoin(usersTable, eq(eventsTable.actingUserId, usersTable.id))
.where(eq(eventsTable.type, 'ADMIN_CONTRIBUTION_LINK_CREATE'))
.orderBy(asc(eventsTable.id))
@ -33,7 +33,7 @@ export async function loadAdminUsersCache(db: MySql2Database): Promise<void> {
})
.from(userRolesTable)
.where(eq(userRolesTable.role, 'ADMIN'))
.leftJoin(usersTable, eq(userRolesTable.userId, usersTable.id))
.innerJoin(usersTable, eq(userRolesTable.userId, usersTable.id))
result.map((row: any) => {
adminUsers.set(row.gradidoId, v.parse(userDbSchema, row.user))
@ -52,8 +52,12 @@ export async function loadCommunities(db: MySql2Database): Promise<CommunityDb[]
userMinCreatedAt: sql`MIN(${usersTable.createdAt})`,
})
.from(communitiesTable)
.leftJoin(usersTable, eq(communitiesTable.communityUuid, usersTable.communityUuid))
.where(isNotNull(communitiesTable.communityUuid))
.innerJoin(usersTable, eq(communitiesTable.communityUuid, usersTable.communityUuid))
.where(
and(
isNotNull(communitiesTable.communityUuid),
sql`${usersTable.createdAt} > '2000-01-01'`),
)
.orderBy(asc(communitiesTable.id))
.groupBy(communitiesTable.communityUuid)
@ -61,16 +65,3 @@ export async function loadCommunities(db: MySql2Database): Promise<CommunityDb[]
return v.parse(communityDbSchema, row)
})
}
export async function loadUserByGradidoId(
db: MySql2Database,
gradidoId: string,
): Promise<UserDb | null> {
const result = await db
.select()
.from(usersTable)
.where(eq(usersTable.gradidoId, gradidoId))
.limit(1)
return result.length ? v.parse(userDbSchema, result[0]) : null
}

View File

@ -125,39 +125,44 @@ export class RemoteTransactionsSyncRole extends AbstractSyncRole<TransactionDb>
publicKey: MemoryBlockPtr,
): AccountBalances {
this.accountBalances.clear()
if (communityContext.foreign) {
this.accountBalances.add(new AccountBalance(publicKey, GradidoUnit.zero(), coinCommunityId))
return this.accountBalances
} else {
// try to use same coins from this community
let lastBalance = this.getLastBalanceForUser(
// try to use same coins from this community
let lastBalance = this.getLastBalanceForUser(
publicKey,
communityContext.blockchain,
coinCommunityId,
)
if (
coinCommunityId != communityContext.communityId &&
(
lastBalance.getBalance().equal(GradidoUnit.zero()) ||
lastBalance.getBalance().calculateDecay(lastBalance.getDate(), item.balanceDate).lt(amount))
) {
// don't work, so we use or own coins
lastBalance = this.getLastBalanceForUser(
publicKey,
communityContext.blockchain,
coinCommunityId,
communityContext.communityId,
)
if (
lastBalance.getBalance().equal(GradidoUnit.zero()) ||
lastBalance.getBalance().calculateDecay(lastBalance.getDate(), item.balanceDate).lt(amount)
) {
// don't work, so we use or own coins
lastBalance = this.getLastBalanceForUser(
publicKey,
communityContext.blockchain,
communityContext.communityId,
)
}
try {
lastBalance.updateLegacyDecay(amount, item.balanceDate)
} catch (e) {
if (e instanceof NegativeBalanceError) {
this.logLastBalanceChangingTransactions(publicKey, communityContext.blockchain, 1)
throw e
}
}
this.accountBalances.add(lastBalance.getAccountBalance())
}
if (
lastBalance.getBalance().calculateDecay(lastBalance.getDate(), item.balanceDate).add(amount).lt(GradidoUnit.zero())
&& communityContext.foreign
) {
this.accountBalances.add(new AccountBalance(publicKey, GradidoUnit.zero(), coinCommunityId))
return this.accountBalances
}
try {
lastBalance.updateLegacyDecay(amount, item.balanceDate)
} catch (e) {
if (e instanceof NegativeBalanceError) {
this.logLastBalanceChangingTransactions(publicKey, communityContext.blockchain, 1)
throw e
}
}
this.accountBalances.add(lastBalance.getAccountBalance())
return this.accountBalances
}
getUser(item: TransactionDb): { senderUser: UserDb; recipientUser: UserDb } {

View File

@ -1,4 +1,4 @@
import { and, asc, eq, gt, or } from 'drizzle-orm'
import { and, asc, eq, gt, isNotNull, or } from 'drizzle-orm'
import {
AccountBalance,
AccountBalances,
@ -51,6 +51,7 @@ export class UsersSyncRole extends AbstractSyncRole<UserDb> {
gt(usersTable.id, lastIndex.id),
),
),
isNotNull(usersTable.communityUuid)
),
)
.orderBy(asc(usersTable.createdAt), asc(usersTable.id))