Matteo Di Paolantonio 23/04/2026
“Do not try and bend the spoon. That’s impossible. Instead, only try to realize the truth… there is no spoon.”
“If your values don’t cost you money, they’re just opinions.”
export default inngest.createFunction(
{ id: 'banks-sync', retries: 0 },
{ cron: 'TZ=Europe/Madrid 0 6,15 * * *' },
async ({ step }) => {
const connections = await step.run(`banks-sync-companies`, async () => {
log.info('start syncing bank data for each company via inngest')
return prisma.bankConnection.findMany()
})
await step.run('send-connections-bank-sync-events', async () => {
const events = connections.map((connection) => ({
name: 'bank/sync.requested',
data: { connectionUuid: connection.uuid },
}))
await inngest.send(events)
return { eventsSent: events.length }
})
return {
count: connections.length,
message: 'triggered syncing bank data for each company and bank',
}
}
)
model ErpContact {
uuid String @id @default(uuid())
externalSystem ErpExternalSystem
externalSystemId String
name String
code String?
email String?
country String?
zipCode String?
externalSystemDataHash String
erpConnectionUuid String
erpConnection ErpConnection
erpDocument ErpDocument[]
erpRecurringDocument ErpRecurringDocument[]
@@index([erpConnectionUuid])
@@index([erpConnectionUuid, name])
@@map("erp_contact")
}
const calculateDelta = <
T extends {
externalSystemId: string | null
internalId?: string
externalSystemDataHash: string
uuid: string
},
>(
fromDb: T[],
fromSource: T[],
key: keyof T,
): DeltaResult<T> => {
const fromDbMap = new Map(fromDb.map((item) => [item[key], item]))
const fromSourceMap = new Map(fromSource.map((item) => [item[key], item]))
const toCreate = fromSource.filter((item) => !fromDbMap.has(item[key]))
const toDelete = fromDb.filter((item) => !fromSourceMap.has(item[key]))
const toUpdate: T[] = []
fromDb.forEach((dbItem) => {
const sourceItem = fromSourceMap.get(dbItem[key])
if (
sourceItem &&
sourceItem.externalSystemDataHash !== dbItem.externalSystemDataHash
) {
const itemToUpdate = { ...sourceItem, uuid: dbItem.uuid }
toUpdate.push(itemToUpdate)
}
})
toDelete.forEach((deletedItem) => { fromDbMap.delete(deletedItem[key]) })
toUpdate.forEach((updatedItem) => { fromDbMap.set(updatedItem[key], updatedItem) })
toCreate.forEach((createdItem) => { fromDbMap.set(createdItem[key], createdItem) })
return { toCreate, toDelete, toUpdate, upToDate: Array.from(fromDbMap.values()) }
}
export async function getProfitAndLossReport({
companyGroupId,
date,
}: {
companyGroupId: string
date: string
}): Promise<CompanyGroupReport> {
const dateFrom = moment.utc(date).startOf('year')
const isCurrentYear = moment.utc().year() === moment.utc(date).year()
const ytdDate = moment.utc(date).subtract(1, 'month').endOf('month')
const dateTo = isCurrentYear ? ytdDate : moment.utc(date).endOf('year')
const companyUuids = await getCompanyIdsByCompanyGroupId(companyGroupId)
if (companyUuids.length === 0) {
return { success: false, reason: ErrorReason.UNAUTHORIZED }
}
try {
const companiesProfitAndLoss = await Promise.all(
companyUuids.map(async (companyUuid) =>
generateCompanyProfitAndLossReport({ companyUuid, dateFrom, dateTo })
)
)
return { success: true, data: companiesProfitAndLoss }
} catch (err) {
log.error(
{ err, company_group_uuid: companyGroupId },
'Error generating profit and loss report'
)
return { success: false, reason: ErrorReason.INTERNAL_ERROR }
}
}
// GET balance report by company group and year
export const GET = withAuth(
async (request, { user, log }, { params }: { params: Promise<Params> }) => {
try {
const { id: companyGroupId } = await params
const searchParams = new URL(request.url).searchParams
const companyId = searchParams.get('companyId')
if (!companyId) {
return NextResponse.json(
{ error: 'companyId query parameter is required' },
{ status: 400 }
)
}
await resolveAuthorizedCompanyScope({
user,
requestedCompanyGroupId: companyGroupId,
requestedCompanyIds: [companyId],
})
const yearParam = searchParams.get('year')
if (!yearParam) {
return NextResponse.json(
{ error: 'year query parameter is required' },
{ status: 400 }
)
}
const year = parseInt(yearParam, 10)
if (isNaN(year)) {
return NextResponse.json(
{ error: 'year must be a valid number' },
{ status: 400 }
)
}
const report = await balanceReportService.getBalanceReport(
companyId,
year
)
return NextResponse.json(report)
} catch (err) {
log.error({ err }, 'Error getting balance report')
return handleHttpError(err)
}
}
)
It doesn't scale → It scales according to the business
“You can take on all the technical tasks as a founder at the cost of time, or you can delegate to people better than you at the cost of money.”
“Doing the latest instead of always doing the same”
Claude, where were you?
What's left? Understanding the problem.
"Anyone can code" — but not anyone can understand what to build and why
The engineer who asks HOW
The engineer who asks WHY
“Do not try and bend the code. Instead, only try to realize the truth… there is no code without a WHY.”