@accounter/server
Version:
Accounter GraphQL server
99 lines • 4.24 kB
JavaScript
import { GraphQLError } from 'graphql';
import { hashStringToInt } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { ChargesProvider } from '../../charges/providers/charges.provider.js';
import { getDocumentFromFile } from '../../documents/helpers/upload.helper.js';
import { DocumentsProvider } from '../../documents/providers/documents.provider.js';
import { suggestionDataSchema } from '../../financial-entities/helpers/business-suggestion-data-schema.helper.js';
import { BusinessesProvider } from '../../financial-entities/providers/businesses.provider.js';
const businessEmailConfig = async (_, { email }, { injector }) => {
const business = await injector.get(BusinessesProvider).getBusinessByEmail(email);
if (!business) {
return null;
}
let listenerConfig = {};
if (business?.suggestion_data) {
const { data, success, error } = suggestionDataSchema.safeParse(business.suggestion_data);
if (success) {
if (data.emailListener) {
listenerConfig = data.emailListener;
}
}
else {
console.error(`Invalid suggestion_data schema for business "${business.name}" [${business.id}]: ${JSON.stringify(error.issues)}`);
}
}
const listenerConfigRes = {
internalEmailLinks: listenerConfig.internalEmailLinks,
emailBody: listenerConfig.emailBody,
attachments: listenerConfig.attachments,
};
return {
...listenerConfigRes,
businessId: business.id,
};
};
const insertEmailDocuments = async (_, { documents, userDescription, messageId, businessId }, { injector }) => {
if (documents.length === 0) {
return true;
}
try {
const { ownerId } = await injector.get(AdminContextProvider).getVerifiedAdminContext();
const newDocuments = [];
await Promise.all(documents.map(async (doc) => {
const hash = hashStringToInt(await doc.text());
const existingDocument = await injector.get(DocumentsProvider).getDocumentByHash.load(hash);
if (existingDocument) {
console.log(`Document ${'name' in doc ? doc.name : 'unknown'} already exists in the database with id=${existingDocument.id}, skipping upload.`);
return;
}
const newDocument = await getDocumentFromFile(injector, doc, null, false, businessId ?? undefined, hash);
newDocuments.push({ ...newDocument, remarks: userDescription });
}));
if (newDocuments.length > 0) {
await injector.get(TenantAwareDBClient).transaction(async (client) => {
const charge = await injector
.get(ChargesProvider)
.generateCharge({
ownerId,
userDescription,
}, client)
.catch(e => {
throw new Error(`Error generating charge for email id=${messageId}: ${e}`);
});
if (!charge?.id) {
throw new Error(`Charge creation failed for email id=${messageId}`);
}
const documentsWithChargeId = newDocuments.map(doc => ({
...doc,
chargeId: charge.id,
}));
return await injector
.get(DocumentsProvider)
.insertDocuments({ documents: documentsWithChargeId }, client);
});
}
return true;
}
catch (error) {
console.error('Failed to insert email documents:', error);
if (error instanceof GraphQLError) {
throw error;
}
throw new GraphQLError(`Failed to insert email documents`, {
extensions: {
code: 'INTERNAL_SERVER_ERROR',
},
});
}
};
export const emailIngestionResolvers = {
Query: {
businessEmailConfig,
},
Mutation: {
insertEmailDocuments,
},
};
//# sourceMappingURL=email-ingestion.resolver.js.map