app.post('job-offer', async (req, res) => {
return req.db.transaction(async (trx) => {
const jobOffer = await createJobOffer(trx, req.body)
})
})
// Transaction like is just a custom type, imagine it like `typeof db`
async function createJobOffer(trx: TransactionLike, data: any) {
const authorId = await upsertAuthor(trx, data.author)
const jobId = await upsertJobCategory(trx, data.job)
const jobOffer = await trx
.insert(jobOfferTable)
.values({...data, authorId, jobId})
.returning()
// now the same as in upsert job, we want to make the jobOffer more searchable
// so we want to trigger BullMQ queue that uses AI to generate tags,
// categories and embeddings for the jobOffer, only problem the jobOffer isn't committed yet so it wouldn't be available inside the job if it starts sooner
// so to fix this we could 'schedule it' with the 'afterCommit` hook
trx.afterCommit(() => generateJobOfferAttributesFlow.invoke(jobOffer.id))
return jobOffer
}
export async function upsertJobCategory(trx: TransactionLike, data: any) {
const existingJobCategory = await trx.select()....
if(existingJobCategory) return existingJob.id
// if job doesn't exist, create it
const jobCategory = await trx.insert()..
// now after we create new jobCategory, I want to trigger BullMQ queue that uses AI to generate tags,
// other attributes and embeddings for the jobCategory, only problem the transaction isn't committed yet, so if the generate flow starts sooner before the transaction commits, the newly created row wouldn't be available
// so to fix this we could 'schedule it' with the 'afterCommit` hook
trx.afterCommit(() => generateJobCategoryAttributesFlow.invoke(job.id))
return jobCategory.id
}