feat: add authenticated remote MCP access and complete business workflows
This commit is contained in:
1 parent
f40f4da781
commit
027a8c1b6a
35 files changed
+4430
-183
No files matched your search
@@ -1,13 +1,35 @@
|
||||
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
||||
import { PrismaClient, Prisma } from '@prisma/client';
|
||||
import { AsyncLocalStorage } from 'node:async_hooks';
|
||||
const transactions = new AsyncLocalStorage<Prisma.TransactionClient>();
|
||||
@Injectable()
|
||||
export class Database extends PrismaClient implements OnModuleInit, OnModuleDestroy {
|
||||
async serial<T>(work: (tx: Prisma.TransactionClient) => Promise<T>): Promise<T> {
|
||||
constructor() {
|
||||
super();
|
||||
return new Proxy(this, {
|
||||
get(target, key, receiver) {
|
||||
const tx = transactions.getStore();
|
||||
if (tx && key === '$transaction')
|
||||
return (work: any) => (typeof work === 'function' ? work(tx) : Promise.all(work));
|
||||
if (tx && key in tx && key !== '$disconnect' && key !== '$connect') {
|
||||
const value = (tx as any)[key];
|
||||
return typeof value === 'function' ? value.bind(tx) : value;
|
||||
}
|
||||
return Reflect.get(target, key, receiver);
|
||||
},
|
||||
});
|
||||
}
|
||||
async atomic<T>(work: () => Promise<T>, timeout = 30000): Promise<T> {
|
||||
return this.serial((tx) => transactions.run(tx, work), timeout);
|
||||
}
|
||||
async serial<T>(work: (tx: Prisma.TransactionClient) => Promise<T>, timeout = 30000): Promise<T> {
|
||||
const current = transactions.getStore();
|
||||
if (current) return work(current);
|
||||
for (let attempt = 0; ; attempt++) {
|
||||
try {
|
||||
return await this.$transaction(work, {
|
||||
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
|
||||
timeout: 30000,
|
||||
timeout,
|
||||
});
|
||||
} catch (error) {
|
||||
// Serializable deadlock/write conflict; retry the entire atomic operation.
|
||||
|
||||
Reference in new issue
Block a user