first commit for refactored project

This commit is contained in:
KS Jannette
2026-05-23 17:08:47 -04:00
commit 6545f8f549
166 changed files with 48911 additions and 0 deletions

65
ax3Services/.gitignore vendored Normal file
View File

@@ -0,0 +1,65 @@
**/__pycache__/
bin/
build/
dist/
*.pyc
*.pyo
**/env/
env/
.env
mCovo.py
secrets_1.py
lib/
lib64/
parts/
sdist/
var/
pip-log.txt
pip-delete-this-directory.txt
node_modules
node_modules/
*node_modules
node_modules*
*node_modules*
Client/node_modules
*Documents/
*Converted/
*Documents/Converted
*Documents/Converted/
Documents/Converted
Documents/Converted/*
Backend/Documents
Backend/Documents*
*PNG
*png
*pdf
*pdf
*.PNG
*.png
*.pdf
*.pdf
.vscode
Docx
lib64
lib64/
*lib64
./Backend/EditedCompletions/
*EditedCompletions/
Createtemp
Doctemp
Docxfinal
*Docx*
./Docx
secrets.js
firebase/secrets.js
./Backend/firebase/secrets.js
*secrets.js
Backend/firebase/secrets.js
/firebase/agentx2-firebase-adminsdk.json
/agent/secrets_1.js
anImporter.cjs
logger/logs/*
logger/
logger/logs/error.log

View File

@@ -0,0 +1,10 @@
export const rogInstructions = [
{
interrogatoryId: "c42293a4-77fd-4c1f-926d-72c36af01298",
text: "Identify the indivudal responding to these reusts. Set forth the indivdual's name, address, telephone number.",
},
{
interrogatoryId: "17822ae2-d8ae-4d76-aff6-2c0740d7ba0e",
text: "For the person verifying these answers, state the date of first employment with you, and the datesand titles of each job position the person has held while employed by you.",
},
];

View File

@@ -0,0 +1,764 @@
const fs = require("fs");
const path = require("path");
const { updateDB } = require("../firebase/firebase.js");
const OpenAI = require("openai");
const {
iteratePathsReturnString,
makeDir,
saveCompletions,
selectRequestPath,
selectResponsePath,
} = require("./utilities.js");
const {
createArrayFromSingleDocPrompt,
createResponseFromOneQuestionPrompt,
createArrayOfInterrogatoriesPlaintiffPrompt,
createArrayOfInterrogatoriesDefendantPrompt,
createVerboseResponseFromOneQuestionPrompt,
createArrayFromStringBlobPrompt,
} = require("./promptTemplates.js");
const { OPENAI_API_KEY } = require("./secrets_1.js");
const { v4: uuidv4 } = require("uuid");
const dJSON = require("dirty-json");
const openai = new OpenAI({
apiKey: OPENAI_API_KEY,
});
class ModelController {
/*
* LLM PROMPT CONTROLLER
* RETURNS ANSWERS FROM JSON ARRAY OF REQUEST Qs
*
*/
async arrayGenAnswers(docId, reqType, isRequests) {
/*
const basePath = process.cwd();
if (reqType == "combined-numbered") {
filePath = `${basePath}/Documents/Requests/combined-numbered/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "interrogatories") {
filePath = `${basePath}/Documents/Requests/interrogatories/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "admissions") {
filePath = `${basePath}/Documents/Requests/admissions/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "production") {
filePath = `${basePath}/Documents/Requests/production/${docId}/${docId}-jbk-parsedRequests.json`;
}
*/
const filePath = path.join(
__dirname,
"..",
"Documents",
"Requests",
`${reqType}`,
`${docId}`,
`${docId}-jbk-parsedRequests.json`
);
console.log(
"**arrayGenAnswers ------------------------- reqType, isRequests",
reqType,
isRequests
);
const fileData = fs.readFileSync(filePath, "utf8");
const rogs = await JSON.parse(fileData);
const requests = rogs[0].requests;
let completions;
if (reqType == "combined-numbered") {
completions = await this.start(requests, reqType, isRequests);
} else {
completions = await this.start(requests, reqType, isRequests);
}
//moved makedir up - race condition
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
"Responses",
`${reqType}`,
`${docId}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("arrayGenAnswers error creating directory: " + err);
}
});
let masterArray = [];
const completionsArray = [];
const completionsObject = { type: `response to ${reqType}` };
const finalArray = completions[0];
let temp;
finalArray?.forEach((comp) => {
let obj = {};
const responseId = uuidv4();
obj["responseId"] = responseId;
obj["text"] = comp;
completionsArray.push(obj);
});
completionsObject["responses"] = completionsArray;
masterArray.push(completionsObject);
temp = docId;
temp = masterArray;
const data = JSON.stringify(temp);
const fileSuffix = "-jbk-responses.json";
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log("arrayGenAnswers err in writeFile:", err);
}
}
);
updateDB(docId, reqType);
return temp;
}
/*
* LLM PROMPT CONTROLLER
*
* FOR docPARSER FAILS(?)/docCLASSIFIER DETERMINES COMBINED-NUMBERED
* CREATES JSON ARRAY OF QUESTIONS FROM STRING BLOB OF INCOMING REQ
*/
async createArrayOfQuestions(docId, reqType, isRequests, countObject) {
const masterArray = [];
//const clientPosition = countObject.clientPosition;
console.log(
"----------------------------------------------------------------------"
);
console.log("createArrayOfQuestions docId:", docId);
console.log("createArrayOfQuestions reqType:", reqType);
console.log("createArrayOfQuestions isRequests:", isRequests);
console.log(
"----------------------------------------------------------------------"
);
const directionVar = isRequests ? "Requests" : "Responses";
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
"Requests",
`${reqType}`,
`${docId}`
);
const dirPath = path.join(
__dirname,
"..",
"Documents",
"Textfiles",
`${docId}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("arrayGenAnswers error creating directory: " + err);
}
});
let fileNames = fs.readdirSync(dirPath);
const dirArray = fileNames.map((name) => {
return `${dirPath}/${name}`;
});
let requestStr;
let completes;
let newArray = [];
let flatReq;
let parsedRequests = [];
if (dirArray.length > 12) {
const splitAt = Math.floor(dirArray.length / 2);
const temp1 = dirArray.slice(0, splitAt);
const temp2 = dirArray.slice(splitAt, dirArray.length);
newArray.push(temp1);
newArray.push(temp2);
completes = await Promise.all(
newArray.map(async (arr) => {
requestStr = await iteratePathsReturnString(arr);
const comp = await this.startOne(requestStr, reqType, isRequests);
return comp;
})
);
let fooz = null;
let barz = null;
try {
try {
fooz = JSON.parse(completes[0]);
if (!fooz) {
fooz = dJSON.parse(completes[0]);
}
} catch (err) {
console.log("err in first fooz try", err);
}
} catch (err) {
console.log("Error in createArrayOfQuestions at :", err);
}
try {
try {
barz = JSON.parse(completes[1]);
if (!barz) {
fooz = dJSON.parse(completes[1]);
}
} catch (err) {
console.log("err in first barz try", err);
}
} catch (err) {
console.log("Error in createArrayOfQuestions :", err);
}
fooz.forEach((item) => {
parsedRequests.push(item);
});
barz.forEach((item) => {
parsedRequests.push(item);
});
} else {
requestStr = await iteratePathsReturnString(dirArray);
flatReq = await this.startOne(requestStr, reqType, isRequests);
try {
parsedRequests = JSON.parse(flatReq);
} catch (err) {
console.log(
"Error parsing json in ModelController.createArrayOfQuestions: ",
err
);
}
}
const completionsObject = { type: "combined-numbered" };
completionsObject["requests"] = parsedRequests;
masterArray.push(completionsObject);
let temp = docId;
temp = masterArray;
const fileSuffix = isRequests
? "-jbk-parsedRequests.json"
: "-jbk-responses.json";
const data = JSON.stringify(temp);
//change back
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log("arrayGenAnswers err in writeFile:", err);
}
}
);
updateDB(docId, reqType);
return temp;
}
//****************** Create Array of Interrogatories from Complaint **********************/
async createArrayOfInterrogatories(
docId,
clientPosition,
reqType = "interrogatories-out"
) {
const masterArray = [];
const isRequests = false;
const fdirup = path.resolve(
process.cwd() + `/Documents/Textfiles/${docId}/`
);
console.log(
"****************** Create Array of Interrogatories from Complaint fdirup for text files:",
fdirup
);
const dirPath = `../Documents/Textfiles/${docId}/`;
let fileNames = fs.readdirSync(fdirup);
const dirArray = fileNames.map((name) => {
return `${fdirup}/${name}`;
});
let requestStr;
let completes;
let newArray = [];
let flatReq;
let parsedRequests = [];
if (dirArray.length > 10) {
const splitAt = Math.floor(dirArray.length / 2);
const temp1 = dirArray.slice(0, splitAt);
const temp2 = dirArray.slice(splitAt, dirArray.length);
newArray.push(temp1);
newArray.push(temp2);
completes = await Promise.all(
newArray.map(async (arr) => {
requestStr = await iteratePathsReturnString(arr);
const comp = await this.startOne(
requestStr,
reqType,
isRequests,
reqType
);
return comp;
})
);
let fooz = JSON.parse(completes[0]);
let barz = JSON.parse(completes[1]);
fooz.forEach((item) => {
parsedRequests.push(item);
});
barz.forEach((item) => {
parsedRequests.push(item);
});
} else {
requestStr = await iteratePathsReturnString(dirArray);
flatReq = await this.startOneCreateOutgoing(
requestStr,
reqType,
isRequests,
clientPosition
);
try {
if (flatReq) {
parsedRequests = JSON.parse(flatReq);
}
} catch (err) {
console.log(
"Error parsing json in ModelController.createArrayOfQuestions: ",
err
);
}
}
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
"RequestsOut",
`${docId}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("makeDir utilities error creating directory: " + err);
}
});
const completionsObject = { type: "interrogatories-out" };
completionsObject["requests"] = parsedRequests;
masterArray.push(completionsObject);
let temp = docId;
temp = masterArray;
const data = JSON.stringify(temp);
const fileSuffix = "-jbk-requests-out.json";
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
await sleep(1000);
try {
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
console.log(
"Error in createArrayOfInterrogatories writeFile:",
err
);
}
}
);
} catch (err) {
console.log("Error writing file in createArrayOfInterrogatories:", err);
}
//updateDB(docId, reqType); //need to fix
return temp;
}
/*
* LLM PROMPT CONTROLLER
* RETURNS REQUESTS FROM STRING BLOB
* FOR VERY LONG REQUEST DOCUMENTS
* (> 50 pages?? ... guestimate; determined by timer in tesseWatcher)
*/
async createArrayOfQuestionsLarge(docId, reqType) {
const masterArray = [];
const isRequests = true;
const dirPath = `../Documents/Textfiles/${docId}/`;
let fileNames = fs.readdirSync(dirPath);
const dirArray = fileNames.map((name) => {
return dirPath + name;
});
let requestStr;
let completes;
let newArray = [];
let flatReq;
let parsedRequests = [];
const arrSize = 20;
while (dirArray.length > 0) {
newArray.push(dirArray.splice(0, arrSize));
}
completes = await Promise.all(
newArray.map(async (arr) => {
requestStr = await iteratePathsReturnString(arr);
const comp = await this.startOne(requestStr, reqType, isRequests);
return comp;
})
);
const num = newArray.length - 1;
for (let i = 0; i < num; i++) {
try {
let temp = dJSON.parse(completes[i]);
temp.forEach((item) => {
parsedRequests.push(item);
});
} catch (err) {
console.log(
`Error parsing JSON in completions for item at index no ${i}`,
err
);
}
}
/*
const foo = dJSON.parse(completes[0]);
const bar = dJSON.parse(completes[1]);
console.log("foo", foo);
parsedRequests = completes.flat(Infinity);
parsedRequests = foo.concat(bar);
*/
const directionVar = isRequests ? "Requests" : "Responses";
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
`${directionVar}`,
`${reqType}`,
`${docId}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("makeDir utilities error creating directory: " + err);
}
});
const completionsObject2 = { type: "combined-numbered" };
completionsObject2["requests"] = parsedRequests;
masterArray.push(completionsObject2);
let temp2 = docId;
temp2 = masterArray;
const fileSuffix = isRequests
? "-jbk-parsedRequests.json"
: "-jbk-responses.json";
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log(
"createArrayOfQuestionsLargeError in writeFile:",
err
);
}
}
);
updateDB(docId, reqType);
return temp2;
}
/*
* LLM PROMPT CYCLE
* CREATE RESPONSES TO JSON ARRAY OF REQUEST Qs
*
*/
async start(requests, reqType) {
const answersResponses = await Promise.all(
requests.map(async (request) => {
const prompt = createVerboseResponseFromOneQuestionPrompt(request.text);
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: prompt,
});
console.log("completion.choices[0].message.content");
return completion.choices[0].message.content;
})
);
const fooBar = [];
fooBar.push(answersResponses);
fooBar.push(reqType);
return fooBar;
}
/*
* LLM PROMPT CYCLE
* PULL ARRAY OF Qs FROM STRING BLOB OF INCOMING REQUEST DOC
*
*/
async startOne(requestStr, reqType, isRequests) {
let prompt;
if (reqType === "interrogatories-out") {
//prompt = createArrayOfInterrogatoriesPrompt(request);
} else {
prompt = createArrayFromStringBlobPrompt(requestStr);
}
//prompt = createArrayOfInterrogatoriesPlaintiffPrompt(requestStr);
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: prompt,
});
console.log(
"completion.choices[0].message.content",
completion.choices[0].message.content
);
return completion.choices[0].message.content;
}
/*
* LLM PROMPT CYCLE
* CREATE OUTGOING REQUESTS FROM COMPLAINT
*
*/
async startOneCreateOutgoing(
requestStr,
reqType,
isRequests,
clientPosition
) {
let prompt;
if (clientPosition?.toLowerCase() === "plaintiff") {
prompt = createArrayOfInterrogatoriesPlaintiffPrompt(requestStr);
} else {
prompt = createArrayOfInterrogatoriesDefendantPrompt(requestStr);
}
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: prompt,
});
console.log(
"completion.choices[0].message.content",
completion.choices[0].message.content
);
return completion.choices[0].message.content;
}
// for development
async testSaveFunction(docId, reqType, isRequests) {
const directionVar = isRequests ? "Requests" : "Responses";
const temp = [
{ one: "one", two: "two", three: "three", four: "ddd", five: "mmm" },
];
const data = JSON.stringify(temp);
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
`${directionVar}`,
`${reqType}`,
`${docId}`
);
const fileSuffix = isRequests
? "-jbk-parsedRequests.json"
: "-jbk-responses.json";
console.log("-----------------------------------------");
console.log("saveDirectory:", saveDirectory);
console.log("-----------------------------------------");
console.log(
"saveDirectory AND FILE",
`${saveDirectory}/${docId}${fileSuffix}`
);
console.log("-----------------------------------------");
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log(
"createArrayOfQuestionsLargeError in writeFile:",
err
);
}
}
);
}
}
module.exports = new ModelController();
/* ******** **************************************************************************
fs.writeFile(
`/Users/kjannette/workspace/ax3/ax3Services/Documents/Requests/${reqType}/${docId}`,
data,
(err) => {
console.log("test err:", err);
}
);
* LLM PROMPT CONTROLLER
* CREATES ANSWERS FROM ARRAY OF REQUESTS - COMBINED TYPE
*
async arrayGenAnswersCombined(docId, reqType, isRequests) {
let filePath;
const basePath = process.cwd();
if (reqType == "combined-numbered") {
filePath = `${basePath}/Documents/Requests/Parsedcombined/${docId}/${docId}-jbk-parsedRequests.json`;
//filePath = `${basePath}/Documents/Requests/Parsedcombined/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "interrogatories") {
filePath = `${basePath}/Documents/Requests/Parsedrogs/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "admissions") {
filePath = `${basePath}/Documents/Requests/Parsedadmit/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "production") {
filePath = `${basePath}/Documents/Requests/Parsedprod/${docId}/${docId}-jbk-parsedRequests.json`;
}
const path = path.join(
__dirname,
"..",
"Documents",
"Requests",
`${reqType}`,
`${docId}`
);
const fileData = fs.readFileSync(
`${path}/${docId}-jbk-parsedRequests.json`,
"utf8"
);
const rogs = await JSON.parse(fileData);
const requests = rogs[0].requests;
let completions;
completions = await this.start(requests, reqType, isRequests);
let masterArray = [];
const completionsArray = [];
const completionsObject = { type: `response to ${reqType}` };
const finalArray = completions[0];
finalArray?.forEach((comp) => {
console.log("comp", comp);
let obj = {};
const responseId = uuidv4();
obj["responseId"] = responseId;
obj["text"] = comp;
completionsArray.push(obj);
});
completionsObject["responses"] = completionsArray;
masterArray.push(completionsObject);
const directionVar = isRequests ? "Requests" : "Responses";
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
`${directionVar}`,
`${reqType}`,
`${docId}`
);
const fileSuffix = isRequests
? "-jbk-parsedRequests.json"
: "-jbk-responses.json";
let temp;
temp = docId;
temp = masterArray;
return temp;
}
async combinedGenAnswers(docId, reqType, isRequests) {
console.log(
"_____________________________________________________________ fired combinedGenAnswers"
);
const masterArray = [];
let dirPath;
if (reqType === "combined-numbered") {
dirPath = `../Documents/Textfiles/${docId}/`;
} else {
//
}
let fileNames = fs.readdirSync(dirPath);
const dirArray = fileNames.map((name) => {
return dirPath + name;
});
const requestString = iteratePathsReturnString(dirArray);
const completions = await this.startOne(requestString, reqType, isRequests); //START
const completionsObject = { type: `response to combined-requests` };
completionsObject["responses"] = completions;
masterArray.push(completionsObject);
const directionVar = isRequests ? "Requests" : "Responses";
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
`${directionVar}`,
`${reqType}`,
`${docId}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("makeDir utilities error creating directory: " + err);
}
});
temp = docId;
temp = masterArray;
const data = JSON.stringify(temp);
const fileSuffix = isRequests
? "-jbk-parsedRequests.json"
: "-jbk-responses.json";
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log("Error in saveCompletions writeFile:", err);
}
}
);
return temp;
}
*/

View File

@@ -0,0 +1,137 @@
/// this is used when you already ahve an array of questions -- plain old answers
const createResponseFromOneQuestionPrompt = (request) => {
const regularPrompt = [
{
role: "user",
content: `You are a paralegal assisting trial attorneys in drafting discovery responses, including interrogatories, requests for production and requests for admissions. Draft a response to the following request. Include only objections, but thoroughly include all possible, non-frivolous, objections. Do not assume facts about the case. Refer to our client, who is responding here, as 'Respondent'. Begin each response with "RESPONDENT OBJECTS TO THE REQUEST" (or, where appropriate, "RESPONDENT FURTHER OBJECTS" which should always be uppersace and always start on a new line). Do not preface or suffix your response with observations, notes, analysis or comments. Do not add any signature block, such as 'Executed on this __ day of _______, 20__.'. Do not preface any response with numbering, such as 'RESPONSE NO. 1'. End each response with 'SUBJECT TO AND WITHOUT WAIVING these objections, Respondent states as follows:' then stop there, write nothing further. This is the request:${request}`,
},
];
return regularPrompt;
};
const createVerboseResponseFromOneQuestionPrompt = (request) => {
const verbosePrompt = [
{
role: "user",
content: `You are a paralegal assisting trial attorneys in drafting discovery responses, including interrogatories, requests for production and requests for admissions. Draft a response to the following request. In responding, first state applicable objections. Be sure to thoroughly include all possible, non-frivolous, objections. Refer to our client, who is responding here, as 'Respondent'. Begin each response with "RESPONDENT OBJECTS TO THE REQUEST" (or, where appropriate, "RESPONDENT FURTHER OBJECTS" (which should always be uppercase and always start on a new line). Once you have stated the objections, then continue with 'SUBJECT TO AND WITHOUT WAIVING these objections, Respondent states as follows:' and state your substantive response. Do not preface or suffix your response with observations, notes, analysis or comments. Do not add any signature block, such as 'Executed on this __ day of _______, 20__.'. Do not preface any response with numbering, such as 'RESPONSE NO. 1'. This is the request: ${request}`,
},
];
return verbosePrompt;
};
// create an array of the questions for a combined numbered type
const createArrayFromSingleDocPrompt = (request) => {
console.log(">>9980989cteArrayFromSingleDocPrompt FIRED~~~~~~~~~~~~~~~~~~~");
const parseRequestsPrompt = [
{
role: "user",
content: `You are an AI paralegal assisting attorneys in drafting discovery requests. Your firm represents the defendant in a lawsuit against it for an injury
allegedly sustained by the plaintiff. To prevail, the plaintiff must prove that 1. your client owed him/her a duty of care, 2. breached that duty, and
3. the breach was the proximate (direct) cause of his/her 4. actual damages (actual damages must be proven). It is the plaintiffs duty to prove each of those elements.
It is not the defendant's duty to disprove them. I will provide you with the complaint filed in court, then some technical instructions.
Review the complaint carefully. Asd you do, think about the facts the plaintiff will need to prove to satisfy each of those four elements.
Then, draft 20 interrogatories. They should seek all evidence the plaintiff has in his/her possession to prove the claim. The technical instructions: return the
interrogatories in JSON format. The JSON should be in the form of an array of objects. There should be one object for each interrogatory The object should contain
two key/value pairs: first, “requestId": this key's value will be a randomly generated version 4 UUID The second key is ”text": its value will be the substantive
content of the individual interrogatory. This is an example sequence of three interrogatories: [{ "requestId": "73a855af-4fdc-4b8b-9e7f-34d57a2c084a",
"text": "example - Please identify the person or persons responding to these Interrogatories, and identify each person who has provided information in connection
with these Interrogatories.”}, { "requestId": "36fe8375-240d-4a08-8a71-9b2ba5bda348", "text": "example - Identify the owner of the premises described in complaint."},
{ "requestId": "cfaf4a36-20de-44ff-8673-5a725bddca03", "text": "example - Identify any person not already named as a party to this lawsuit whom you contend caused
or contributed to the occurrence which you contend proximately caused your injuries and/or other damages .“}]. Lastly, do not add introductory comments, analysis,
or observations. Return only the interrogatories in the manner previously described. This is the complaint: ${complaint}`,
},
];
return parseRequestsPrompt;
};
const createArrayOfInterrogatoriesPlaintiffPrompt = (complaint) => {
console.log(
"createArrayOfInterrogatoriesPlaintiffPrompt fired-----------------------------------------"
);
const parseRequestsPrompt = [
{
role: "user",
content: `You are an AI paralegal assisting attorneys in drafting discovery requests. You represent the plaintiff in a negligence lawsuit. To prevail, the plaintiff must satisfy these legal elements: 1) the defendant owed it a duty of care, 2) the defendant breached that duty; 3) which was the proximate cause of 4) plaintiffs damages (typically physical injuries, may include losses stemming from injuries, i.e. lost wages).
Your task is to draft ten (10) interrogatories to the defendant. I will provide technical instructions and the Complaint (for background). Review the complaint carefully, thinking about the above legal elements stated, and what facts would satisfy them. Then, think about the information the defendant might possess that would satisfy them. That is the information you seek.
The technical instructions: return interrogatories in JSON format. The JSON should be an array of objects, with one object for each interrogatory. An object will contain two key/value pairs: First key: “requestId", value: a random version 4 UUID Second key is ”text", its value is the individual interrogatory. I will give you examples of the form. They are hypothetical in substance, (not necessarily similar to this cases facts).
Use them to think about the legal writing style youll employ. (Reference to paragraphs of a complaint in the examples are hypothetical and for illustration. They do not refer to the facts in this case. However, if they are similar, you may reuse/paraphrase them.) THIS IS IMPORTANT, FOLLOW THIS INSTRUCTION: Accurately cite the complaint where appropriate, using the phrase 'as set forth in paragraph <you will insert appropriate number(s) here> of the complaint'. Do not include foundational questions in your interrogatories, such as asking the respondents name, address, age, etc. These will be supplied elsewhere.
Do not add introductory comments, analysis, or observations, such as "Based on your request, I have parsed the complaint and..," etc. This will be problematic for later data processing. Here are the examples:
[{ "requestId": "73a855af-4fdc-4b8b-9e7f-34d57a2c084a", "text": "Give a detailed statement of how you contend the occurrence took place, including where you were traveling from and traveling to, any stops made along the way, the date, time, location of the accident.”}, { "requestId": "36fe8375-240d-4a08-8a71-9b2ba5bda348", "text": "State whether you were the driver and/or owner of the vehicle involved in the occurrence on the date,
time and location as outlined in the Complaint. If you were not the driver, then state who you claim was driving the vehicle.”}, { "requestId": "cfaf4a36-20de-44ff-8673-5a725bddca03",
"text": "If you were employed at the time of the occurrence, as indicated in the Complaint, and working within the scope of that employment when the occurrence took place, identify your employer and the nature of the work you were performing.“}]. This is the complaint: ${complaint}`,
},
];
return parseRequestsPrompt;
};
const createArrayOfInterrogatoriesDefendantPrompt = (complaint) => {
console.log(
"createArrayOfInterrogatoriesDefendantPrompt fired-----------------------------------------"
);
const parseRequestsPrompt = [
{
role: "user",
content: `You are an AI paralegal assisting attorneys in drafting discovery requests. You represent the defendant in a negligence lawsuit. To prevail, the plaintiff must show facts sufficient to satisfy these legal elements: 1) the defendant owed it a duty of care, 2) the defendant breached that duty, which 3) was the proximate cause, of 4) plaintiffs damages (typically physical injuries, and may include losses stemming from injuries, i.e. lost wages).
Your task is to draft ten (10) interrogatories to the plaintiff. I will provide technical instructions and the Complaint (for background). Review the Complaint carefully, thinking about the above legal elements, and what facts the plaintiff must prove to satisfy them. That is the information you seek. In other words, the interrogatories goal is to discover if the plaintiff can prove its case.
The technical instructions: return the ten (10) interrogatories in JSON format. The JSON should be an array of objects, with one object for each interrogatory. An object will contain two key/value pairs: First key: “requestId", value: a random version 4 UUID Second key is ”text", its value is the individual interrogatory. I will give you examples. They are hypothetical in substance, not necessarily similar to this cases facts. Use them to think about the legal writing style youll employ. (Reference to paragraphs of a complaint in the examples are hypothetical and for illustration. They do not refer to the facts in this case. However, if they are similar, you may reuse/paraphrase them.) THIS IS IMPORTANT, FOLLOW THIS INSTRUCTION: Accurately cite the Complaint where appropriate, using the phrase 'as set forth in paragraph(s) <you will insert appropriate number(s) here> of the Complaint.' Do not include foundational questions in your interrogatories, such as asking the respondents name, address, age, etc. These will be supplied elsewhere.
Do not add introductory comments, analysis, or observations, such as "Based on your request, I have parsed the Complaint and..," etc. This will be problematic for later data processing. Here are the examples:
[{ "requestId": "73a855af-4fdc-4b8b-9e7f-34d57a2c084a", "text": "Give a detailed statement of how you contend the occurrence took place, including where you were traveling from and traveling to, any stops made along the way, the date, time, location of the accident.”}, { "requestId": "36fe8375-240d-4a08-8a71-9b2ba5bda348", "text": "State whether you were the driver and/or owner of the vehicle involved in the occurrence on the date,
time and location as outlined in the Complaint. If you were not the driver, then state who you claim was driving the vehicle.”}, { "requestId": "cfaf4a36-20de-44ff-8673-5a725bddca03",
"text": "If you were employed at the time of the occurrence, as indicated in the Complaint, and working within the scope of that employment when the occurrence took place, identify your employer and the nature of the work you were performing.“}]. This is the Complaint: ${complaint}`,
},
];
return parseRequestsPrompt;
};
const createArrayFromStringBlobPrompt = (request) => {
console.log(
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>createArrayFromStringBlobPrompt FIRED~~~~~~~~~~~~~~~~~~~"
);
const parseRequestsPrompt = [
{
role: "user",
content: `You are an AI paralegal assisting attorneys in drafting discovery responses. Part of your job is to convert discovery request documents from text to other formats, such as JSON, for processing. I will provide you with some instructions, then a discovery request document, then you will perform a parsing operation.
The instructions: Review the discovery request document and return the numbered requests, and only the requests, as JSON. This JSON should be in the following form: an array of objects. There should be one object for each numbered discovery request. The object should contain two key/value pairs: first, a “requestId". This key's value will be a randomly generated, version 4 UUID The second key is ”text", its value will be the substantive content of the individual request. This is an example response to a hypothetical sequence of three requests: [{ "requestId": "73a855af-4fdc-4b8b-9e7f-34d57a2c084a",
"text": "example - you would put an individual request here.”}, { "requestId": "36fe8375-240d-4a08-8a71-9b2ba5bda348",
"text": "example - you would put an individual request here."}, { "requestId": "cfaf4a36-20de-44ff-8673-5a725bddca03",
"text": "you would put an individual request here.“}]. Some documents may contain sections before the requests. such as “Definitions”, or “Instructions,” do not include definitions, instructions or any other text that precedes the requests. Return the text of the question only, do not respond to it. Note the following CAREFULLY, it is important: some documents may have two kinds of requests - 1. Interrogatories and 2. requests for production of documents. You MUST be sure to include both the interrogatories and the requests for production of documents. Do not add introductory comments, analysis, or observations, such as "Based on your request, I have parsed the document and..," etc. Such comments will be problematic for later. This is the request document: ${request}`,
},
];
return parseRequestsPrompt;
};
module.exports = {
createArrayFromSingleDocPrompt,
createResponseFromOneQuestionPrompt,
createArrayOfInterrogatoriesPlaintiffPrompt,
createArrayOfInterrogatoriesDefendantPrompt,
createVerboseResponseFromOneQuestionPrompt,
createArrayFromStringBlobPrompt,
};
/*
this is used for combined-numbered -- skip right to answers no middle of parsing out the quesitons into an array
const singleDocPrompt = [
{
role: "user",
content: `You are a paralegal assisting trial attorneys in drafting discovery, including responses to interrogatories and requests for production of documents.
Draft a response to the discovery request I will give you,
after some instructions. The instructions: Respond
to each request, wether it is an interrogatory or a request for production. Include only objections, but thoroughly include all possible,
non-frivolous objections. Do not assume facts about the case. Refer to your client, the party
responding here, as 'Respondent'. Begin each response with "RESPONDENT OBJECTS TO THE REQUEST (or, where appropriate,
"RESPONDENT FURTHER OBJECTS"). End each response with 'SUBJECT TO AND WITHOUT WAIVING these
objections, Respondent states as follows:'. Your overall response should be in the form of an array, containing
one JSON object for each discrete response. This JSON object
should contain two key/value pairs with the following data: 1. A “requestId,” the value for this key
will be a randomly-generated version 4 UUID, and 2. "text," the value for this key will be your
substantive response, This is an example to
illustrate form, it exemplifies a hypothetical response sequence : [{ requestId: 73a855af-4fdc-4b8b-9e7f-34d57a2c084a,
text: 'example - response text would be stated here'}, { requestId: 16e82593-0b71-4c1a-9c3c-04f54ec4db9a,
text: 'example - response text would be stated here'}, { requestId: 0fe87371-bee8-439d-a672-bff256c75d43,
text: 'example - response text would be stated here'}]. That concludes the instructions.
This is the request: ${request}`,
},
];
*/

View File

@@ -0,0 +1,153 @@
const fs = require("fs");
const path = require("path");
/*
*
* Strore returned completions
*/
function saveCompletions(responses, folder, reqType, isRequests) {
const data = JSON.stringify(responses);
if (reqType === "") {
}
if (isRequests === true) {
dir = selectRequestPath(reqType, isRequests, folder);
} else {
dir = selectResponsePath(reqType, isRequests, folder);
}
let fileSuffix;
if (isRequests === true) {
fileSuffix = `-jbk-parsedRequests.json`;
} else {
fileSuffix = `-jbk-responses.json`;
}
try {
fs.writeFile(`${dir}${folder}${fileSuffix}`, data, function (err) {
if (err) {
return console.log(
"utilities Error in saveCompletions writeFile:",
err
);
}
});
} catch (err) {
console.log("Error writing file:", err);
}
}
function selectRequestPath(reqType, isRequests, folder) {
let dir;
const fdirup = path.resolve(process.cwd() + "/../Documents/Requests");
const fdir = path.resolve(
process.cwd() + "/../Documents/Requests/Parsedcombined"
);
if (reqType == "interrogatories") {
dir = `${fdirup}/Parsedrogs/${folder}/`;
} else if (reqType == "admissions") {
dir = `${fdirup}/Parsedadmit/${folder}/`;
} else if (reqType == "production") {
dir = `${fdirup}/Parsedprod/${folder}/`;
} else if (reqType == "combined-numbered") {
dir = `${fdir}/${folder}/`;
}
return dir;
}
function selectResponsePath(reqType, isRequests, folder) {
let dir;
//const fdirup = path.resolve(process.cwd() + "/Documents/Responses");
const fdirup = path.join(__dirname, "..", "Documents");
const fdir = path.resolve(
process.cwd() + "/Documents/Responses/Combinedresp"
);
console.log("fdirup in selectResponsePath", fdirup);
if (reqType === "interrogatories") {
dir = `${fdirup}/interrogatories/${folder}/`;
} else if (reqType == "admissions") {
dir = `${fdirup}/admissions/${folder}/`;
} else if (reqType == "production") {
dir = `${fdirup}/production/${folder}/`;
} else if (reqType == "combined-numbered") {
dir = `${fdir}/${folder}/`;
}
console.log("dir returned in selectResponsePath", dir);
return dir;
}
//const directoryPath = `/Users/kjannette/workspace/agentxa2new/Backend/Documents/Textfiles/`;
/**
*
* Takes path to directory returns
* concat path + fileName
*/
async function readDir(docId, direcPath = directoryPath) {
try {
const fullPath = direcPath + `${docId}`;
let fileNames = fs.readdirSync(direcPath);
const dirArray = fileNames.map((name) => {
return direcPath + name;
});
return dirArray;
} catch (err) {
console.log("read error", err);
}
}
/**
* Create directory w/its location based on if
* 1. request or response and
* 2. request/response type
*/
///Users/kjannette/workspace/ax3/ax3Services/Documents/Requests/Parsedcombined
async function makeDir(folder, reqType, isRequests) {
let dir;
if (reqType)
if (isRequests === true) {
dir = selectRequestPath(reqType, isRequests, folder);
} else {
dir = selectResponsePath(reqType, isRequests, folder);
}
console.log("dir in mkDir", dir);
fs.mkdir(`${dir}`, function (err) {
if (err) {
console.log("makeDir utilities error creating directory: " + err);
}
});
}
/**
* Takes an array of file paths, reads all files,
* pushes string contents to an array, then
* joins into massive string to stream to LLM
*
*/
async function iteratePathsReturnString(paths) {
const masterArray = [];
for (let path of paths) {
if (path == undefined || path == null) {
return;
}
const fileData = await fs.promises.readFile(path, "utf8");
masterArray.push(fileData);
}
const massiveString = masterArray.join();
return massiveString;
}
module.exports = {
readDir,
makeDir,
iteratePathsReturnString,
selectResponsePath,
selectRequestPath,
saveCompletions,
};

504
ax3Services/app.js Normal file
View File

@@ -0,0 +1,504 @@
const express = require("express");
const app = express();
const fs = require("fs");
const tesseReader = require("./tesseReaderService/tesseReader.js");
const cors = require("cors");
const multer = require("multer");
const logger = require("./logger/logger.js");
const modelController = require("./agent/ModelController.js");
const tesseController = require("./tesseReaderService/tesseController.js");
const stripeController = require("./paymentService/stripeController.js");
const { db } = require("./firebase/firebase.js");
const trialUsers = require("./Constants/trialSignupData.js");
const crypto = require("crypto");
const {
storeEditedCompletions,
storeDataForGenServices,
} = require("./storageService/storeEditedCompletion.js");
const {
deleteDocument,
deleteFolderAndContents,
cleanupGenFolderAndContents,
} = require("./storageService/deleteDirOrDoc.js");
const {
handlePaymentFailure,
handleSubscriptionDeletion,
} = require("./paymentService/stripe.js");
const { collection, query, where, getDocs } = require("firebase/firestore");
const generatePassword = (
length = 20,
characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$"
) =>
Array.from(crypto.randomFillSync(new Uint32Array(length)))
.map((x) => characters[x % characters.length])
.join("");
//*** STRIPE ***/
const Stripe = require("stripe");
const { stripeAPIKey, stripeWebhooksKey } = require("./firebase/secrets.js");
const stripe = Stripe(stripeAPIKey);
// Secret for Stripe webhooks
const endpointSecret = stripeWebhooksKey;
//** NODE HTTP-PROXY ***/
const httpProxy = require("http-proxy");
const targetUrl = "http://127.0.0.1:8081";
const proxy = httpProxy.createProxy({
changeOrigin: true,
target: targetUrl,
});
//** NODE HTTP-PROXY ***/
const httpProxy2 = require("http-proxy");
const targetAdd = "http://127.0.0.1:8087";
const proxyTwo = httpProxy.createProxy({
changeOrigin: true,
target: targetAdd,
});
//*** MULTER ***/
const storage = multer.diskStorage({
destination: "./Documents/Uploads",
filename: function (req, file, callback) {
callback(null, file.originalname);
},
});
const altStorage = multer.diskStorage({
destination: "./Documents/Complaints",
filename: function (req, file, callback) {
callback(null, file.originalname);
},
});
const upload = multer({ storage: storage });
const uploadComp = multer({ storage: altStorage });
//POST NEW COMPLAINT DOC -> py docConvert pdf-png
app.post(
"/v1/parse-new-compdoc",
uploadComp.single("file"),
function (req, res) {
const id = req.file.originalname.split(".")[0];
const isComplaint = true;
const clientPosition = "plaintiff";
try {
req.url = req.url.replace(
"/v1/parse-new-compdoc",
`/parse-new-complaint/${id}`
);
proxy.web(req, res, {
function(err) {
console.log("Proxy error:", err);
},
});
} catch (err) {
logger.error({ level: "error", message: "err", err });
console.log("Error at /v1/gen-disc-request", err);
res.send(err);
}
res.sendStatus(200);
}
);
/*
* POST new discv request => docConvert - for pdf to png
*/
app.post("/v1/parse-new-req-doc", upload.single("file"), function (req, res) {
const id = req.file.originalname.split(".")[0];
try {
req.url = req.url.replace(
"/v1/parse-new-req-doc",
`/parse-new-disc-req/${id}`
);
proxy.web(req, res, {
function(err) {
console.log("Proxy error:", err);
},
});
} catch (err) {
logger.error({ level: "error", message: "err", err });
console.log("Error at /v1/gen-disc-request", err);
res.send(err);
}
res.sendStatus(200);
});
//Make outgoing requests from complaint
app.post(
"/v1/generate-outgoing-disc-req/:docId/:clientPosition",
async (req, res) => {
const { docId, clientPosition } = req.params;
const isComplaint = true;
try {
const res = await tesseController.executeReadWriteActions(
docId,
isComplaint,
clientPosition
);
//return res;
} catch (err) {
console.log("err in make-outgoing-requests", err);
}
res.sendStatus(200);
}
);
//make resp to incoming requests from req doc
app.post(
"/v1/generate-disc-responses/:docId/:clientPosition",
async (req, res) => {
const { docId, clientPosition } = req.params;
const isComplaint = false;
try {
const res = await tesseController.executeReadWriteActions(
docId,
isComplaint,
clientPosition
);
return res;
} catch (err) {
console.log("err in make-outgoing-requests", err);
}
res.sendStatus(200);
}
);
/*
* POST to Generate Docx
*/
app.post("/v1/generate-request-docx/:docId", async function (req, res) {
const { docId } = req.params;
const data = req.body;
try {
req.url = req.url.replace("/v1/generate-request-docx", `/gen-req-docx`);
proxyTwo.web(req, res, {
function(err) {
console.log("Proxy error:", err);
},
});
} catch (err) {
console.log("generate-request-docx error", err);
}
});
const rootDir =
process.env.NODE_ENV === "development"
? "/Users/kjannette/workspace/ax3"
: "/var/www";
//*** EXPRESS ***/
const port = 3001;
var corsOptions = {
AccessControlAllowOrigin: "*",
origin: "*",
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
optionsSuccessStatus: 200,
};
app.use(cors(corsOptions));
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
/*
* Client POST create stripe subscription, make payment
*/
app.post("/create-subscription", async (req, res) => {
const { planType, additionalAccounts, isAnnual, customerData, token } =
req.body;
try {
const sub = await stripeController.createNewSubscription(
planType,
additionalAccounts,
isAnnual,
customerData,
token
);
const subscriptionCreated = sub.subscription.created;
const subscriptionPeriodStart = sub.subscription.current_period_start;
const subscriptionPeriodEnd = sub.subscription.current_period_end;
const subscriptionId = sub.subscription.id;
const customerId = sub.customer.customerId;
res.send({
subscriptionCreated,
subscriptionPeriodStart,
subscriptionPeriodEnd,
subscriptionId,
customerId,
});
} catch (error) {
console.log("Error in create-subscription", error);
res.status(400).send({ error: { message: error.message } });
}
});
/*
* Client POST create stripe subscription, make payment
*/
console.log("process.env.NODE_ENV", process.env.NODE_ENV);
app.post("/new-payment-intent", async (req, res) => {
const { planType, additionalAccounts, isAnnual, customerData, token } =
req.body;
const userAgent = req.headers["user-agent"];
try {
const payIntent = await stripeController.createNewPaymentIntent(
customerData,
token,
userAgent
);
res.send({
payIntent,
});
} catch (error) {
console.log(error);
res.status(400).send({ error: { message: error.message } });
}
});
/*
* Client POST for cancelling a subscription
*/
app.post("/cancel-subscription", async (req, res) => {
const { appUserId } = req.body;
try {
const usersRef = collection(db, "users");
const q = query(usersRef, where("appUserId", "==", appUserId));
const querySnapshot = await getDocs(q);
if (querySnapshot.empty) {
console.log("No user found with the email:", appUserId);
return;
}
const userDoc = querySnapshot.docs[0];
//get the user's subscription ID and customer ID
const subscriptionId = userDoc.data().subscriptionId;
const deletedSubscription = await stripe.subscriptions.update(
subscriptionId,
{
cancel_at_period_end: true,
}
);
res.status(200).send();
} catch (error) {
console.log(error);
res.status(500).send({ error: { message: error.message } });
}
});
/*
* Client POST - Stripe webhook(s)
*/
app.post(
"/stripe-webhook",
express.raw({ type: "application/json" }),
async (request, response) => {
const { type } = request.body.type;
switch (request.body.type) {
case "customer.subscription.deleted":
const subscription = request.body.data.object;
//get stripe customer
const stripeCustomer = await stripe.customers.retrieve(
subscription.customer
);
await handleSubscriptionDeletion(stripeCustomer, subscription, stripe);
break;
x;
case "invoice.payment_failed":
const paymentIntent = request.body.data.object;
await handlePaymentFailure(paymentIntent);
break;
default:
console.log(`Unhandled event type`);
}
response.status(200).send();
}
);
/*
* Generate responses to irregular types
* combined-numbered
*/
app.get(
"/v1/generate-disc-responses-irreg/:docId/:docType/:isRequests",
async (req, res) => {
const { docId, docType } = req.params;
const isRequests = false;
try {
const data = await modelController.arrayGenAnswers(
docId,
docType,
isRequests
);
res.send(data);
} catch (error) {
console.log(error);
}
}
);
/*
*
* GET .docx discovery response
*
*/
app.get("/v1/get-docx/:docId/:reqType", (req, res) => {
const { docId } = req.params;
res.sendFile(`${docId}.docx`, {
root: `${rootDir}/ax3Services/Docxfinal/`,
});
});
/*
* Cleanup docx working files (temp workaround)
*/
app.get("/cleanUpDocx/:docId/:reqType", (req, res) => {
const { docId, reqType } = req.params;
try {
cleanupGenFolderAndContents(docId, reqType);
res.end("doc cleanup complete");
} catch (err) {
console.log(err);
}
});
/*
* POST store user-edited completions
*/
app.post("/v1/store-edited-completions", function (req, res) {
const data = req.body;
try {
storeEditedCompletions(data);
} catch (err) {
console.log("Error at /v1/store-edited-completions:", err);
}
res.end();
});
/*
* POST store docx data for gen service
*/
app.post("/v1/store-docx-data/:docId", function (req, res) {
const { docId } = req.params;
const data = req.body;
console.log("data", data);
try {
storeDataForGenServices(docId, data);
} catch (err) {
console.log("Error at /v1/store-edited-completions:", err);
}
res.end();
});
/*
*
* Client GET parsed requests array
*/
app.get("/v1/get-parsed-requests/:docId/:docType", (req, res) => {
const { docId, docType } = req.params;
try {
res.sendFile(`${docId}-jbk-parsedRequests.json`, {
root: `${rootDir}/ax3Services/Documents/Requests/${docType}/${docId}/`,
});
} catch (err) {
console.log("err", err);
}
});
/*
*
* Client GET focus user data
*/
app.get("/v1/get-focused-data/:code", (req, res) => {
const { code } = req.params;
try {
const match = trialUsers.trialUsers.filter(
(user) => user.signupCode === code
);
if (match.length > 0) {
const mspall = generatePassword();
match[0]["mspall"] = mspall;
res.send(match);
}
} catch (err) {
console.log("err", err);
}
});
/*
* Client GET completions - (responses to) incoming requests
*/
app.get("/v1/get-completions/:docId/:docType", (req, res) => {
const { docId, docType } = req.params;
try {
res.sendFile(`${docId}-jbk-responses.json`, {
root: `./Documents/Responses/${docType}/${docId}/`,
});
} catch (err) {
console.log("err", err);
}
});
/*
* Client GET completions - requests outgoing
*/
app.get("/v1/get-outgoing-requests/:docId/:docType", (req, res) => {
const { docId, docType } = req.params;
try {
res.sendFile(`${docId}-jbk-requests-out.json`, {
root: `./Documents/RequestsOut/${docId}/`,
});
} catch (err) {
console.log("err", err);
}
});
/*
* Client POST to delete a request or response document
*/
app.post("/deleteDoc/:docId/:docType/:respGens", (req, res) => {
const { docId, docType, respGens } = req.params;
try {
deleteFolderAndContents(docId, docType, respGens);
} catch (err) {
console.log("err", err);
}
});
console.log("app running on port", port);
console.log("rootDir", rootDir);
app.listen(port);

View File

@@ -0,0 +1,72 @@
const fs = require("fs");
const docParser = require("../docParserService/docParser.js");
async function checkFile(
docType,
filePaths,
folder,
searchStr,
determinedDocType
) {
let path;
if (determinedDocType === "interrogatories") {
path = `../Documents/Requests/Parsedrogs/${folder}/${folder}-jbk-parsedArr.json`;
} else if (determinedDocType === "production") {
path = `../Documents/Requests/Parsedprod/${folder}/${folder}-jbk-parsedArr.json.json`;
} else if (determinedDocType === "admissions") {
path = `../Documents/Requests/Parsedadmit/${folder}/${folder}-jbk-parsedArr.json.json`;
} else if (determinedDocType === "combined-numbered") {
// For now assume its rogs if no other match
path = `../Documents/Requests/Parsedcombined/${folder}/${folder}-jbk-parsedArr.json.json`;
}
async function fileExists(path) {
try {
const result = await fs.promises.stat(path, (err, stats) => {
const reRun = err?.code
? err?.code === "ENOENT"
? true
: false
: false;
return reRun;
});
return result.json();
} catch (err) {
console.log(err);
}
}
//const parseError = fileExists(path);
//console.log("parseError in checkFIle:", parseError);
async function reRun() {
const runAgain = await fileExists(path);
if (runAgain) {
const now = new Date(8.64e15).toString();
}
}
fs.stat(path, function (err, stats) {
const reRun = err?.code ? (err?.code === "ENOENT" ? true : false) : false;
});
}
module.exports = {
checkFile,
};
/*
if (determinedDocType === "interrogatories") {
path = `../Documents/Responses/Parsedrogs/${folder}/${folder}-jbk-parsedArr.json`;
} else if (determinedDocType === "production") {
path = `../Documents/Responses/Parsedprod/${folder}/${folder}-jbk-parsedArr.json.json`;
} else if (determinedDocType === "admissions") {
path = `../Documents/Responses/Parsedadmit/${folder}/${folder}-jbk-parsedArr.json.json`;
} else if (determinedDocType === "combined-numbered") {
// For now assume its rogs if no other match
path = `../Documents/Fallback/${folder}/${folder}-jbk-parsedArr.json.json`;
}
*/

View File

@@ -0,0 +1,161 @@
//https://www.npmjs.com/package/csvtojson
//https://www.npmjs.com/package/json-2-csv
//https://stackoverflow.com/questions/72218301/transforming-large-array-of-objects-to-csv-using-json2csv
const path = require("path");
const json2csv = require("json2csv");
const fs = require("fs");
const trialUsers = require("../Constants/trialSignupData.js");
const njFocusList = require("../Constants/njFocusData.js");
const csv = require("csvtojson");
const converter = csv({
noheader: true,
trim: true,
});
//const csvFilePath = "data2.csv";
const codeRoot = "novofreedom-fl24-0";
const number = 201;
function convertCsvToJson(csvFilePath, codeRoot) {
converter
.fromFile(csvFilePath)
.then((jsonArr) => {
let num = number;
const newArr = [];
jsonArr.forEach((obj) => {
let newObj = {};
const valueArr = Object.values(obj);
const keysArr = [
"firstName",
"lastName",
"firm",
"email",
"city",
"state",
];
valueArr.forEach((value, i) => {
newObj[keysArr[i]] = value;
});
num = num + 1;
newObj["description"] = `${codeRootNJ}${num}`;
newArr.push(newObj);
});
return newArr;
})
.then((res) => {
const filePath = path.join(__dirname, "..", "Userinfo");
const data = JSON.stringify(res);
fs.writeFile(`./njFocuslist.json`, data, function (err) {
if (err) {
return console.log("err in csvJson writeFile:", err);
}
});
});
}
const codeRootNJ = "novolens-nj24-";
const csvFilePath = "./data.csv";
//convertCsvToJson(csvFilePath, codeRootNJ);
//const data = JSON.parse(fileData);
//works for array of objects. one object => one csv row
function convertJsonToCsv(data, fileName) {
let csv;
data.forEach((obj, i) => {
json2csv
.parseAsync(obj)
.then((line) => {
csv += line + "\n";
return csv;
})
.then((csv) => {
fs.writeFile(`./${fileName}.csv`, csv, function (err) {
if (err) throw err;
console.log("File Saved!");
});
});
});
}
const fileName = "njFocusList";
convertJsonToCsv(njFocusList.njFocusList, fileName);
/*
function convertJsonToCsv2(data) {
data.forEach((obj) => {
json2csv
.parseAsync(obj, {
fields: [
"uuid",
"firstName",
"LastName",
"firm",
"email",
"city",
"state",
"zip",
"description",
],
})
.then((csv) => {
fs.writeFile("./flRemainingProspects.csv", csv, function (err) {
if (err) throw err;
console.log("File Saved!");
});
});
});
}
function convertJsonToCsv(data) {
json2csv.parseAsync(data).then((csv) => {
fs.writeFile("flRemainingProspects.csv", csv, function (err) {
if (err) throw err;
console.log("File Saved!");
});
});
}
*/
/*
function convertJsonToCsv2(data) {
let csv;
data.forEach((obj, i) => {
json2csv
.parseAsync(obj, {
fields: [
"uuid",
"firstName",
"lastName",
"firm",
"email",
"city",
"state",
"zip",
"signupCode",
],
})
.then((line) => {
csv += line + "\n";
return csv;
})
.then((csv) => {
console.log(csv);
});
.then((csv) => {
fs.writeFile("./flRemainingProspects.csv", csv, function (err) {
if (err) throw err;
console.log("File Saved!");
});
});
});
}
*/

View File

@@ -0,0 +1,37 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
from splitPdf import SplitPdf
import logging
hostName = "localhost"
serverPort = 5050
sp = SplitPdf()
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_POST(self):
print('post hit')
content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
print('content_length', content_length)
post_data = self.rfile.read(content_length) # <--- Gets the data itself
print('post_data', post_data)
logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
str(self.path), str(self.headers), post_data.decode('utf-8'))
self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print("Server started http://%s:%s" % (hostName, serverPort))
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")

View File

@@ -0,0 +1,44 @@
import bottle
from bottle import run, get, post, request, route
from bottle import HTTPResponse
from splitPdf import SplitPdf
from pathlib import Path
import json
def fix_environ_middleware(app):
def fixed_app(environ, start_response):
environ['wsgi.url_scheme'] = 'https'
environ['HTTP_X_FORWARDED_HOST'] = 'novodraft.com'
return app(environ, start_response)
return fixed_app
app = bottle.default_app()
app.wsgi = fix_environ_middleware(app.wsgi)
sp = SplitPdf()
suc = {
'ok': True
}
@post('/parse-new-complaint/<id>')
def newdoc(id='test'):
newDir = f"{id}" # path[-1].split(".")[0]
print('newDir', newDir)
sp.make_dir(newDir)
path_arg = f"../Documents/Complaints/{id}.pdf"
print(f"../Documents/Complaints/{id}.pdf")
sp.split_and_convert(path_arg, newDir)
respBody = json.dumps({'Status': 'Success'})
return bottle.HTTPResponse(status=200, body=respBody)
@post('/parse-new-disc-req/<id>')
def newdoc(id='test'):
newDir = f"{id}"
print('newDir', newDir)
sp.make_dir(newDir)
path_arg = f"../Documents/Uploads/{id}.pdf"
print("path_arg", path_arg)
sp.split_and_convert(path_arg, newDir)
respBody = json.dumps({'Status': 'Success'})
return bottle.HTTPResponse(status=200, body=respBody)
run(app, host='127.0.0.1', port=8081, debug=True)

View File

@@ -0,0 +1,49 @@
import pdf2image from "pdf2image";
//The converter uses the same options as the convertPDF function
var converter = pdf2image.compileConverter({
density: 200,
quality: 100,
outputFormat: "%s_page_%d",
outputType: "png",
});
//Converts a single pdf
converter.convertPDF("badRogs.pdf");
//Converts multiple pdfs
//converter.convertPDFList(["example1.pdf", "example1.pdf"]);
/*
const { fromPath } = require("pdf2pic");
const pdf = require("pdf-page-counter");
const fs = require("fs");
const split = () => {
const { filename } = "./badRogs.pdf";
const options = {
density: 100,
saveFilename: "file",
savePath: "./converted",
format: "png",
width: 600,
height: 600,
};
const storeAsImage = fromPath(`./converted/${filename}`, options);
let dataBuffer = fs.readFileSync(`./converted/${filename}`);
pdf(dataBuffer).then(function (data) {
for (
var pageToConvertAsImage = 1;
pageToConvertAsImage <= data.numpages;
pageToConvertAsImage++
) {
storeAsImage(pageToConvertAsImage).then((resolve) => {
return resolve;
});
}
res.send({
filename: filename,
});
});
};
*/

View File

@@ -0,0 +1,136 @@
import os
import uuid
from pdf2image import convert_from_path
from pdf2image.exceptions import (
PDFInfoNotInstalledError,
PDFPageCountError,
PDFSyntaxError,
)
class SplitPdf(object):
def make_dir(self, newDir):
print("newDir in module", newDir)
self.directory = newDir
self.parent_dir = "../Documents/Converted/"
self.path = os.path.join(self.parent_dir, self.directory)
os.mkdir(self.path)
def split_and_convert(self, pathArg, newDir):
print("in split and convert: pathArg, newDir", pathArg, newDir)
arr = [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"aa",
"ab",
"ac",
"ad",
"ae",
"af",
"ag",
"ah",
"ai",
"ak",
"al",
"am",
"an",
"ao",
"ap",
"aq",
"ar",
"as",
"at",
"au",
"av",
"aw",
"ax",
"ay",
"az",
"ba",
"bb",
"bc",
"bd",
"be",
"bf",
"bg",
"bh",
"bi",
"bk",
"bl",
"bm",
"bn",
"bo",
"bp",
"bq",
"br",
"bs",
"bt",
"bu",
"bv",
"bw",
"bx",
"by",
"bz",
"za",
"zb",
"zc",
"zd",
"ze",
"zf",
"zg",
"zh",
"zi",
"zj",
"zk",
"zl",
"zm",
"zn",
"zo",
"zp",
"zq",
"zr",
"zs",
"zt",
"zu",
"zv",
"zw",
"zx",
"zy",
"zz",
]
self.images = convert_from_path(pathArg, fmt="png")
print(f"../Documents/Converted/{self.directory}")
for i, image in enumerate(self.images):
fname = f"{newDir}" + arr[i] + ".png"
image.save(f"../Documents/Converted/{self.directory}/{fname}", "PNG")
# split pdf to multiple png files
# https://pypi.org/project/pdf2image/
# https://pythonforundergradengineers.com/pdf-to-multiple-images.html
# convert to js(?):
# https://www.npmjs.com/package/pdf2image

View File

@@ -0,0 +1,41 @@
import sys
import time
import logging
from splitPdf import SplitPdf
from watchdog.observers import Observer
from pathlib import Path
# from watchdog.events import LoggingEventHandler
from watchdog.events import PatternMatchingEventHandler
watch_dir = f"{Path(__file__).parents[1]}/Documents/Uploads"
if __name__ == "__main__":
sp = SplitPdf()
def on_created(event):
print(f"Event: {event.src_path} was created.")
path = str(event.src_path).split("/")
print(">>>>>>>>>>>>>>>path", path[-1].split(".")[0])
newDir = path[-1].split(".")[0]
sp.make_dir(newDir)
sp.split_and_convert(event.src_path, newDir)
patterns = ["*"]
ignore_patterns = None
ignore_directories = False
case_sensitive = True
path = watch_dir
my_event_handler = PatternMatchingEventHandler(
patterns, ignore_patterns, ignore_directories, case_sensitive
)
my_event_handler.on_created = on_created
observer = Observer()
observer.schedule(my_event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
finally:
observer.stop()
observer.join()

View File

@@ -0,0 +1,18 @@
import * as fs from "fs";
import * as sleep from "system-sleep";
import createFormattedContent from "./responseHeaderGenerator.mjs";
const directory = "/Users/kjannette/workspace/agentxa2new/Backend/Doctemp";
async function watchOnce() {
const watcher = fs.watch(directory, (event, file) => {
const path = `/Users/kjannette/workspace/agentxa2new/Backend/Doctemp/${file}`;
createFormattedContent(path);
watcher.close();
// Relaunch watcher after 1 second
sleep(1000);
watchOnce();
});
}
watchOnce();

View File

@@ -0,0 +1,79 @@
import {
AlignmentType,
Document,
convertInchesToTwip,
Packer,
Paragraph,
Styles,
Style,
SectionType,
TextRun,
UnderlineType,
Underline,
} from "docx";
export const newYorkCaptionTemplate = (
jurisdiction,
venue,
plaintiff,
defendant,
caseNumber,
judge,
documentType,
comesNow
) => {
const template = [
new Paragraph({
text: `${jurisdiction}`,
style: "normalIndent",
}),
new Paragraph({ text: `${venue}`, style: "normalIndent" }),
new Paragraph({
text: "________________________________________________",
}),
new Paragraph({
text: `${plaintiff}`,
style: "normalIndentSpacingAfter",
}),
new Paragraph({
text: `Plaintiffs, Index No.: ${caseNumber}`,
style: "captionIndent",
}),
new Paragraph({
text: `-against- Judge: ${judge}`,
style: "normalIndentMostSpacingAfter",
}),
new Paragraph({
text: `${defendant}`,
style: "normalIndentSpacingAfter",
}),
new Paragraph({
text: "Defendants.",
style: "captionIndent",
}),
new Paragraph({
text: "________________________________________________",
style: "normalIndent",
}),
new Paragraph({
style: "headingIndent",
children: [
new TextRun({
text: `RESPONSE TO ${documentType}`,
bold: true,
}),
],
}),
new Paragraph({
style: "reset",
children: [
new TextRun({
text: `COMES NOW, ${comesNow}, by and through the undersigned counsel, in accordance with NY CPLR § 3133, et. seq., as and for its response to the ${documentType.toLowerCase()}, served upon it, and states as follows:`,
bold: false,
}),
],
}),
];
return template;
};

View File

@@ -0,0 +1,175 @@
import {
AlignmentType,
Document,
convertInchesToTwip,
Packer,
Paragraph,
Styles,
Style,
SectionType,
TextRun,
UnderlineType,
Underline,
LineRuleType,
} from "docx";
export const newYorkStyleTemplate = {
styles: {
paragraphStyles: [
{
id: "captionIndent",
name: "Caption Indent",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(1.5),
hanging: convertInchesToTwip(0.18),
},
},
},
{
id: "headingIndent",
name: "Heading Indent",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(2.1),
hanging: convertInchesToTwip(0.18),
},
spacing: {
before: 340,
after: 340,
},
},
},
{
id: "indexIndent",
name: "indexIndent",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(4),
hanging: convertInchesToTwip(0.18),
},
},
},
{
id: "normalIndent",
name: "Normal Indent",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(0),
hanging: convertInchesToTwip(0.18),
},
},
},
{
id: "normalIndentSpacingAfter",
name: "normalIndentSpacingAfter",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(0),
hanging: convertInchesToTwip(0.18),
},
spacing: {
after: 240,
},
},
},
{
id: "normalIndentMoreSpacingAfter",
name: "normalIndentSpacingAfter",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(0),
hanging: convertInchesToTwip(0.18),
},
spacing: {
after: 310,
},
},
},
{
id: "normalIndentMostSpacingAfter",
name: "normalIndentSpacingAfter",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(0),
hanging: convertInchesToTwip(0.18),
},
spacing: {
after: 340,
},
},
},
{
id: "verticalSpacing",
name: "Vertical Spacing",
basedOn: "Normal",
next: "Normal",
paragraph: {
spacing: {
after: 220,
},
},
},
{
id: "reset",
name: "reset",
basedOn: "Normal",
next: "Normal",
paragraph: {
indent: {
left: convertInchesToTwip(0),
hanging: convertInchesToTwip(0),
},
spacing: {
after: 0,
},
},
},
{
id: "doubleSpacedText",
name: "Double Spaced Text",
basedOn: "Normal",
next: "Normal",
paragraph: {
spacing: {
before: 10 * 72 * 0.1,
after: 10 * 72 * 0.01,
lineRule: LineRuleType.AT_LEAST,
line: 2,
},
alignment: AlignmentType.JUSTIFIED,
},
},
{
id: "secondHeaderRun",
name: "Second Header Run",
basedOn: "Normal",
next: "Normal",
paragraph: {
spacing: {
before: 10 * 72 * 0.3,
after: 10 * 72 * 0.3,
lineRule: LineRuleType.EXACTLY,
line: 276,
},
},
},
],
},
sections: [],
};

View File

@@ -0,0 +1,348 @@
import json
import os
from docx import Document
from docx.shared import Inches
from docx.shared import Pt
from docx.shared import Length
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from pyCaptionTemplates import make_ny_header, make_nj_header, make_fl_header, make_mi_header
from pyGenObjectionTemplates import make_ny_gen_obj, make_nj_gen_obj, make_fl_gen_obj, make_mi_gen_obj
from pyOutgoingCopy import make_outgoing_instructions
from pyRequestsForProduction import make_requests_for_production
class GenerateBody(object):
def generate(self, docId):
path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), ".."))
foundationRogArray = [
"State your full name, home addresses for the past ten years, your employer for the last 10 years, your current work address, date of birth and social security number.",
"Identify all insurance carriers or self-insured funds, by name, address, policy numbers and policy limits, for any insurance policy or fund which may provide coverage for any judgment entered against you in this action.",
"If you contend that any other entity or person, including any other party or the Plaintiff, was responsible for the occurrence and Plaintiff's damages, identify such person(s) or entities, and give a concise statement of the facts upon which you rely in support of your contention.",
"Identify all experts who will be called to testify at a trial on the merits of this action, the subject matter and substance of such testimony, a summary of the grounds for each opinion; and produce any written report made by the expert concerning those findings and opinions.",
"Identify any documents and recordings including, but not limited to, pictures, photographs, PowerPoint presentations for use at trial, demonstrative exhibits, computer generated exhibits, electronically stored data, visual aids, overlays, employment records, plats, visual recorded images, audio recordings, cassette tapes, transcripts of testimony, diagrams and objects relative to the occurrence, the scene of the occurrence, Plaintiff's physical condition or statements made by any party or witness. Identify the substance of the item, the date obtained, what is depicted within the item, and the name and address of the present custodian of each item.",
"If you, your insurance carrier, private investigator, or any other person or entity is in possession of any written, oral or recorded statements by any party or person with personal knowledge relative to the occurrence, indicate the date and time each statement was obtained, the name and address of each person who provided the statement, the contents of the statement, and the name and address of the current custodian of the statement.",
"Describe any conduct, comment, conversation, statement, or report made by any person at the scene of the occurrence or at any time, concerning fault for the occurrence or facts relevant to any issue in this case. Include in your answer where the conduct, comment, conversation, or statement took place, and in whose presence it was made/observed, as well as the name of the author of such statement, the present custodian of the statement and the address for the custodian.",
"Since your eighteenth birthday, when you were represented by an attorney or waived the right to be represented by an attorney, state whether you have been found guilty of, or plead guilty to, any crimes other than minor traffic violations (i.e., those traffic offenses without the potential penalty of incarceration) and, if so, state the nature of the offense, the date of each conviction, and the full name of the court where each conviction was entered.",
"If you are aware of any other case or proceeding involving the incident identified in Plaintiff's Complaint including, but not limited to, civil, criminal or administrative actions, identify the case or action by tribunal, case number, docket number or citation number, the date of any hearing, and indicate any pleas in the case(s) and the disposition of the matter(s).",
]
# Init variables
reqType = None
arrLen = None
respArray = None
reqArray = None
reqHeader = None
respHeader = None
jsonData = None
leadAttorneys = None
clientPosition = None
respondent = None
servingParty = None
firmStreetAddress = None
firmCity = None
firmState = None
firmZip = None
firmTel = None
reqFile = None
respFile = None
# filePath = f"/Users/kjannette/workspace/ax3/ax3Services/docGenService/Docxstaging/{docId}.docx"
# f = open(filePath, "rb")
document = Document()
dataFile = f"./Docxinfo/{docId}.json"
# Get case data
with open(dataFile) as json_data:
caseInfo = json.load(json_data)
#caseInfo = jsonData.get("caseInfo")
caption1 = caseInfo["caseCaption1"]
caption2 = caseInfo["caseCaption2"]
clientPosition = caseInfo["clientPosition"]
defendant = caseInfo["defendant"]
plaintiff = caseInfo["plaintiff"]
jurisdiction = caseInfo["jurisdiction"]
reqType = caseInfo["currentRequestType"]
venue = caseInfo["venue"]
caseNumber = caseInfo["caseNumber"]
judge = caseInfo["judge"]
# Get attorney/firm data
firm = caseInfo["firm"]
leadAttorneys = caseInfo["leadAttorneys"]
firmStreetAddress = caseInfo["firmStreetAddress"]
firmCity = caseInfo["firmCity"]
firmState = caseInfo["state"]
firmTel = caseInfo["tel"]
firmZip = caseInfo["firmZip"]
if reqType == "interrogatories":
#reqFile = f"/var/www/ax3Services/Documents/Requests/Parsedrogs/{docId}/{docId}-jbk-parsedRequests.json"
#respFile = f"/var/www/ax3Services/Documents/Responses/Rogresp/{docId}/{docId}-jbk-responses.json"
reqFile = f"{path}/Documents/Requests/interrogatories/{docId}/{docId}-jbk-parsedRequests.json"
respFile = f"{path}/Documents/Responses/interrogatories/{docId}/{docId}-jbk-responses.json"
elif reqType == "combined-numbered":
reqFile = f"{path}/Documents/Requests/combined-numbered/{docId}/{docId}-jbk-parsedRequests.json"
respFile = f"{path}/Documents/Responses/combined-numbered/{docId}/{docId}-jbk-responses.json"
#reqFile = f"/var/www/ax3Services/Documents/Requests/combined-numbered/{docId}/{docId}-jbk-parsedRequests.json"
#respFile = f"/var/www/ax3Services/Documents/Responses/combined-numbered/{docId}/{docId}-jbk-responses.json"
elif reqType == "production":
reqFile = f"{path}/Documents/Requests/production/{docId}/{docId}-jbk-parsedRequests.json"
reqFile = f"{path}/Documents/Requests/production/{docId}/{docId}-jbk-parsedRequests.json"
#reqFile = f"/var/www/ax3Services/Documents/Requests/production/{docId}/{docId}-jbk-parsedRequests.json"
#reqFile = f"/var/www/ax3Services/Documents/Requests/production/{docId}/{docId}-jbk-parsedRequests.json"
elif reqType == "admissions":
reqFile = f"{path}/Documents/Requests/admissions/{docId}/{docId}-jbk-parsedRequests.json"
respFile = f"{path}/Documents/Responses/admissions/{docId}/{docId}-jbk-responses.json"
#reqFile = f"/var/www/ax3Services/Documents/Requests/admissions/{docId}/{docId}-jbk-parsedRequests.json"
#respFile = f"/var/www/ax3Services/Documents/Responses/admissions/{docId}/{docId}-jbk-responses.json"
elif reqType == "interrogatories-out":
reqFile = f"{path}/Documents/RequestsOut/{docId}/{docId}-jbk-requests-out.json"
#reqFile = f"/var/www/ax3Services/Documents/RequestsOut/{docId}/{docId}-jbk-requests-out.json"
if reqType == 'interrogatories-out':
if clientPosition == "Plaintiff":
respondent = defendant
elif clientPosition == "Defendant":
respondent = plaintiff
else:
if clientPosition == "Plaintiff":
respondent = plaintiff
elif clientPosition == "Defendant":
respondent = defendant
if reqType == 'interrogatories-out':
if clientPosition == "Plaintiff":
servingParty = plaintiff
elif clientPosition == "Defendant":
servingParty = defendant
else:
if clientPosition == "Plaintiff":
servingParty = caption2
elif clientPosition == "Defendant":
servingParty = caption1
if reqType == 'interrogatories-out':
if firmState == "mi":
comesNowString = f"COMES NOW, {clientPosition}, {servingParty}, through counsel, and hereby propounds these Interrogatories and Requests for Production upon {respondent}, to be answered under oath, in writing."
elif firmState == "ny":
comesNowString = f"COMES NOW, {clientPosition}, {servingParty}, through counsel, and hereby propounds these Interrogatories and Requests for Production upon {respondent}, to be answered under oath, in writing, in accordance with NY CPLR 3120 - 3130."
elif firmState == "nj":
comesNowString = f"Comes now ${clientPosition}, ${servingParty}, through counsel, and hereby propounds these Interrogatories and Requests for Production upon ${respondent}, to be answered to be answered under oath, in writing, in accordance with NJ R. 4:17-1 - 4:18-1, + et. seq. All questions must be answered unless the court otherwise orders or unless a claim of privilege or protective order is made in accordance with R. 4:17-1(b)(3)."
elif firmState == "fl":
comesNowString = f"COMES NOW, ${clientPosition}, ${servingParty}, through counsel, and hereby propounds these Interrogatories and Requests for Production upon ${respondent}, to be answered to be answered under oath, in writing, in accordance with Rule 1.340, Florida Rules of Civil Procedure."
else:
comesNowString = f"COMES NOW, Respondent(s), {respondent}, through counsel, in response to the {reqType} served by {servingParty}, and states as follows:"
if reqType == "interrogatories":
reqHeader = "INTERROGATORY NO."
respHeader = "RESPONSE TO INTERROGATORY NO."
mainHeader = "RESPONSE TO INTERROGATORIES"
mainHeader2 = "RESPONSES"
elif reqType == "admissions":
reqHeader = "Request for Admission No."
respHeader = "Response to Request for Admission No."
mainHeader = "RESPONSE TO REQUEST FOR ADMISSIONS"
mainHeader2 = "RESPONSES"
elif reqType == "production":
reqHeader = "Request for Production No."
respHeader = "Response to Request for Production No."
mainHeader = "RESPONSE TO REQUEST FOR PRODUCTON"
mainHeader2 = "RESPONSES"
elif reqType == 'interrogatories-out':
reqHeader = "Request no."
respHeader = "Response to Request for Production No."
mainHeader = "INTERROGATORIES AND REQUEST FOR PRODUCTION OF DOCUMENTS"
mainHeader2 = "INTERROGATORIES"
else:
reqHeader = "Request No."
respHeader = "Response to Request No."
mainHeader = "RESPONSE TO INTERROGATORIES AND REQUEST FOR PRODUCTION"
mainHeader2 = "RESPONSES"
# Create header
if firmState == "mi":
document = make_mi_header(
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
clientPosition,
)
elif firmState == "ny":
document = make_ny_header(
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
clientPosition,
)
elif firmState == "nj":
document = make_nj_header(
comesNowString,
firm,
leadAttorneys,
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
firmStreetAddress,
firmCity,
firmState,
firmTel,
firmZip,
clientPosition,
)
elif firmState == "fl":
document = make_fl_header(
comesNowString,
firm,
leadAttorneys,
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
firmStreetAddress,
firmCity,
firmState,
firmTel,
firmZip,
clientPosition,
)
elif firmState == None:
document = make_ny_header(
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
clientPosition,
)
paragraph = document.add_paragraph(f"{comesNowString}")
paragraph.paragraph_format.line_spacing = Pt(24)
paragraph.paragraph_format.space_before = Pt(12)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
# Add Instructions/Definitions if outgoing, else add General Objections
if reqType == "interrogatories-out":
document = make_outgoing_instructions(document, clientPosition, servingParty)
else:
if firmState == "mi":
document = make_mi_gen_obj(document, clientPosition, servingParty)
elif firmState == "ny":
document = make_ny_gen_obj(document, clientPosition, servingParty)
elif firmState == "nj":
document = make_nj_gen_obj(document, clientPosition, servingParty)
elif firmState == "fl":
document = make_fl_gen_obj(document, clientPosition, servingParty)
# Add main heading two
p = document.add_paragraph()
p.add_run(f"{mainHeader2}").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# INIT responses to iterate if doc is responsive, not outgoing
if (reqType != "interrogatories-out"):
json_resp_data = open(respFile)
respData = json.load(json_resp_data)
respArray = respData[0]["responses"]
arrLen = len(respArray)
# INIT requests and begin iteration to generate copy
if (reqType == "interrogatories-out"):
with open(reqFile) as json_data:
dataz = json.load(json_data)
reqArray = dataz[0]["requests"]
filtered = []
for req in reqArray:
filtered.append(req["text"])
joinedReqArray = [*foundationRogArray, *filtered]
arrLen2 = len(joinedReqArray)
count = 1
for req in joinedReqArray:
if count == arrLen2:
break
paragraph = document.add_paragraph(f"{count}. {req}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
document = make_requests_for_production(document, clientPosition, servingParty)
elif (reqType != "interrogatories-out"):
with open(reqFile) as json_data:
dataz = json.load(json_data)
reqArray = dataz[0]["requests"]
count = 1
for req in reqArray:
if count == arrLen:
break
text = req["text"]
paragraph = document.add_paragraph(f"{reqHeader} {count}:")
paragraph = document.add_paragraph(text)
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
paragraph = document.add_paragraph(f"{respHeader} {count}:")
paragraph.paragraph_format.space_before = Pt(24)
paragraph = document.add_paragraph(respArray[count]["text"])
paragraph.paragraph_format.line_spacing = Pt(24)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
paragraph = document.add_paragraph(
f"For the {clientPosition}, attorney {leadAttorneys} on this ______ day of _______________________, 2024."
)
paragraph.paragraph_format.space_before = Pt(24)
paragraph.paragraph_format.space_after = Pt(12)
paragraph = document.add_paragraph(
" ___________________________________"
)
paragraph.paragraph_format.space_before = Pt(24)
paragraph.paragraph_format.space_after = Pt(12)
document.save(f"{path}/Docxfinal/{docId}.docx")
respBody = json.dumps({'Status': 'Success'})
return respBody
# document.save(
# f"/Users/kjannette/workspace/ax3/ax3Services/Docxfinal/{docId}.docx"
# document.save(f"/var/www/ax3Services/Docxfinal/{docId}.docx")
# Uncomment for development/smoke testing
#genBod = GenerateBody()
#genBod.generate("eb75d30a-d58a-4b2e-80ba-695c8a79a1e6")
# reqFile = f"/Users/kjannette/workspace/ax3/ax3Services/Documents/Requests/Parsedrogs/{docId}/{docId}-jbk-parsedRequests.json"
# respFile = f"/Users/kjannette/workspace/ax3/ax3Services/Documents/Responses/Rogresp/{docId}/{docId}-jbk-responses.json"
# reqFile = f"/Users/kjannette/workspace/ax3/ax3Services/Documents/Requests/Parsedrogs/{docId}/{docId}-jbk-parsedRequests.json"
# respFile = f"/Users/kjannette/workspace/ax3/ax3Services/Documents/Responses/Rogresp/{docId}/{docId}-jbk-responses.json"

View File

@@ -0,0 +1,304 @@
import json
from docx import Document
from docx.shared import Inches
from docx.shared import Pt
from docx.shared import Length
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
# New York *******************************************************************/
def make_ny_header(
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
clientPosition,
):
print(
"______________________________________________________________NEW YORK!! MAKE HEADER FIRED"
)
paragraph = document.add_paragraph(f"{jurisdiction}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(f"{venue}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(
"-------------------------------------------------------------X"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(f"{caption1}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
paragraph = document.add_paragraph(
f" Plaintiff(s) Index No.: {caseNumber}"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
paragraph = document.add_paragraph(
f"- against - Judge: {judge}"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(16)
paragraph = document.add_paragraph(f"{caption2}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(
" Defendant(s)"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(3)
paragraph = document.add_paragraph(
"-------------------------------------------------------------X"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
p = document.add_paragraph()
p.add_run(f"{clientPosition.upper()}'S {mainHeader}").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
return document
# Florida *******************************************************************/
def make_fl_header(
comesNowString,
firm,
leadAttorneys,
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
firmStreetAddress,
firmCity,
firmState,
firmTel,
firmZip,
clientPosition,
):
print(
"______________________________________________________________FLORIDA MAKE HEADER FIRED"
)
jurisdictionUpper = jurisdiction.upper()
venueUpper = venue.upper()
p = document.add_paragraph()
p.add_run(f" IN THE CIRCUIT COURT OF THE {jurisdictionUpper}")
p.paragraph_format.space_before = Pt(0)
p.paragraph_format.space_after = Pt(1)
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p = document.add_paragraph()
p.add_run(f"OF FLORIDA, IN AND FOR {venueUpper} COUNTY")
p.paragraph_format.space_before = Pt(0)
p.paragraph_format.space_after = Pt(12)
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
paragraph = document.add_paragraph(f"{caption1}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
paragraph = document.add_paragraph(
f" Plaintiff(s), Case No.: {caseNumber}"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
paragraph = document.add_paragraph(f"v.")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(16)
paragraph = document.add_paragraph(f"{caption2}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(
" Defendant(s)."
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(3)
paragraph = document.add_paragraph(
"________________________________________________________________________/"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
p = document.add_paragraph()
p.add_run(f"{clientPosition.upper()}'S {mainHeader}").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
return document
# New Jersey *******************************************************************/
def make_nj_header(
comesNowString,
firm,
leadAttorneys,
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
firmStreetAddress,
firmCity,
firmState,
firmTel,
firmZip,
clientPosition,
):
paragraph = document.add_paragraph(f"{firm}")
paragraph.paragraph_format.space_before = Pt(2)
paragraph.paragraph_format.space_after = Pt(2)
paragraph = document.add_paragraph(f"By: {leadAttorneys}")
paragraph.paragraph_format.space_before = Pt(2)
paragraph.paragraph_format.space_after = Pt(2)
paragraph = document.add_paragraph(f"{firmStreetAddress}")
paragraph.paragraph_format.space_before = Pt(2)
paragraph.paragraph_format.space_after = Pt(2)
paragraph = document.add_paragraph(f"{firmCity}, {firmState} {firmZip}")
paragraph.paragraph_format.space_before = Pt(2)
paragraph.paragraph_format.space_after = Pt(2)
paragraph = document.add_paragraph(f"Tel: {firmTel}")
paragraph.paragraph_format.space_before = Pt(2)
paragraph.paragraph_format.space_after = Pt(2)
paragraph = document.add_paragraph(
f"_______________________________________________________________"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(f"{caption1:<92} ")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" {jurisdiction} "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" {venue} "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" Plaintiff "
)
paragraph = document.add_paragraph(
f" "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" v. Docket No,{caseNumber}"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph((f"{caption2:<90} "))
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" Defendant "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f" "
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph = document.add_paragraph(
f"_______________________________________________________________"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
return document
# Michigan *******************************************************************/
def make_mi_header(
document,
jurisdiction,
venue,
caption1,
caption2,
mainHeader,
caseNumber,
judge,
clientPosition,
):
print(
"______________________________________________________________MICHIGAN MAKE HEADER FIRED"
)
temp = venue.split(" ", 1)
newVenue = temp[0].upper()
paragraph = document.add_paragraph("STATE OF MICHIGAN")
paragraph.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(f"IN THE CIRCUIT COURT FOR THE COUNTY OF {newVenue}")
paragraph.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(" ")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(f"{caption1}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
paragraph = document.add_paragraph(
f" Plaintiff(s) Case No.: {caseNumber}"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
paragraph = document.add_paragraph(
f"v. Hon. {judge}"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(16)
paragraph = document.add_paragraph(f"{caption2}")
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(1)
paragraph = document.add_paragraph(
" Defendant(s)"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(3)
paragraph = document.add_paragraph(
"___________________________________________________________________/"
)
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(12)
p = document.add_paragraph()
p.add_run(f"{clientPosition.upper()}'S {mainHeader}").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
return document

View File

@@ -0,0 +1,41 @@
import sys
import time
import logging
from generateDocument import GenerateBody
from watchdog.observers import Observer
import os
# from watchdog.events import LoggingEventHandler
from watchdog.events import PatternMatchingEventHandler
bodygen = GenerateBody()
if __name__ == "__main__":
def on_created(event):
print(f"Event: {event.src_path} was created.")
path = str(event.src_path).split("/")
print(">>>>>>>>>>>>>>>>>>>>>>>path", path[-1].split(".")[0])
docId = str(path[-1].split(".")[0])
bodygen.generate(docId)
root_path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), ".."))
patterns = ["*"]
ignore_patterns = None
ignore_directories = False
case_sensitive = True
#path = "/var/www/ax3Services/docGenService/Docxinfo"
path = f"{root_path}/docGenService/Docxinfo"
my_event_handler = PatternMatchingEventHandler(
patterns, ignore_patterns, ignore_directories, case_sensitive
)
my_event_handler.on_created = on_created
observer = Observer()
observer.schedule(my_event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
finally:
observer.stop()
observer.join()

View File

@@ -0,0 +1,133 @@
import json
from docx import Document
from docx.shared import Inches
from docx.shared import Pt
from docx.shared import Length
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
# Michigan *****************************************************************/
def make_mi_gen_obj(document, clientPosition, servingParty):
objectionsArray = [
f"All of {clientPosition}'s responses herein are subject to the following objections, in addition to any and all specific objections set forth in the responses to individual requests.",
f"In responding to these requests, {clientPosition} does not admit or concede any presumptions or assumptions made in the propounding parties' definitions, or in the requests themselves.",
f"{clientPosition} objects to any and all requests to the extent they seek or may be interpreted to seek disclosure of information not within the scope of MCR 2.302(B), or not within the scope of what is permitted under any applicable Preliminary Conference or Case Scheduling Order entered in this case, and {clientPosition} reserves all rights to contest any such matters in any other context or proceeding where they may be relevant.",
f"{clientPosition} objects to all requests that seek disclosure of information which (a) is subject to attorney-client privilege, or (b) the 'work product' doctrine; (c) is subject to the required reports privilege; (d) is subject to a joint defense or common interest privilege; (e) was generated in anticipation of litigation or for trial, (f) relates to the identity or opinions of experts who have been retained or employed in anticipation of litigation and who are not expected to be called as witnesses at trial; (g) is protected as a trade secret; (h) is subject to a protective order or confidentiality order or agreement which was entered or made in another matter, and/or (i) is otherwise privileged, protected from disclosure, or beyond the scope of discovery under applicable rules and laws. Further, {clientPosition} does not intend to disclose or produce any such information, and any disclosure of such information is inadvertent, and all rights to demand return and/or destruction of any such information are reserved.",
f"{clientPosition} objects to the propounding parties' requests insofar as they seek a proposition of law and/or the formulation of a legal theory, or seek contentions regarding factual matters as to which essential discovery is incomplete. {clientPosition}'s current responses to such requests necessarily cannot present all information {clientPosition} may ultimately discover and utilize or rely upon in this matter. {clientPosition} thus reserves all rights to supplement or amend its responses in accordance with applicable rules, laws, orders or agreements of the parties, if and when circumstances warrant.",
]
print(
"______________________________________________________________NEW YORK MAKE OBJECTION FIRED"
)
p = document.add_paragraph()
p.add_run("GENERAL OBJECTIONS").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
arrLen = len(objectionsArray)
count = 0
for obj in objectionsArray:
if count == arrLen:
break
paragraph = document.add_paragraph(f"{count + 1}. {obj}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
return document
# New York *****************************************************************/
def make_ny_gen_obj(document, clientPosition, servingParty):
objectionsArray = [
f"All of {clientPosition}'s responses herein are subject to the following objections, in addition to any and all specific objections set forth in the responses to individual requests.",
f"In responding to these requests, {clientPosition} does not admit or concede any presumptions or assumptions made in the propounding parties' definitions, or in the requests themselves.",
f"{clientPosition} objects to any and all requests to the extent they seek or may be interpreted to seek disclosure of information not within the scope of New York CPLR 3120, 3130 - 33, or not within the scope of what is permitted under any applicable Preliminary Conference or Case Scheduling Order entered in this case, and {clientPosition} reserves all rights to contest any such matters in any other context or proceeding where they may be relevant.",
f"{clientPosition} objects to all requests that seek disclosure of information which (a) is subject to attorney-client privilege, or (b) the 'work product' doctrine; (c) is subject to the self-critical analysis privilege; (d) is subject to the required reports privilege; (e) is subject to a joint defense or common interest privilege; (f) was generated in anticipation of litigation or for trial, (g) relates to the identity or opinions of experts who have been retained or employed in anticipation of litigation and who are not expected to be called as witnesses at trial; (h) is protected as a trade secret; (i) is subject to a protective order or confidentiality order or agreement which was entered or made in another matter, and/or (j) is otherwise privileged, protected from disclosure, or beyond the scope of discovery under applicable rules and laws. Further, {clientPosition} does not intend to disclose or produce any such information, and any disclosure of such information is inadvertent, and all rights to demand return and/or destruction of any such information are reserved.",
f"{clientPosition} objects to the propounding parties' requests insofar as they seek a proposition of law and/or the formulation of a legal theory, or seek contentions regarding factual matters as to which essential discovery is incomplete. {clientPosition}'s current responses to such requests necessarily cannot present all information {clientPosition} may ultimately discover and utilize or rely upon in this matter. {clientPosition} thus reserves all rights to supplement or amend its responses in accordance with applicable rules, laws, orders or agreements of the parties, if, as and when circumstances may warrant.",
]
print(
"______________________________________________________________NEW YORK MAKE OBJECTION FIRED"
)
p = document.add_paragraph()
p.add_run("GENERAL OBJECTIONS").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
arrLen = len(objectionsArray)
count = 0
for obj in objectionsArray:
if count == arrLen:
break
paragraph = document.add_paragraph(f"{count + 1}. {obj}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
return document
# New Jersey *******************************************************************/
def make_nj_gen_obj(document, clientPosition, servingParty):
objectionsArray = [
f"All of {clientPosition}s responses to the discovery requests being answered are subject to the following objections, in addition to any and all objections stated in the answers to each individual request.",
f"""{clientPosition} objects to the definitions and instructions included in {servingParty}'s discovery requests, to the extent that: (a) the definitions or instructions are inconsistent with any applicable statutes, regulations, laws, legal precedents, or the terms of any applicable agreements or other legal documents; (b) the definitions or instructions seek to impose on {clientPosition} obligations that exceed the requirements of the New Jersey Rules of Court; and/or, (c) the definitions are overly broad or inclusive, and presume or assume unproven assertions of fact or law.""",
f"In responding to these requests, {clientPosition} does not admit or concede any presumptions or assumptions embedded in {servingParty}'s definitions.",
f"{clientPosition} objects to any and all requests to the extent they seek or may be interpreted to seek disclosure of information not within the scope of R. 4:10-2(a) or not within the scope of what is permitted under any applicable Case Management Order entered in this case, and {clientPosition} reserves all rights to contest any such matters in any other context or proceeding where they may be relevant.",
f"{clientPosition} objects to any and all requests to the extent they seek or may be interpreted to seek disclosure of any information which (a) is subject to the attorney-client privilege; (b) is covered by the 'work product' doctrine; (c) is subject to the self-critical analysis privilege; (d) is subject to the required reports privilege; (e) is subject to a joint defense or common interest privilege; (f) was generated in anticipation of litigation or for trial by or for {clientPosition} or any representatives of {clientPosition} including attorneys, consultants or agents; (g) relates to the identity or opinions of consultants or experts who have been retained or specially employed in anticipation of litigation and who are not expected to be called as witnesses at trial; (h) is protected as a trade secret; (i) is subject to a protective order or confidentiality order or agreement which was entered or made in another matter, to the extent the same prevents disclosure in this matter; and/or (j) is otherwise privileged, protected from disclosure, or beyond the scope of discovery under applicable rules and laws. {clientPosition} does not intend to disclose or produce any such information in response to the request being answered, and the following responses should be read accordingly. Any disclosure of information which is privileged or otherwise protected from disclosure is inadvertent, and all rights to demand return and/or destruction of any such information are reserved.",
f"{clientPosition} objects to the propounding parties' requests insofar as they seek a proposition of law and/or the formulation of a legal theory, or seek contentions regarding factual matters as to which essential discovery is incomplete. {clientPosition}'s current responses to such requests necessarily cannot present all information {clientPosition} may ultimately discover and utilize or rely upon in this matter. {clientPosition} thus reserves all rights to supplement or amend its responses in accordance with applicable rules, laws, orders or agreements of the parties as circumstances may warrant.",
]
print(
"______________________________________________________________NEW JERSEY MAKE OBJECTION FIRED"
)
p = document.add_paragraph()
p.add_run("GENERAL OBJECTIONS").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
arrLen = len(objectionsArray)
count = 0
for obj in objectionsArray:
if count == arrLen:
break
paragraph = document.add_paragraph(f"{count + 1}. {obj}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
return document
# Florida *******************************************************************/
def make_fl_gen_obj(document, clientPosition, servingParty):
objectionsArray = [
f"All of {clientPosition}s responses to the discovery requests answered herein are subject to the following objections, in addition to any and all objections stated in the answers to each individual request.",
f"""{clientPosition} objects to the definitions and instructions included in {servingParty}'s discovery requests, to the extent that: (a) the definitions or instructions are inconsistent with any applicable statutes, rules, legal precedents, or the terms of any applicable agreements or orders; (b) the definitions or instructions seek to impose on {clientPosition} obligations that exceed the requirements of the Florida Rules of Civil Procedure; and/or, (c) the definitions are overly broad or inclusive, and presume or assume unproven assertions of fact or law.""",
f"In responding to these requests, {clientPosition} does not admit or concede any presumptions or assumptions embedded in {servingParty}'s definitions.",
f"{clientPosition} objects to any and all requests to the extent they seek or may be interpreted to seek disclosure of information not within the scope of what is permitted under any applicable Case Management Order entered in this case, and {clientPosition} reserves all rights to contest any such matters in any other context or proceeding where they may be relevant.",
f"{clientPosition} objects to any requests to the extent they seek disclosure of information which is subject to (a) the attorney-client privilege; (b) the 'work product' doctrine; (c) the spousal communications privilege; (e) a joint defense or common interest privilege; or (f) was generated in anticipation of litigation by or for {clientPosition} or any representatives of {clientPosition}; or (g) that relates to the identity or opinions of experts retained in anticipation of litigation and who are not expected to be called as trial witnesses; or (h) is protected as a trade secret; (i) subject to a protective order in another matter; or (j) is otherwise privileged, protected from disclosure, or beyond the scope of discovery. {clientPosition} does not intend to disclose any such information, and disclosure of any information which is privileged or protected from disclosure is inadvertent. All rights to demand return or destruction of such information are reserved.",
f"{clientPosition} objects to the propounding parties' requests insofar as they seek a conclusion of law and/or formulation of a legal theory, or seek contentions regarding factual matters as to which essential discovery is incomplete. {clientPosition}'s current responses to such requests necessarily cannot present all information {clientPosition} may ultimately discover and utilize or rely upon in this matter. {clientPosition} thus reserves all rights to supplement or amend its responses in accordance with applicable rules, laws, orders or agreements of the parties as circumstances may warrant.",
]
print(
"______________________________________________________________FLORIDA MAKE OBJECTION FIRED"
)
p = document.add_paragraph()
p.add_run("GENERAL OBJECTIONS").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
arrLen = len(objectionsArray)
count = 0
for obj in objectionsArray:
if count == arrLen:
break
paragraph = document.add_paragraph(f"{count + 1}. {obj}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
return document

View File

@@ -0,0 +1,26 @@
import bottle
from bottle import run, get, post, request, route
from bottle import HTTPResponse
from generateDocument import GenerateBody
from pathlib import Path
import json
def fix_environ_middleware(app):
def fixed_app(environ, start_response):
environ['wsgi.url_scheme'] = 'https'
environ['HTTP_X_FORWARDED_HOST'] = 'novodraft.com'
return app(environ, start_response)
return fixed_app
app = bottle.default_app()
app.wsgi = fix_environ_middleware(app.wsgi)
gen_body = GenerateBody()
@post('/gen-req-docx/<docId>')
def newdoc(docId):
print('________________in pyserv docId', docId)
gen_body.generate(docId)
respBody = json.dumps({'Status': 'Success'})
return bottle.HTTPResponse(status=200, body=respBody)
run(app, host='127.0.0.1', port=8087, debug=True)

View File

@@ -0,0 +1,65 @@
import json
from docx import Document
from docx.shared import Inches
from docx.shared import Pt
from docx.shared import Length
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
def make_outgoing_instructions(document, clientPosition, servingParty):
print(
"______________________________________________________________OUTGOING FIRED"
)
instructionsArray = [
"These requests are continuing in nature and require you to file supplementary or amended responses if you obtain further, different or contradictory information at any time prior to a trial of this action.",
"Unless otherwise stated, these requests refer to the time, place, and circumstances of the occurrences described and/or complained of in the Complaint and which form the basis for this action.",
"Where name and identity of a person is required, state the full name, home address and business address, if known.",
"When the identity of a corporation or other business entity is requested, state the entity's principal place of business, address and telephone number. Also, set forth the individual or individuals with knowledge of the facts and circumstances that form the basis for this action.",
"Where knowledge or information in possession of a party is requested, such request includes knowledge of the party's agents, representatives, and, unless privileged, attorneys. ",
"Where the respondent is a corporation or other business entity, state the name, address and title of persons supplying the information and making the affidavit, and state with particularity the source of his or her information and basis of knowledge.",
"If you are unable to provide an accurate answer to an interrogatory, or are uncertain regarding a response to any item, please provide your best estimate of the information requested, specifying that the answer is merely an estimate, and that an accurate response cannot be given by you to the item.",
"If you withhold any information or documents on the basis of privilege, confidentiality, relevance, or for any other reason whatsoever please identify it, providing sufficient information to identify the withheld documents or items for this party and the Court to determine whether the documents, items or information should be disclosed.",
]
definitionsArray = [
"'You' refers to the party to whom the requests are addressed and any additional parties or entities as described in the foregoing instructions and these definitions.",
"“Person”, unless otherwise specified”, includes the plural as well as the singular, and includes in its meaning any natural person, or artificial or legal entity, including corporations, partnerships, joint ventures, associations, governmental agencies, groups, organizations, and any and every other form of entity cognizable at law.",
"“Document” means and includes all written and graphic matter of every kind and description, whether printed or produced by any process or by hand, whether final draft or reproduction, whether in the actual or constructive possession, custody or control of the respondent to a given interrogatory, including any and all written letters, correspondence, memoranda, notes, statements, transcripts, files, charters, articles of incorporation, securities, bonds, stocks, certificates of deposit, evidences of debt, contracts, agreements, licenses, memoranda or notes of telephone or personal conversations, work papers, tapes, charts, reports, books, ledgers, telegrams, sound recordings, books of account, customer account statements, financial statements, catalogs, checks, check stubs, and written statements of witnesses or other persons having knowledge pertaining to the pertinent facts requested or relating to the interrogatory or subpart thereof, whether or not these documents are claimed to be privileged against disclosure.",
"“Identify” means, when used with reference to an individual person, organization, corporation or association, to state the full name, home and work addresses, e-mail address, home and business telephone numbers, present or last known position and business affiliation and position both in the past and at the time said interrogatory or subpart thereof is being responded to.",
"The term “identify” further means, when used with reference to a document, to state the date it was created, its author, the signatory, if different, the addressee, the recipient of all copies, the type of document (e.g. chart, memorandum, letter, or other written document) and its present or last known custodian.",
"“Describe” means that the person or entity to whom the interrogatory or subpart thereof is directed should state what is requested to be described, including all facts and opinions known and held regarding, relating to, or pertinent to what is requested to be described, and (i) the identity of each person or entity involved or having any knowledge of each fact or opinion that relates to what is so described, (ii) the identity of each document evidencing the answer or response given or relating, referring or pertaining to said subject-matter in any way, and (iii) all relevant or material dates and time periods, specifying the way in which said dates or time periods are pertinent to the subject-matter described.",
]
p = document.add_paragraph()
p.add_run("INSTRUCTIONS").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
arrLen = len(instructionsArray)
count = 0
for inst in instructionsArray:
if count == arrLen:
break
paragraph = document.add_paragraph(f"{count + 1}. {inst}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
p = document.add_paragraph()
p.add_run("DEFINITIONS").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
arrLen = len(definitionsArray)
count_two = 0
for defn in definitionsArray:
if count_two == arrLen:
break
paragraph = document.add_paragraph(f"{count_two + 1}. {defn}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count_two = count_two + 1
return document

View File

@@ -0,0 +1,41 @@
import json
from docx import Document
from docx.shared import Inches
from docx.shared import Pt
from docx.shared import Length
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
def make_requests_for_production(document, clientPosition, servingParty):
requestsForProductionArray = [
"All documents identified, directly or indirectly, in your answers to Interrogatories.", "All written reports of all expert witnesses with whom you or your attorneys have consulted, including, of course, those persons you expect to call as an expert witness at trial.",
"All documents upon which any expert witness upi intend to call at trial relied upon in formulating an opinion about the subject matter of this action.",
"The most recent curriculum vitae of each expert whom you expect to call as an expert witness at trial.",
"All notes, correspondence, bills, invoices, diagrams, photographs, or other documents prepared or reviewed by each person whom you expect to call as an expert witness at trial.",
"All invoices generated by expert witnesses generated for performing all expert witness services to you, including but not limited to, fees for the medical examination, the records review, the pretrial preparation, any telephone conference, any trial testimony anticipated and any other fee paid for expert fees.",
"Any and all written, recorded, or signed statements of any party, including the plaintiff, defendant, witnesses, investigators, or agent, representative or employee of the parties concerning the subject matter of this action.",
"All documents, photographs, videotapes or audio tapes, recordings in any medium, diagnostic images, diagrams, records, surveys or other graphic representations of information concerning the subject matter of this action.",
"Any documents which afforded, described or pertained to liability insurance coverage for the occurrences which are the subject matter of the complaint.",
"Any documents identified in any other parties' answers to Interrogatories in your possession, if any.",
"Any documents received pursuant to a subpoena request in this case.",
"Any document prepared during the regular course of business as a result of the occurrence complained of in the complaint.",
"Copies of any treaties, standards in the industry, legal authority, rule, case, statute, or code that will be relied upon in the defense of this case.",
]
p = document.add_paragraph()
p.add_run("REQUESTS FOR PRODUCTION OF DOCUMENTS").underline = True
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
arrLen = len(requestsForProductionArray)
count = 0
for req in requestsForProductionArray:
if count == arrLen:
break
paragraph = document.add_paragraph(f"{count + 1}. {req}")
paragraph.paragraph_format.line_spacing = Pt(20)
paragraph.paragraph_format.space_after = Pt(12)
paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
count = count + 1
return document

View File

@@ -0,0 +1,121 @@
import * as fs from "fs";
import { newYorkCaptionTemplate } from "./documentTemplates/captionTemplates.mjs";
//import { newYorkStyleTemplate } from "./documentTemplates/styleTemplates.mjs";
function selectRequestPath(reqType, isRequests, folder) {
let dir;
if (reqType == "interrogatories") {
dir = `../Documents/Requests/Parsedrogs/${folder}/`;
} else if (reqType == "admissions") {
dir = `../Documents/Requests/Parsedadmit/${folder}/`;
} else if (reqType == "production") {
dir = `../Documents/Requests/Parsedprod/${folder}`;
} else if (reqType == "combined-numbered") {
dir = `../Documents/Requests/Parsedcombined/${folder}/`;
}
return dir;
}
function selectResponsePath(reqType, isRequests, folder) {
let dir;
if (reqType === "interrogatories") {
dir = `./Documents/Responses/Rogresp/${folder}/`;
} else if (reqType == "admissions") {
dir = `./Documents/Responses/Admitresp/${folder}/`;
} else if (reqType == "production") {
dir = `./Documents/Responses/Prodresp/${folder}/`;
} else if (reqType == "combined-numbered") {
dir = `./Documents/Responses/Combinedresp/${folder}/`;
}
return dir;
}
async function makeDir(docId, dest) {
const dir = `/var/www/ax3Services/docGenService/${dest}/${docId}`;
//const dir = `/Users/kjannette/workspace/ax3/ax3Services/docGenService/${dest}/${docId}`;
fs.mkdir(dir, function (err) {
if (err) {
console.log("createDoc makeDir. Error creating directory: " + err);
}
});
}
/* ******************************* generateDoc ******************************* */
const responseHeaderGenerator = (docId, reqType, data) => {
const documentType = reqType.toUpperCase();
const jurisdiction = data?.jurisdiction.toUpperCase();
console.log("---------------------------------->data", data);
//const responndantPosition =
// / data?.clientPosition === "Plaintiff" ? "Plaintiff" : "Defendant";
//const { defendant, plaintiff, caseNumber, judge } = data;
//const venue = data.venue.toUpperCase();
//const comesNow = responndantPosition === "Plaintiff" ? plaintiff : defendant;
//let doc;
//const dest = "Docxstaging";
//const dest2 = "Docxinfo";
//makeDir(docId, dest);
//makeDir(docId, dest2);
/*
const templateNY = newYorkCaptionTemplate(
jurisdiction,
venue,
plaintiff,
defendant,
caseNumber,
judge,
documentType,
comesNow
);
*/
//doc = new Document(newYorkStyleTemplate);
//const temp1 = JSON.parse(responseFileData);
//const responseArray = temp1[0].responses;
// /const temp2 = JSON.parse(requestFileData);
//const requestArray = temp2[0].requests;
//const allChildren = [];
/*
doc.addSection({
properties: {
type: SectionType.CONTINUOUS,
},
children: templateNY,
});
*/
/*
Packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync(
`/Users/kjannette/workspace/ax3/ax3Services/docGenService/Docxstaging/${docId}.docx`,
buffer
);
});
*/
//const dir = `/var/www/ax3Services/docGenService/Docxinfo/${docId}.json`;
const dir = `/Users/kjannette/workspace/ax3/ax3Services/docGenService/Docxinfo/${docId}.json`;
data["currentRequestType"] = reqType;
const saveData = JSON.stringify(data);
fs.writeFile(dir, saveData, function (err) {
if (err) {
return console.log("Error writing in responseHeaderGenerator", err);
}
});
};
export default responseHeaderGenerator;
/*
import {
AlignmentType,
Document,
convertInchesToTwip,
Packer,
Paragraph,
Styles,
Style,
SectionType,
TextRun,
UnderlineType,
Underline,
} from "docx";
*/

View File

@@ -0,0 +1,207 @@
//const fs = require("fs");
const { readFile } = require("fs/promises");
const searchRog1 = "interrogatories";
const searchRog2 = "interrogatory";
const searchProduce1 = "produce";
const searchProduce2 = "production";
const searchProduce4 = "production of documents";
const searchProduce5 = "request for production";
const searchProduce6 = "request for produc";
const searchAdmit1 = "admit";
const searchAdmit2 = "admission";
const searchAdmit3 = "admissions";
const total = {
rogs: null,
docProd: null,
admit: null,
combined: null,
};
function includesTest(str, regex) {
return (str.match(regex) || []).length;
}
async function inspectFile(data) {
const searchTermArr = [
"interrogatories",
"interrogatory",
"produce",
"production",
"production of documents",
"request to produce",
"request for production",
"admit",
"admission",
"admissions",
"request to admit",
"request for admissions",
];
/*
Below patterns are Michigan - specific
const regexPattern =
/interrogatories (#?[\sa-z0-9]{0,15}) and requests? for production+\b/g;
const regexPattern1 =
/interrogatories[\sa-z0-9]{0,15}and requests? for production+\b/;
*/
const regexPattern2 =
/interrogatories (#?[\sa-z0-9]{0,15}) and requests? for production+\b/g;
const resultArray = [];
if (data) {
const temp = data.toString();
//const containsPattern = includesTest(temp, regexPattern);
//const containsPattern1 = includesTest(temp, regexPattern1);
const containsPattern2 = includesTest(temp, regexPattern2);
if (
containsPattern2 ||
temp
.toLowerCase()
.includes("interrogatories and request for production") ||
temp
.toLowerCase()
.includes("interrogatories and requests for production") ||
temp.toLowerCase().includes("interrogatories and document requests") ||
temp.toLowerCase().includes("and requests for production of documents") ||
temp.toLowerCase().includes("discovery and inspection") ||
temp.toLowerCase().includes("combined discovery demands") ||
temp.toLowerCase().includes("demand for discovery") ||
temp.toLowerCase().includes("discovery demands") ||
temp.toLowerCase().includes("combined demands")
) {
total.combined = "combined-numbered";
}
}
let lines = await data.split("\n");
searchTermArr.forEach((term) => {
let obj = { searchTerm: "", count: 0 };
obj.searchTerm = term;
lines.forEach(function (line) {
if (line.toLowerCase().indexOf(term) != -1) {
obj.count++;
}
});
resultArray.push(obj);
});
if (total.combined === "combined-numbered") {
return total;
} else {
return resultArray;
}
}
// TODO find the first iteration one in chain - would it be tesseWatcher? maybe py watcher
// major refactor - do after launch
const iterateFilePaths = async (paths) => {
const result = await Promise.all(
paths.map(async (path) => {
fileData = await readFile(path, "utf8");
resultArrOrObj = await inspectFile(fileData);
return resultArrOrObj;
})
);
return result;
};
async function classifyDoc(sortedPaths) {
const master = [
{ searchTerm: "interrogatories", count: 0 },
{ searchTerm: "interrogatory", count: 0 },
{ searchTerm: "produce", count: 0 },
{ searchTerm: "production", count: 0 },
{ searchTerm: "production of documents", count: 0 },
{ searchTerm: "request to produce", count: 0 },
{ searchTerm: "request for production", count: 0 },
{ searchTerm: "admit", count: 0 },
{ searchTerm: "admission", count: 0 },
{ searchTerm: "admissions", count: 0 },
{ searchTerm: "interrogatories and request for production", count: 0 },
{ searchTerm: "interrogatories and requests for production", count: 0 },
{ searchTerm: "interrogatories and requests for production", count: 0 },
];
const result = {
rogs: null,
docProd: null,
admit: null,
};
const termOccuranceCount = await iterateFilePaths(sortedPaths);
const foundObj = termOccuranceCount.find(
(item) => item.combined === "combined-numbered"
);
if (foundObj) {
//pass
}
let interrogatories = 0;
let interrogatory = 0;
let produce = 0;
let production = 0;
let admit = 0;
let admission = 0;
let admissions = 0;
let rogAndProd = 0;
let rogAndProd2 = 0;
let rogAndProd3 = 0;
let rogAndProd4 = 0;
if (!foundObj) {
termOccuranceCount.forEach((array) => {
array.forEach((obj) => {
if (obj.searchTerm === "interrogatories") {
interrogatories = interrogatories + obj.count;
} else if (obj.searchTerm === "interrogatory") {
interrogatory = interrogatory + obj.count;
} else if (obj.searchTerm === "produce") {
produce = produce + obj.count;
} else if (obj.searchTerm === "production") {
production = production + obj.count;
} else if (obj.searchTerm === "production of documents") {
production = production + obj.count;
} else if (obj.searchTerm === "request to produce") {
production = production + obj.count;
} else if (obj.searchTerm === "request for production") {
production = production + obj.count;
} else if (obj.searchTerm === "admit") {
admit = admit + obj.count;
} else if (obj.searchTerm === "admission") {
admission = admission + obj.count;
} else if (obj.searchTerm === "admissions") {
admissions = admissions + obj.count;
} else if (obj.searchTerm === "request to admit") {
admissions = admissions + obj.count;
} else if (obj.searchTerm === "request for admissions") {
admissions = admissions + obj.count;
}
});
});
}
result.rogs = interrogatories + interrogatory;
result.docProd = produce + production;
result.admit = admit + admission + admissions;
result.combined = false;
if (foundObj) {
return foundObj;
} else {
return result;
}
}
module.exports = {
classifyDoc,
};

View File

@@ -0,0 +1,708 @@
const fs = require("fs");
const docClassifer = require("./docClassifier.js");
//const checkService = require("../checkService/checkService.js");
const modelController = require("../agent/ModelController.js");
const { updateDB } = require("../firebase/firebase.js");
const { v4: uuidv4 } = require("uuid");
const path = require("path");
const { count } = require("firebase/firestore");
async function readDir(direcPath, folder, countObject) {
const fdirup = path.join(
__dirname,
"..",
"Documents",
"Textfiles",
`${folder}`
);
try {
const dirArray = countObject.files.map((file) => {
return `${fdirup}/${file.split(".")[0]}.txt`;
});
const sortedFilePaths = dirArray.sort();
const docType = await docClassifer.classifyDoc(sortedFilePaths, folder);
console.log("====================================== docParser readDir");
let parseOneCount = 0;
methodSelector(
docType,
sortedFilePaths,
folder,
parseOneCount,
countObject
);
} catch (err) {
console.log("read error", err);
}
}
async function methodSelector(
docType,
filePaths,
folder,
parseOneCount,
countObject
) {
let searchStr;
let determinedDocType;
if (docType.combined === "combined-numbered") {
determinedDocType = "combined-numbered";
const isRequests = true;
console.log(
"=========================================determinedDocType in docParser methodSelecotr",
determinedDocType
);
updateDB(docId, determinedDocType);
modelController.createArrayOfQuestions(
folder,
determinedDocType,
isRequests,
countObject
);
return;
} else if (docType.rogs > docType.docProd && docType.rogs > docType.admit) {
determinedDocType = "interrogatories";
let parseRogsCount = 0;
parseRogs(docType, filePaths, folder, determinedDocType, parseRogsCount);
} else if (
docType.docProd > docType.rogs &&
docType.docProd > docType.admit
) {
determinedDocType = "production";
parseProdCount = 0;
parseProduction(
docType,
filePaths,
folder,
parseOneCount,
determinedDocType,
parseProdCount
);
return;
} else if (docType.admit > docType.rogs && docType.admit > docType.docProd) {
determinedDocType = "admissions";
let parseAdmitCount = 0;
parseAdmissions(
docType,
filePaths,
folder,
parseOneCount,
determinedDocType,
parseAdmitCount
);
return;
} else if (
docType.combined > docType.rogs &&
docType.combined > docType.docProd &&
docType.combined > docType.admit
) {
// maybe deprecate
determinedDocType = "combined";
parseCombined(docType, filePaths, folder, parseOneCount, determinedDocType);
} else {
// To avoid undefined errors in later checks (for now)
searchStr = "N~U**LL";
}
return determinedDocType;
}
/*******************************************************************************
*
* Combined (Interrogatories and Requests for Production) Request parser
*
*******************************************************************************/
async function parseCombined(
docType,
filePaths,
folder,
parseOneCount,
determinedDocType,
parseCombinedCount
) {
const processArray = [];
const rogs = [];
filePaths.forEach((filePath) => {
fileData = fs.readFileSync(filePath, "utf8", function (err) {
console.log("error in readFile", err);
});
const arr = [];
searchStr = 1;
const stringChunk = fileData.toString().toLowerCase();
const string = fileData.toString().toLowerCase();
for (
let pos = stringChunk.lastIndexOf(`${searchStr.toString()}.`);
pos > -1;
pos = stringChunk.indexOf(`${searchStr.toString()}.`, pos + 1)
) {
arr.push(pos);
searchStr++;
console.log("arr, pos", arr, pos);
}
const questionsArray = arr.map((item, i) => {
return string.slice(arr[i], arr[i + 1]);
});
const clean = questionsArray.map((item) => {
return item.replace(/\r?\n|\r/g, "");
});
processArray.push(...clean);
const unique = processArray.filter(function (item, pos) {
return processArray.indexOf(item) == pos;
});
unique.forEach((item) => {
let obj = {};
const requestId = uuidv4();
obj["requestId"] = requestId;
obj["text"] = item;
rogs.push(obj);
});
if (rogs.length < 3) {
} else {
makeDir(folder, determinedDocType);
let requestArray = [];
let requestObject = {};
requestObject["type"] = determinedDocType;
requestObject["requests"] = rogs;
requestArray.push(requestObject);
saveParsedRogs(requestArray, folder, determinedDocType);
}
});
return;
}
/*******************************************************************************
*
* Request for production of documents parser
*
*******************************************************************************/
async function parseProduction(
docType,
filePaths,
folder,
parseOneCount,
determinedDocType,
parseProdCount
) {
const initialHeaderString = "requests for production"; // /^request* for admission*$/;
const processArray = [];
const rogs = [];
let searchStr;
if (parseProdCount < 1) {
searchStr = "REQUEST FOR PRODUCTION";
} else if (parseProdCount === 1) {
searchStr = "REQUEST NO";
} else if (parseProdCount === 2) {
searchStr = "REQUEST NUM";
}
filePaths.forEach((filePath, mainIndex) => {
let fileData;
fileData = fs.readFileSync(filePath, "utf8");
const arr = [];
const stringChunk = fileData.toString().toLowerCase();
const string = fileData.toString().toLowerCase();
for (
let pos = stringChunk.indexOf(searchStr.toLowerCase());
pos > -1;
pos = stringChunk.indexOf(searchStr.toLowerCase(), pos + 1)
) {
arr.push(pos);
}
const questionsArray = arr.map((item, i) => {
return string.slice(arr[i], arr[i + 1]);
});
const clean = questionsArray.map((item) => {
return item.replace(/\r?\n|\r/g, "");
});
processArray.push(...clean);
});
const unique = processArray.filter(function (item, pos) {
return processArray.indexOf(item) == pos;
});
unique.forEach((item) => {
let obj = {};
const requestId = uuidv4();
obj["requestId"] = requestId;
obj["text"] = item;
rogs.push(obj);
});
if (rogs.length < 2) {
if (parseProdCount < 2) {
parseProdCount++;
parseProduction(
docType,
filePaths,
folder,
parseOneCount,
determinedDocType,
parseProdCount
);
} else {
determinedDocType = "combined-numbered";
const isRequests = true;
modelController.createArrayOfQuestions(
folder,
determinedDocType,
isRequests
);
return;
}
} else {
const docId = folder;
const reqType = "production"; //determinedDocType var value is lost by here not sure why but this hack should fix
const directionVar = "Requests";
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
`${directionVar}`,
`${reqType}`,
`${docId}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("makeDir utilities error creating directory: " + err);
}
});
let requestArray = [];
let requestObject = {};
requestObject["type"] = determinedDocType;
requestObject["requests"] = rogs;
requestArray.push(requestObject);
const fileSuffix = "-jbk-parsedRequests.json";
const data = JSON.stringify(requestArray);
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log("Error in parseProd writeFile:", err);
}
}
);
}
}
/*******************************************************************************
*
* Requests for Admissions parser
*
*******************************************************************************/
async function parseAdmissions(
docType,
filePaths,
folder,
parseOneCount,
determinedDocType,
parseAdmitCount
) {
const initialHeaderString = "requests for admissions"; //^request* for admission*$/;
console.log(
"parseAdmissions called-------------------------------------------"
);
const processArray = [];
const rogs = [];
let searchStr;
if (parseAdmitCount < 1) {
searchStr = "REQUEST NO";
} else if (parseAdmitCount === 1) {
searchStr = "ADMIT THAT";
} else if (parseAdmitCount === 2) {
searchStr = "ADMIT";
} else if (parseAdmitCount === 3) {
regex = /^[1-9]?$/;
searchStr = `Request No. ${reggex}`;
} else if (parseAdmitCount === 4) {
regex = /^[1-9][0-9]?$/;
searchStr = `Request No. ${reggex}`;
} else if (parseAdmitCount === 5) {
regex = /^[1-9]?$/;
searchStr = `Request ${reggex}.`;
} else {
regex = /^[1-9][0-9]?$/;
searchStr = `Request ${reggex}.`;
}
filePaths.forEach((filePath, mainIndex) => {
let fileData;
fileData = fs.readFileSync(filePath, "utf8");
const arr = [];
const stringChunk = fileData.toString().toLowerCase();
//const string = fileData.toString().toLowerCase(); this might solve lowercase problem
const string = fileData.toString();
for (
let pos = stringChunk.indexOf(searchStr.toLowerCase());
pos > -1;
pos = stringChunk.indexOf(searchStr.toLowerCase(), pos + 1)
) {
arr.push(pos);
}
const questionsArray = arr.map((item, i) => {
return string.slice(arr[i], arr[i + 1]);
});
const clean = questionsArray.map((item) => {
let temp4;
const temp = item.replace(/\r?\n|\r/g, "");
const temp2 = temp.replace("request no.", "").trim();
const temp3 = temp2.replace("REQUEST NO.", "").trim();
const firstChar = Number(temp3[0]);
if (Number.isInteger(firstChar)) {
temp4 = temp3.substring(3);
char = temp3[2].toUpperCase();
return `${char}${temp4}`;
} else {
return temp2;
}
});
processArray.push(...clean);
});
const unique = processArray.filter(function (item, pos) {
return processArray.indexOf(item) == pos;
});
unique.forEach((item) => {
let obj = {};
const requestId = uuidv4();
obj["requestId"] = requestId;
obj["text"] = item;
rogs.push(obj);
});
if (rogs.length < 2) {
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>rogs.length < 2 fired");
if (parseAdmitCount < 6) {
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>parseAdmitCount < 6 fired");
let determinedDocType = "admissions";
parseAdmitCount++;
parseAdmissions(
docType,
filePaths,
folder,
parseOneCount,
determinedDocType,
parseAdmitCount
);
} else {
console.log(
"--------------------> Parsed admissions switching to LLM calling createArrayOfQuestions"
);
const isRequests = true;
determinedDocType = "combined-numbered";
updateDB(docId, determinedDocType);
modelController.createArrayOfQuestions(
folder,
determinedDocType,
isRequests
);
}
} else {
const reqType = "admissions"; //determinedDocType var value is lost by here not sure why but this hack should fix
const directionVar = "Requests";
const docId = folder;
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
"Requests",
"admissions",
`${docId}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("makeDir utilities error creating directory: " + err);
}
});
let requestArray = [];
let requestObject = {};
requestObject["type"] = determinedDocType;
requestObject["requests"] = rogs;
requestArray.push(requestObject);
parseTextFiles2SaveCount = 0;
parseAdmitCount = 0;
console.log("requestArray", requestArray);
const data = JSON.stringify(requestArray);
const fileSuffix = "-jbk-parsedRequests.json";
fs.writeFile(
`${saveDirectory}/${docId}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log("Error in parse admit writeFile:", err);
}
}
);
const reqstType = "admissions";
const isRequests = true;
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
await sleep(3000);
modelController.arrayGenAnswers(docId, reqstType, isRequests);
}
}
/*******************************************************************************
*
* Interrogatory Parser
*
*******************************************************************************/
async function parseRogs(
docType,
filePaths,
folder,
determinedDocType,
parseRogsCount
) {
let searchStr;
console.log(
"***************************************************************************** PARSE ROGS FIRED"
);
if (parseRogsCount < 1) {
searchStr = "INTERROGATORY NO";
} else {
searchStr = "INTERROGATORY NUM";
}
const processArray = [];
const rogs = [];
filePaths.forEach((filePath) => {
let fileData = fs.readFileSync(filePath, "utf8");
const arr = [];
if (fileData) {
if (!fileData.toLowerCase().includes(searchStr.toLowerCase())) return;
}
const string = fileData.toString();
for (
let pos = fileData.toLowerCase().indexOf(searchStr.toLowerCase());
pos > -1;
pos = fileData.toLowerCase().indexOf(searchStr.toLowerCase(), pos + 1)
) {
arr.push(pos);
}
const questionsArray = arr.map((item, i) => {
return string.slice(arr[i], arr[i + 1]);
});
const clean = questionsArray.map((item) => {
return item.replace(/\r?\n|\r/g, "");
});
processArray.push(...clean);
});
const unique = processArray.filter(function (item, pos) {
return processArray.indexOf(item) == pos;
});
const regex = /[A-Za-z]+ [A-Za-z]+\. [A-Za-z0-9]+:/;
const regex2 = new RegExp(/.[Pp]age\s\d{1,2}$/);
const tempArr = unique.map((item) => {
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
const scrubbed = item.replace(regex, "");
const scrubbedMore = scrubbed.replace(regex2, ".");
const caps = capitalizeFirstLetter(scrubbedMore);
return caps;
});
tempArr.forEach((item) => {
let obj = {};
const interrogatoryId = uuidv4();
obj["interrogatoryId"] = interrogatoryId;
obj["text"] = item;
rogs.push(obj);
});
if (rogs.length < 2) {
if (parseRogsCount < 2) {
parseRogsCount++;
parseRogs(docType, filePaths, folder, determinedDocType, parseRogsCount);
} else {
const _isRequests = true;
const reqType = "combined-numbered";
console.log(
"---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- parseRogs GIVING UP calling createArrayOfQuestions ---- ---- "
);
modelController.createArrayOfQuestions(folder, reqType, _isRequests);
return;
}
} else {
let requestArray = [];
let requestObject = {};
requestObject["type"] = "interrogatories";
requestObject["requests"] = rogs;
requestArray.push(requestObject);
const docId = folder;
const reqType = "interrogatories"; //determinedDocType var value is lost by here not sure why but this hack should fix
const saveDirectory = path.join(
__dirname,
"..",
"Documents",
"Requests",
"interrogatories",
`${folder}`
);
fs.mkdir(`${saveDirectory}`, function (err) {
if (err) {
console.log("makeDir utilities error creating directory: " + err);
}
});
const fileSuffix = "-jbk-parsedRequests.json";
const data = JSON.stringify(requestArray);
console.log(
"************************************************************** parseRogs updating DB"
);
updateDB(docId, reqType);
console.log(
" `${saveDirectory}/${docId}${fileSuffix}`",
`${saveDirectory}/${folder}${fileSuffix}`
);
fs.writeFileSync(
`${saveDirectory}/${folder}${fileSuffix}`,
data,
function (err) {
if (err) {
return console.log("Error in parseRogs writeFile:", err);
}
}
);
// Send it straight to LLM
const isRequests = false;
modelController.arrayGenAnswers(docId, reqType, isRequests);
}
}
/*******************************************************************************
*
* Create a directory
*
*******************************************************************************/
async function makeDir(folder, determinedDocType) {
let dir;
if (determinedDocType === "interrogatories") {
dir = path.join(
__dirname,
"..",
"Documents",
"Requests",
"interrogatories",
`${folder}`
);
} else if (determinedDocType === "production") {
dir = path.join(
__dirname,
"..",
"Documents",
"Requests",
"production",
`${folder}`
);
} else if (determinedDocType === "admissions") {
dir = path.join(
__dirname,
"..",
"Documents",
"Requests",
"admissions",
`${folder}`
);
} else if (determinedDocType === "combined-numbered") {
dir = path.join(
__dirname,
"..",
"Documents",
"Requests",
"combnined-numbered",
`${folder}`
);
} else {
dir = `../Documents/Requests/Fallback/${folder}`;
}
fs.mkdir(dir, function (err) {
if (err) {
console.log("docParser makeDir error. Error Creating Directory: " + err);
}
});
}
/*******************************************************************************
*
* Write result to a file
*
*******************************************************************************/
function saveParsedRogs(rogs, folder, determinedDocType) {
let dir;
const fdirup = path.join(__dirname, "..", "Documents", "Requests");
const data2 = JSON.stringify(rogs);
if (determinedDocType === "interrogatories") {
dir = `${fdirup}/interrogatories/${folder}/`;
} else if (determinedDocType === "production") {
dir = `${fdirup}/production/${folder}/`;
} else if (determinedDocType === "admissions") {
dir = `${fdirup}/admissions/${folder}/`;
} else if (determinedDocType === "combined-numbered") {
dir = `${fdirup}/combined-numbered/${folder}/`;
}
try {
if (folder) {
updateDB(folder, determinedDocType);
}
fs.writeFile(
dir + `${folder}-jbk-parsedRequests.json`,
data2,
function (err) {
if (err) {
return console.log("Error writing in saveParsedRogs", err);
}
}
);
} catch (err) {
console.log("docParser saveParsedRogs error. Error writing file:", err);
}
}
/*
const reqType = "admissions";
const docId = "73cf6d0d-15cd-4d12-9edc-00bfa8de8ebb";
const isRequests = true;
modelController.testSaveFunction(docId, reqType, isRequests);
*/
module.exports = {
readDir,
makeDir,
saveParsedRogs,
};

View File

@@ -0,0 +1,13 @@
const fs = require("fs");
const { readDir, parseTextFile } = require("./docParser");
function watchParseSave() {
const watchPath = "../Documents/Textfiles/";
fs.watch(watchPath, (eventType, filename) => {
console.log(eventType);
console.log(filename);
});
}
watchParseSave();

BIN
ax3Services/eng.traineddata Normal file

Binary file not shown.

View File

@@ -0,0 +1,172 @@
var firebase = require("firebase/app");
const { initializeApp } = require("firebase/app");
const { getFirestore } = require("firebase/firestore");
const {
collection,
deleteDoc,
doc,
onSnapshot,
query,
where,
updateDoc,
increment,
} = require("firebase/firestore");
const {
apiKey,
authDomain,
projectId,
storageBucket,
messagingSenderId,
appId,
measurementId,
} = require("./secrets");
const firebaseConfig = {
apiKey: apiKey,
authDomain: authDomain,
projectId: projectId,
storageBucket: storageBucket,
messagingSenderId: messagingSenderId,
appId: appId,
measurementId: measurementId,
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
/*******************************************************************************
*
* Write determinedDocType to Firebase DB
*
******************************************************************************/
async function updateDB(docId, docType) {
await updateDoc(doc(db, "documents", docId), {
docType: docType,
});
}
async function updateDBCombNum(docId, message) {
await updateDoc(doc(db, "documents", docId), {
combinedNumberedType: message,
});
}
async function getDoc(docId) {
try {
const docRef = doc(db, "documents", `${docId}`);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
const _doc = docSnap.data();
return _doc;
} else {
console.log("DB item does not exist");
}
} catch (error) {
console.log(`A system error occurred while getting doc: ${error}`);
}
}
/*******************************************************************************
*
* Resest Number of Available Docs each month
*
******************************************************************************/
async function getUsers() {
onSnapshot(collection(db, "users"), (snapshot) => {
const idArray = [];
const run = snapshot.docs.map((user) => {
const userData = user.data();
console.log("userData", userData);
const userDate = userData.subscriptionPeriodStart;
const subStart = new Date(userDate * 1000);
const subDayOfMonth = subStart.toDateString().split(" ")[2];
//stringDateconst subDay = stringDate;
const subDay = Number(subDayOfMonth);
const today = new Date();
const thisDay = today.getDate();
//console.log("subDay, thisDay", subDay, thisDay);
if (subDay === thisDay) {
//console.log("user.id =>", user.id);
const obj = {};
obj["userId"] = user.id;
obj["docsPerMonth"] = userData.subscriptionPlan[0].docsAllowedPerMonth;
obj["docsGenerated"] = userData.docsGenerated;
const tempCarryOverDocs =
userData.subscriptionPlan[0].docsAllowedPerMonth -
userData.docsGenerated;
let actualCarryOverDocs;
if (userData.subscriptionPlan[0].docsAllowedPerMonth === 3) {
if (tempCarryOverDocs >= 2) {
actualCarryOverDocs = 2;
} else {
actualCarryOverDocs = tempCarryOverDocs;
}
let tempDocsThisPeriod =
userData.subscriptionPlan[0].docsAllowedPerMonth +
actualCarryOverDocs;
const docsThisPeriod =
tempDocsThisPeriod > 5 ? 5 : tempDocsThisPeriod;
obj["docsThisPeriod"] = docsThisPeriod;
} else if (
userData.subscriptionPlan[0].docsAllowedPerMonth === 1 &&
tempCarryOverDocs > 0
) {
actualCarryOverDocs = 1;
obj["actualCarryOverDocs"] = actualCarryOverDocs;
let tempDocsThisPeriod =
userData.subscriptionPlan[0].docsAllowedPerMonth +
actualCarryOverDocs;
const docsThisPeriod =
tempDocsThisPeriod >= 2 ? 2 : tempDocsThisPeriod;
obj["docsThisPeriod"] = docsThisPeriod;
}
idArray.push(obj);
}
});
console.log("idArray", idArray);
idArray.forEach((obj) => {
// update db to add docsThisPeriod prop/value
});
});
return;
}
//getUsers();
module.exports = {
db,
updateDB,
updateDBCombNum,
getDoc,
};
/*
async function updateRespGenerationCount(docId) {
await updateDoc(doc(db, "documents", docId), {
docType: "interrogatories",
});
}
*/
//updateRespGenerationCount("4af8c149-1bda-44a7-8c54-be0c09ed655c");
/*
var admin = require("firebase-admin");
// Fetch the service account key JSON file contents
var serviceAccount = require("./agentx2-firebase-adminsdk.json");
// Initialize the app with a service account, granting admin privileges
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://agentx2.firebaseio.com",
});
// As an admin, the app has access to read and write all data, regardless of Security Rules
var db = admin.database();
var ref = db.ref("restricted_access/secret_document");
*/

2935
ax3Services/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

37
ax3Services/package.json Normal file
View File

@@ -0,0 +1,37 @@
{
"name": "agentx",
"version": "0.0.1",
"main": "index.js",
"dependencies": {
"@json2csv/node": "^7.0.6",
"async": "^3.2.4",
"cors": "^2.8.5",
"csvtojson": "^2.0.10",
"dirty-json": "^0.9.2",
"docx": "^8.2.4",
"express": "^4.18.2",
"firebase": "^10.6.0",
"http-proxy": "^1.18.1",
"json2csv": "^6.0.0-alpha.2",
"multer": "^1.4.5-lts.1",
"openai": "^4.17.4",
"openai-api": "^1.3.1",
"pdf2image": "^1.2.3",
"pdf2json": "^3.0.4",
"pdf2pic": "^3.0.3",
"react-router-dom": "^6.16.0",
"readline": "^1.3.0",
"stripe": "^14.14.0",
"system-sleep": "^1.3.7",
"tesseract.js": "^4.1.2",
"uuid": "^9.0.1",
"winston": "^3.11.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node ./app"
},
"author": "",
"license": "ISC",
"description": ""
}

View File

@@ -0,0 +1,82 @@
// stripe.js
const {
doc,
updateDoc,
collection,
query,
where,
getDocs,
} = require("firebase/firestore");
const { db } = require("../firebase/firebase.js");
async function handlePaymentFailure(paymentData) {
const usersRef = collection(db, "users");
const q = query(usersRef, where("email", "==", paymentData.customer_email));
try {
const querySnapshot = await getDocs(q);
if (querySnapshot.empty) {
console.log("No user found with the email:", paymentData);
return;
}
const userDoc = querySnapshot.docs[0];
const userRef = doc(db, "users", userDoc.id);
await updateDoc(userRef, {
subscriptionId: null,
customerId: null,
});
console.log("User data updated for email:", paymentData.customer_email);
} catch (error) {
console.error("Error updating user data:", error);
}
}
async function handleSubscriptionDeletion(
stripeCustomer,
stripeSubscription,
stripe
) {
try {
let customer_email = stripeCustomer.email;
const usersRef = collection(db, "users");
const q = query(usersRef, where("email", "==", customer_email));
const querySnapshot = await getDocs(q);
if (querySnapshot.empty) {
console.log("No user found with the email:", customer_email);
return;
}
const userDoc = querySnapshot.docs[0];
const userRef = doc(db, "users", userDoc.id);
const userData = userDoc.data();
//get the user's subscription ID and customer ID
const subscriptionId = userDoc.data().subscriptionId;
const customerId = userDoc.data().customerId;
if (!subscriptionId) {
return null;
}
//update the user's subscription data
await updateDoc(userRef, {
subscriptionId: null,
customerId: null,
});
return true;
} catch (error) {
console.error("Error cancelling subscription:", error);
//res.status(400).send({ error: { message: error.message } });
}
}
module.exports = {
handlePaymentFailure,
handleSubscriptionDeletion,
};

View File

@@ -0,0 +1,453 @@
const Stripe = require("stripe");
const { stripeAPIKey, stripeWebhooksKey } = require("../firebase/secrets.js");
const {
handlePaymentFailure,
handleSubscriptionDeletion,
} = require("./stripe.js");
const stripe = Stripe(stripeAPIKey);
// Secret for Stripe webhooks
const endpointSecret = stripeWebhooksKey;
class StripeController {
async createNewSubscription(
planType,
additionalAccounts,
isAnnual,
customerData,
token
) {
const tokenId = token.id;
let priceId;
let addId;
let items;
if (process.env.NODE_ENV === "development") {
if (planType === "associate" && isAnnual === false) {
// NEED TO MAKE DEV MODE PRODUCT IN STRIPE DASH
} else if (planType === "associate" && isAnnual === true) {
// NEED TO MAKE DEV MODE PRODUCT IN STRIPE DASH
} else if (planType === "partner" && isAnnual === false) {
priceId = "price_1PJPX6Bi8p7FeGFrBu7BQVkn";
} else if (planType === "partner" && isAnnual === true) {
priceId = "price_1PKqV9Bi8p7FeGFrNzATmnyf";
} else if (planType === "seniorPartner" && isAnnual === false) {
// NEED TO MAKE DEV MODE PRODUCT IN STRIPE DASH
} else if (planType === "seniorPartner" && isAnnual === true) {
// NEED TO MAKE DEV MODE PRODUCT IN STRIPE DASH
}
} else {
if (planType === "associate" && isAnnual === false) {
priceId = "price_1P7PdTBi8p7FeGFrmzmQ8zlX";
} else if (planType === "associate" && isAnnual === true) {
priceId = "price_1PJQ9FBi8p7FeGFrAINvdMHz";
} else if (planType === "partner" && isAnnual === false) {
priceId = "price_1P7PnpBi8p7FeGFrZOPRgDtL";
} else if (planType === "partner" && isAnnual === true) {
priceId = "price_1PKqWwBi8p7FeGFrqHBrAdPU";
} else if (planType === "seniorPartner" && isAnnual === false) {
priceId = "price_1P7PuoBi8p7FeGFrT3JlZMGp";
} else if (planType === "seniorPartner" && isAnnual === true) {
priceId = "price_1P7PvbBi8p7FeGFrce1HVyT4";
}
}
items = [{ price: priceId }];
// might need tyo change this to reflect development/[rpduction mode, as above]
if (planType === "partner" && isAnnual === false) {
if (additionalAccounts === 1) {
addId = "price_1OdIcqBi8p7FeGFrcKhFGudX";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdIvYBi8p7FeGFrLhvk1mwo";
items.push({ price: addId });
}
} else if (planType === "partner" && isAnnual === true) {
if (additionalAccounts === 1) {
addId = "price_1OdIunBi8p7FeGFrOJjULnA0";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdJ0pBi8p7FeGFrFrrXjfwA";
items.push({ price: addId });
}
}
items = [{ price: priceId }];
if (planType === "seniorPartner" && isAnnual === false) {
if (additionalAccounts === 1) {
addId = "price_1OdJ1XBi8p7FeGFrZVHDlSGH";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdJ3vBi8p7FeGFr47ZbQQN6";
items.push({ price: addId });
} else if (additionalAccounts === 3) {
addId = "price_1OdJ50Bi8p7FeGFrFB8wTpZu";
items.push({ price: addId });
} else if (additionalAccounts === 4) {
addId = "price_1OdJ6uBi8p7FeGFrdUhzYaGC";
items.push({ price: addId });
} else if (additionalAccounts === 5) {
addId = "price_1OdJ88Bi8p7FeGFrSwpR5r4Z";
items.push({ price: addId });
}
}
if (planType === "seniorPartner" && isAnnual === true) {
if (additionalAccounts === 1) {
addId = "price_1OdJ3EBi8p7FeGFr6371XcAi";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdJ4PBi8p7FeGFrgW7aKHwZ";
items.push({ price: addId });
} else if (additionalAccounts === 3) {
addId = "price_1OdJ6IBi8p7FeGFrItKkXCeM";
items.push({ price: addId });
} else if (additionalAccounts === 4) {
addId = "price_1OdJ7YBi8p7FeGFrCC6AulEY";
items.push({ price: addId });
} else if (additionalAccounts === 5) {
addId = "price_1OdJ8lBi8p7FeGFr6d8z3afK";
items.push({ price: addId });
}
}
try {
// create new customer object
const customer = await stripe.customers.create({
...customerData,
source: tokenId,
});
// Create the subscription
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: items,
expand: ["latest_invoice.payment_intent"],
});
const obj = { subscription, customer: { customerId: customer.id } };
return obj;
} catch (error) {
console.log("StripeController error in createNewSubscription", error);
}
}
async createNewPaymentIntent(customerData, token, userAgent) {
const tokenId = token.id;
try {
const customer = await stripe.customers.create({
...customerData,
source: tokenId,
});
const paymentIntent = await stripe.paymentIntents.create({
confirm: true,
customer: customer.id,
automatic_payment_methods: { enabled: true },
payment_method: token.card.id,
mandate_data: {
customer_acceptance: {
type: "online",
online: {
ip_address: token.client_ip,
user_agent: userAgent,
},
},
},
return_url: "https://www.novodraft.ai/dashboard",
currency: "usd",
amount: 59 * 100,
});
const obj = { paymentIntent, customer: { customerId: customer.id } };
return obj;
} catch (error) {
console.log("StripeController error in createNewPaymentIntent", error);
return error;
}
}
async cancelSubscription(appUserId) {
const usersRef = collection(db, "users");
const q = query(usersRef, where("appUserId", "==", appUserId));
const querySnapshot = await getDocs(q);
if (querySnapshot.empty) {
console.log("No user found with the email:", appUserId);
return;
}
const userDoc = querySnapshot.docs[0];
//get the user's subscription ID and customer ID
const subscriptionId = userDoc.data().subscriptionId;
const deletedSubscription = await stripe.subscriptions.update(
subscriptionId,
{
cancel_at_period_end: true,
}
);
return deletedSubscription;
}
async stripeWebhook(type, subscription) {
switch (type) {
case "customer.subscription.deleted":
const subscription = request.body.data.object;
//get stripe customer
const stripeCustomer = await stripe.customers.retrieve(
subscription.customer
);
await handleSubscriptionDeletion(stripeCustomer, subscription, stripe);
break;
case "invoice.payment_failed":
const paymentIntent = request.body.data.object;
await handlePaymentFailure(paymentIntent);
break;
default:
console.log(`Unhandled event type`);
}
//response.status(200).send();
}
}
module.exports = new StripeController();
/*
STRIPE TEST MODE PRICE CODES
items = [{ price: priceId }];
if (planType === "associate" && isAnnual === false) {
priceId = "price_1OdGLMBi8p7FeGFrr3JN9LB6";
} else if (planType === "associate" && isAnnual === true) {
priceId = "price_1OdGN3Bi8p7FeGFr9PM7oD93";
} else if (planType === "partner" && isAnnual === false) {
priceId = "price_1OdGO8Bi8p7FeGFrg7EdavjO";
} else if (planType === "partner" && isAnnual === true) {
priceId = "price_1OdGPHBi8p7FeGFrNd0hOVro";
} else if (planType === "seniorPartner" && isAnnual === false) {
priceId = "price_1OdGRLBi8p7FeGFrVAf7QCdw";
} else if (planType === "seniorPartner" && isAnnual === true) {
priceId = "price_1OdGRrBi8p7FeGFr2Zvr7USe";
}
items = [{ price: priceId }];
if (planType === "partner" && isAnnual === false) {
if (additionalAccounts === 1) {
addId = "price_1OdIcqBi8p7FeGFrcKhFGudX";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdIvYBi8p7FeGFrLhvk1mwo";
items.push({ price: addId });
}
} else if (planType === "partner" && isAnnual === true) {
if (additionalAccounts === 1) {
addId = "price_1OdIunBi8p7FeGFrOJjULnA0";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdJ0pBi8p7FeGFrFrrXjfwA";
items.push({ price: addId });
}
}
if (planType === "seniorPartner" && isAnnual === false) {
if (additionalAccounts === 1) {
addId = "price_1OdJ1XBi8p7FeGFrZVHDlSGH";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdJ3vBi8p7FeGFr47ZbQQN6";
items.push({ price: addId });
} else if (additionalAccounts === 3) {
addId = "price_1OdJ50Bi8p7FeGFrFB8wTpZu";
items.push({ price: addId });
} else if (additionalAccounts === 4) {
addId = "price_1OdJ6uBi8p7FeGFrdUhzYaGC";
items.push({ price: addId });
} else if (additionalAccounts === 5) {
addId = "price_1OdJ88Bi8p7FeGFrSwpR5r4Z";
items.push({ price: addId });
} else if (additionalAccounts === 6) {
addId = "price_1OdJ9CBi8p7FeGFrTQNy2YVd";
items.push({ price: addId });
} else if (additionalAccounts === 7) {
addId = "price_1OdJAIBi8p7FeGFrZyWHIlYf";
items.push({ price: addId });
} else if (additionalAccounts === 8) {
addId = "price_1OdJCzBi8p7FeGFriBy3OCso";
items.push({ price: addId });
} else if (additionalAccounts === 9) {
addId = "price_1OddLzBi8p7FeGFrzeVmj4fG";
items.push({ price: addId });
} else if (additionalAccounts === 10) {
addId = "price_1OddNUBi8p7FeGFraRX3ypOK";
items.push({ price: addId });
}
}
if (planType === "seniorPartner" && isAnnual === true) {
if (additionalAccounts === 1) {
addId = "price_1OdJ3EBi8p7FeGFr6371XcAi";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OdJ4PBi8p7FeGFrgW7aKHwZ";
items.push({ price: addId });
} else if (additionalAccounts === 3) {
addId = "price_1OdJ6IBi8p7FeGFrItKkXCeM";
items.push({ price: addId });
} else if (additionalAccounts === 4) {
addId = "price_1OdJ7YBi8p7FeGFrCC6AulEY";
items.push({ price: addId });
} else if (additionalAccounts === 5) {
addId = "price_1OdJ8lBi8p7FeGFr6d8z3afK";
items.push({ price: addId });
} else if (additionalAccounts === 6) {
addId = "price_1OdJ9kBi8p7FeGFrxXTG7s20";
items.push({ price: addId });
} else if (additionalAccounts === 7) {
addId = "price_1OdJBJBi8p7FeGFrc0F6ByO5";
items.push({ price: addId });
} else if (additionalAccounts === 8) {
addId = "price_1OdJDbBi8p7FeGFrbpE4URLd";
items.push({ price: addId });
} else if (additionalAccounts === 9) {
addId = "price_1OddMxBi8p7FeGFraD12KrD4";
items.push({ price: addId });
} else if (additionalAccounts === 10) {
addId = "price_1OddOEBi8p7FeGFrKcFey7PM";
items.push({ price: addId });
}
}
*/
/*
STRIPE PROD PRICE CODES
if (planType === "associate" && isAnnual === false) {
priceId = "price_1OgasxBi8p7FeGFrjrF7VNAk";
} else if (planType === "associate" && isAnnual === true) {
priceId = "price_1OgatkBi8p7FeGFrfwzALYhR";
} else if (planType === "partner" && isAnnual === false) {
priceId = "price_1Ogb1uBi8p7FeGFrk9DFQOo0";
} else if (planType === "partner" && isAnnual === true) {
priceId = "price_1Ogb20Bi8p7FeGFrJDCwuefJ";
} else if (planType === "seniorPartner" && isAnnual === false) {
priceId = "price_1Ogb2VBi8p7FeGFrFjIyL8eW";
} else if (planType === "seniorPartner" && isAnnual === true) {
priceId = "price_1Ogb2gBi8p7FeGFrlTQ6xnoj";
}
if (planType === "partner" && isAnnual === false) {
if (additionalAccounts === 1) {
addId = "price_1Ogb5SBi8p7FeGFrXh5oQ1xL";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1Ogb5dBi8p7FeGFr0Qb7NMIs";
items.push({ price: addId });
}
} else if (planType === "partner" && isAnnual === true) {
if (additionalAccounts === 1) {
addId = "price_1Ogb5XBi8p7FeGFrYp3OqBgN";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1Ogb5iBi8p7FeGFrZJga58z2";
items.push({ price: addId });
}
}
if (planType === "seniorPartner" && isAnnual === false) {
if (additionalAccounts === 1) {
addId = "price_1OgbBRBi8p7FeGFrhNNCiKSB";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OgbBbBi8p7FeGFrDkiHBqjJ";
items.push({ price: addId });
} else if (additionalAccounts === 3) {
addId = "price_1OgbBrBi8p7FeGFr3iaomKIM";
items.push({ price: addId });
} else if (additionalAccounts === 4) {
addId = "price_1OgbC2Bi8p7FeGFrS5mVMoco";
items.push({ price: addId });
} else if (additionalAccounts === 5) {
addId = "price_1OgbCCBi8p7FeGFrsCDdUtv0";
items.push({ price: addId });
} else if (additionalAccounts === 6) {
addId = "price_1OgbCOBi8p7FeGFrYXgF9caV";
items.push({ price: addId });
} else if (additionalAccounts === 7) {
addId = "price_1OgbCaBi8p7FeGFrHs3urIBo";
items.push({ price: addId });
} else if (additionalAccounts === 8) {
addId = "price_1OgbCkBi8p7FeGFrP150586E";
items.push({ price: addId });
} else if (additionalAccounts === 9) {
addId = "price_1OgbCvBi8p7FeGFrhn7Fc6yz";
items.push({ price: addId });
} else if (additionalAccounts === 10) {
addId = "price_1OgbDEBi8p7FeGFrfVkhYgsC";
items.push({ price: addId });
}
}
if (planType === "seniorPartner" && isAnnual === true) {
if (additionalAccounts === 1) {
addId = "price_1OgbBWBi8p7FeGFrBHRfsvSl";
items.push({ price: addId });
} else if (additionalAccounts === 2) {
addId = "price_1OgbBjBi8p7FeGFr2H3WrJHL";
items.push({ price: addId });
} else if (additionalAccounts === 3) {
addId = "price_1OgbBxBi8p7FeGFrZ4P4HXYj";
items.push({ price: addId });
} else if (additionalAccounts === 4) {
addId = "price_1OgbC8Bi8p7FeGFrdSZJ6vHu";
items.push({ price: addId });
} else if (additionalAccounts === 5) {
addId = "price_1OgbCHBi8p7FeGFrDWU3480v";
items.push({ price: addId });
} else if (additionalAccounts === 6) {
addId = "pprice_1OgbCVBi8p7FeGFrj4XYUjvT";
items.push({ price: addId });
} else if (additionalAccounts === 7) {
addId = "price_1OgbCfBi8p7FeGFrDUHZb3fq";
items.push({ price: addId });
} else if (additionalAccounts === 8) {
addId = "price_1OgbCqBi8p7FeGFrcBpwHOei";
items.push({ price: addId });
} else if (additionalAccounts === 9) {
addId = "price_1OgbD0Bi8p7FeGFrSzd969h7";
items.push({ price: addId });
} else if (additionalAccounts === 10) {
addId = "price_1OgbD9Bi8p7FeGFrrxZ4Y6Cl";
items.push({ price: addId });
}
}
*/
/*
if (planType === "associate" && isAnnual === false) {
priceId = "price_1OgasxBi8p7FeGFrjrF7VNAk";
} else if (planType === "associate" && isAnnual === true) {
priceId = "price_1OgatkBi8p7FeGFrfwzALYhR";
} else if (planType === "partner" && isAnnual === false) {
priceId = "price_1Ogb1uBi8p7FeGFrk9DFQOo0";
} else if (planType === "partner" && isAnnual === true) {
priceId = "price_1Ogb20Bi8p7FeGFrJDCwuefJ";
} else if (planType === "seniorPartner" && isAnnual === false) {
priceId = "price_1Ogb2VBi8p7FeGFrFjIyL8eW";
} else if (planType === "seniorPartner" && isAnnual === true) {
priceId = "price_1Ogb2gBi8p7FeGFrlTQ6xnoj";
}
*/

View File

@@ -0,0 +1,156 @@
const fs = require("fs");
function selectRequestFilePath(docId, reqType) {
let filePath;
const basePath = process.cwd();
if (reqType == "combined-numbered") {
filePath = `${basePath}/Documents/Requests/Parsedcombined/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "interrogatories") {
filePath = `${basePath}/Documents/Requests/Parsedrogs/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "admissions") {
filePath = `${basePath}/Documents/Requests/Parsedadmit/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "production") {
filePath = `${basePath}/Documents/Requests/Parsedprod/${docId}/${docId}-jbk-parsedRequests.json`;
}
return filePath;
}
function selectRequestFolderPath(docId, reqType) {
let folderPath;
const basePath = process.cwd();
if (reqType == "combined-numbered") {
folderPath = `${basePath}/Documents/Requests/Parsedcombined/${docId}/`;
} else if (reqType == "interrogatories") {
folderPath = `${basePath}/Documents/Requests/Parsedrogs/${docId}/`;
} else if (reqType == "admissions") {
folderPath = `${basePath}/Documents/Requests/Parsedadmit/${docId}/`;
} else if (reqType == "production") {
folderPath = `${basePath}/Documents/Requests/Parsedprod/${docId}/`;
}
return folderPath;
}
function selectResponseFilePath(docId, reqType) {
let filePath;
const basePath = process.cwd();
if (reqType == "combined-numbered") {
filePath = `${basePath}/Documents/Responses/Combinedresp/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "interrogatories") {
filePath = `${basePath}/Documents/Requests/Parsedrogs/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "admissions") {
filePath = `${basePath}/Documents/Requests/Parsedadmit/${docId}/${docId}-jbk-parsedRequests.json`;
} else if (reqType == "production") {
filePath = `${basePath}/Documents/Requests/Parsedprod/${docId}/${docId}-jbk-parsedRequests.json`;
}
return filePath;
}
function selectResponseFolderPath(docId, reqType) {
let folderPath;
const basePath = process.cwd();
if (reqType == "combined-numbered") {
folderPath = `${basePath}/Documents/Responses/Combinedresp/${docId}/`;
} else if (reqType == "interrogatories") {
folderPath = `${basePath}/Documents/Responses/Rogresp/${docId}/`;
} else if (reqType == "admissions") {
folderPath = `${basePath}/Documents/Responses/Admitresp/${docId}/`;
} else if (reqType == "production") {
folderPath = `${basePath}/Documents/Responses/Prodresp/${docId}/`;
}
return folderPath;
}
async function deleteDocument(docId, reqType, respGens) {
const requestFilePath = selectRequestFilePath(docId, reqType);
fs.stat(requestFilePath, function (err, stats) {
if (err) {
return err;
} else {
fs.unlink(filePath, (err) => {
if (err) {
return err;
}
});
}
});
}
async function deleteFolderAndContents(docId, reqType, respGens = 0) {
const requestFolderPath = selectRequestFolderPath(docId, reqType);
const gens = parseInt(respGens);
function removeFolder() {
const requestFolderPath = selectRequestFolderPath(docId, reqType);
if (requestFolderPath) {
try {
fs.rm(requestFolderPath, { recursive: true, force: true }, (err) => {
if (err) {
console.log(err);
return err;
}
});
if (gens > 0) {
const responseFolderPath = selectResponseFolderPath(docId, reqType);
fs.rm(responseFolderPath, { recursive: true, force: true }, (err) => {
if (err) {
console.log(err);
return err;
}
});
}
} catch (err) {
console.log(err);
}
}
}
}
async function cleanupGenFolderAndContents(docId, reqType) {
const requestFolderPath = `/var/www/ax3Services/docGenService/Docxinfo/${docId}.json`;
fs.rm(requestFolderPath, { recursive: true, force: true }, (err) => {
if (err) {
console.log(err);
return err;
}
});
}
module.exports = {
deleteDocument,
deleteFolderAndContents,
cleanupGenFolderAndContents,
};
/*
fs.access(
requestFolderPath,
fs.constants.R_OK | fs.constants.W_OK,
removeFolder,
gens
),
(err) => {
if (err) {
console.log("Error in deleteFolderAndContents fs.access:", err);
return err;
} else {
const requestFolderPath = selectRequestFolderPath(docId, reqType);
fs.rm(requestFolderPath, { recursive: true, force: true }, (err) => {
if (err) {
console.log(err);
return err;
}
});
if (gens > 0) {
const responseFolderPath = selectResponseFolderPath(docId, reqType);
fs.rm(responseFolderPath, { recursive: true, force: true }, (err) => {
if (err) {
console.log(err);
return err;
}
});
}
}
};
*/

View File

@@ -0,0 +1,123 @@
const fs = require("fs");
const path = require("path");
async function makeDir(path) {
console.log("makeDir path", path);
fs.mkdir(path, function (err) {
if (err) {
console.log("makeDir error" + err);
}
});
}
function storeDataForGenServices(docId, data) {
const foo = JSON.stringify(data);
console.log("o~~~~~~~~~~~~~~~~~~~~~~~~~~~---v foo", foo);
const saveDirectory = path.join(__dirname, "..", "docGenService", "Docxinfo");
const filename = `${docId}.json`;
const savePath = `${saveDirectory}/${filename}`;
fs.writeFile(savePath, foo, function (err) {
if (err) {
return console.log("Error writing in responseHeaderGenerator", err);
}
});
}
function storeEditedCompletions(editedComps) {
const editedCompletes = JSON.stringify(editedComps);
console.log(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~storeEditedCompletion"
);
let docId = editedComps.id;
const dir = ` ./docGenService/Docxinfo/${docId}/`;
const saveDirectory = path.join(__dirname, "..", "docGenService", "Docxinfo");
try {
if (fs.existsSync(`./docGenService/Docxinfo/${docId}/`)) {
let bim;
const fileData = fs.readdirSync(`EditedCompletions/${docId}/`, "utf8");
if (fileData.length > 1) {
let foo = fileData.sort();
let bar = foo[foo.length - 2];
const nameArray = bar.split("-");
const baz = bar.split("-")[5];
const int = Number(baz) + 1;
nameArray.splice(5, 6, `${int}`);
const delimiter = "-";
const frak = nameArray.reduce((acc, val) =>
[].concat(acc, delimiter, val)
);
const finished = frak.join("");
var options = { flag: "w" };
fs.writeFileSync(
dir + `${finished}-jbk-editedResponses.json`,
editedCompletes,
options,
function (err) {
if (err) {
return console.log("Error writing in storeEditedCompletion", err);
}
}
);
return;
} else {
console.log("filedata length of one fired, fileData", fileData);
let bar = fileData[0];
console.log("bar", bar);
const zeroArray = bar.split("-");
console.log("zeroArray", zeroArray);
bim = `1`;
zeroArray.splice(5, 0, bim);
const delimiter = "-";
const frak = zeroArray.reduce((acc, val) =>
[].concat(acc, delimiter, val)
);
const finished = frak.join("");
console.log("finished", finished);
var options = { flag: "w" };
fs.writeFileSync(
dir + `${finished}`,
editedCompletes,
options,
function (err) {
if (err) {
return console.log("Error writing in storeEditedCompletion", err);
}
}
);
return;
}
} else {
console.log(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~else block saveDirectory",
saveDirectory
);
fs.mkdir(saveDirectory, function (err) {
if (err) {
console.log("makeDir error" + err);
}
});
}
var options = { flag: "w" };
console.log(
"------------------------------------------------------------------->write file directory: ",
`${saveDirectory}/${docId}.json`
);
fs.writeFileSync(
`${saveDirectory}/${docId}.json`,
editedCompletes,
options,
function (err) {
if (err) {
return console.log("Error writing in storeEditedCompletion", err);
}
}
);
} catch (err) {
console.log("Error in store EditedCompletion. Error writing file:", err);
}
}
module.exports = {
storeEditedCompletions,
storeDataForGenServices,
};

View File

@@ -0,0 +1,273 @@
const fs = require("fs");
const { v4: uuidv4 } = require("uuid");
//Main Type IDs
const antiTrustId = "4ec2ef5b-8f0f-4e8a-ad03-5d5cd14effb2";
const classActionId = "142a83b4-354e-4b64-b512-dc3cc6434c30";
const contractId = "cca3094f-a191-4fbb-bbcd-46bfea3ce594";
const defemationId = "c94b2e40-9b26-4c36-b09a-84234be7e4f8";
const employmentId = "8eba99c8-fc01-41e6-bad4-667957b8477f";
const familyLawId = "8e591ed5-ca8e-4569-b1a8-c664dcd678c8";
const landlordTenantId = "9e21a41f-3878-4300-8618-a964aeff0d84";
const legalMalpracticeId = "99501ae9-7045-4843-b2e9-926bf866abd9";
const medicalMalpracticeId = "a282768e-ae02-4baf-b0bb-5cb321ff8834";
const personalInjuryId = "77e0a0bc-2062-432b-9b58-578bbe24dc32";
const productLiabilityId = "99c5e042-e67a-44e9-ab7b-47d152378bd3";
const propertyId = "731d719d-53a1-4995-b210-48cb3d1aaeb3";
const securitiesId = "f5abebeb-b82f-4ce7-a1bd-a993a6563f5e";
const tortId = "e88b3028-8e9e-480e-9bbe-b875d8d8be6a";
const workersCompensationId = "f1b20367-fe5e-40e2-8405-3ad607cf6b25";
const mainTypeArray = [
{ name: "antitrust", id: antiTrustId },
{ name: "class action", id: classActionId },
{ name: "contract", id: contractId },
{ name: "defemation", id: defemationId },
{ name: "employment", id: employmentId },
{ name: "family law", id: familyLawId },
{ name: "landlord tenant", id: landlordTenantId },
{ name: "legal malpractice", id: legalMalpracticeId },
{ name: "medical malpractice", id: medicalMalpracticeId },
{ name: "personal injury", id: personalInjuryId },
{ name: "product liability", id: productLiabilityId },
{ name: "property", id: propertyId },
{ name: "securities", id: securitiesId },
{ name: "tort", id: tortId },
{ name: "workers' compensation", id: workersCompensationId },
];
const tagStrings = [
"antitrust",
"antitrust - bid rigging",
"antitrust - price fixing",
"antitrust - tying arrang",
"antitrust - exclusionary conduct",
"antitrust - mergers",
"antitrust - monopoly",
"antitrust - monopoly leverage",
"antitrust - market allocation",
"antitrust - group boycott",
"antitrust - unfair compet",
"antitrust - price discrim",
"antitrust - customer alloc",
"class action",
"class action - defect product",
"class action - consumer",
"class action - consumer fraud",
"class action - environment",
"class action - employment",
"class action - dangerous drugs",
"class action - roundup",
"class action - civil rights",
"class action - decept bus prac",
"class action - securities fraud",
"contract",
"contract - actual breach ",
"contract - anticipatory breach",
"contract - duress",
"contract - real estate",
"contract - equitable claims",
"comtract - material breach",
"contract - implied contract",
"contract - mistake",
"contract - rescission",
"contract - specific performance",
"contract - fraud",
"contract - ucc",
"contract - unconscionability",
"contract - unit price",
"defemation",
"employment",
"employment - fail grant reas accommd",
"employment - ableism",
"employment - age discrimination",
"employment - fam/med leave act",
"employment - gender discrimination",
"employment - harassment",
"employment - payment mistake",
"employment - racial discrimination",
"employment - religious discrimination",
"employment - retaliation",
"employment - unpaid wages",
"employment - sexual orient discrim",
"employment - wage/hour violation",
"employment - wrongfule termination",
"family law",
"family law - alimony",
"family law - child support",
"family law - general",
"family law - divorce",
"family law - custoday",
"family law - paternity",
"family law - property division",
"family law - termin parental rights",
"family law - juvenile matter",
"family law - legal separation",
"family law - marriage dissolution",
"family law - spousal support",
"landlord tenant",
"landlord tenant - breach quiet enjoy",
"landlord tenant - fail pay rent",
"landlord tenant - holdover",
"landlord tenant - breach of lease",
"landlord tenant - damages after term lease",
"landlord tenant - rent escrow",
"landlord tenant - retaliatory eviction",
"landlord tenant - security deposit",
"landlord tenant" - "wrongful detainer",
"legal malpractice",
"legal malpractice - conflict of interest",
"legal malpractice - missed deadlines",
"legal malpractice - inadequate discovery",
"legal malpractice - failure to comm",
"legal malpractice - fail to file docs",
"legal malpractice - statute of limits",
"legal malpractice - negligence",
"legal malpractice - fraud",
"legal malpractice - lack of consent",
"legal malpractice - confidentiality",
"legal malpractice - mishandling funds",
"legal malpractice - incorrect claim/def",
"legal malpractice - ethical violat",
"legal malpractice - excessive fees",
"legal malpractice - fail introd evid",
"legal malpractice - planning error",
"medical malpractice",
"medical malpractice - anesthesia",
"medical malpractice - birth injury",
"medical malpractice - failure to treat",
"medical malpractice - surg instrument",
"medical malpractice - fail to diagnose",
"medical malpractice - inadequate",
"medical malpractice - bedsores",
"medical malpractice - misdiagnosis",
"medical malpractice - hospital",
"medical malpractice - early discharge",
"medical malpractice - unneeded surgery",
"medical malpractice - impproper treatment",
"medical malpractice - incorrect procedure",
"medical malpractice - amputation error",
"personal injury",
"personal injury - tort",
"personal injury - premises liability",
"personal injury - auto accident",
"personal injury - truck accident",
"personal injury - construction",
"personal injury - wrongful death",
"personal injury - boating",
"personal injury - public transportation",
"personal injury - catastrophic injury",
"personal injury - aviation",
"personal injury - negligence",
"personal injury - dog bite",
"personal injury - product liab",
"personal injury - brain injury",
"personal injury - fall - trip",
"personal injury - fall - other",
"personal injury - fall - slip",
"personal injury - nursing home",
"personal injury - burn injury",
"personal injury - rideshare",
"personal injury - lost wages",
"personal injury - loss consortium",
"product liability",
"product liability - design defec",
"product liability - manufac def",
"product liability - defect marketing",
"product liability - strict liab",
"product liability - fail to warn",
"product liability - breach warranty",
"product liability - negligence",
"product liability - dangerous drug",
"product liability - medical device",
"product liability - misrepresentation",
"product liability - hidden defect",
"product liability - household product",
"property",
"property - boundary dispute",
"property - zoning",
"property - breach contract",
"property - adverse possession",
"property - partition",
"property - title",
"property - chattels",
"securities",
"securities - breach fiduciary duty",
"securities - churning",
"securities - conflict of interest",
"securities - fail to diversify",
"securities - fail to supervise",
"securities - fraudulent misrep",
"securities - malpractice",
"securities - margin call",
"securities - market manipulation",
"securities - negligence",
"securities - risk management",
"securities - switching",
"securities - outside activity",
"securities - unauthorized trading",
"securities - unsuitability",
"tort",
"tort - assault",
"tort - battery",
"tort - conversion",
"tort - animal",
"tort - false imprisonment",
"tort - intentional",
"tort - intent inflict emot dist",
"tort - invasion of privacy",
"tort - negligence",
"tort - damage to chattels (intentional)",
"tort - trespass",
"workers' compensation",
"workers' compensation - repetitive trauma",
"workers' compensation - stress related inj",
"workers' compensation - occupational disease",
"workers' compensation - medical care benefits",
"workers' compensation - partial disability",
"workers' compensation - total disability",
"workers' compensation - death benifits",
"workers' compensation - vocational rehab ben",
"workers' compensation - traumatic",
"workers' compensation - recurrence",
"workers' compensation - consequential",
"workers' compensation - intervening",
];
let caseTagArray = [];
tagStrings.forEach((string) => {
const tagId = uuidv4();
const subId = uuidv4();
const tagName = string;
let subType;
if (typeof string === "string") {
const temp = string.split("-");
const mainType = temp[0].trim();
let mainTypeId;
const temprz = mainTypeArray.filter((type) => {
if (mainType == type.name) {
mainTypeId = type.id;
}
});
const subTemp = temp[1];
if (typeof subTemp === "string") {
subType = subTemp.trim();
}
let obj = {};
obj["tagId"] = tagId;
obj["tagName"] = tagName;
obj["mainType"] = { name: mainType, id: mainTypeId };
if (subType) {
obj["subType"] = { name: subType, subTypeId: subId };
}
caseTagArray.push(obj);
}
});
console.log(caseTagArray);
const data = JSON.stringify(caseTagArray);
fs.writeFile(`caseTags.json`, data, function (err) {
if (err) {
return console.log("Error writing caseTagArray", err);
}
});

Binary file not shown.

View File

@@ -0,0 +1,110 @@
const path = require("path");
const fs = require("fs");
const tesseReader = require("./tesseReader.js");
const { getDoc } = require("../firebase/firebase.js");
class TesseController {
async makeDir(folder) {
const fdirup = path.join(
__dirname,
"..",
"Documents",
"Textfiles",
`${folder}`
);
fs.mkdir(fdirup, function (err) {
if (err) {
console.log("Error Creating Directory: " + err);
}
});
}
async createObj(file) {
console.log("fdirup", fdirup);
// console.log("---------------------------------------fileNames", fileNames);
}
async executeReadWriteActions(
id,
isComplaint = false,
clientPosition = "Plaintiff",
novosValue = 2
) {
const fdirup = path.join(
__dirname,
"..",
"Documents",
"Converted",
`${id}`
);
const countObject = {};
countObject.fileName = id;
let fileNames = fs.readdirSync(fdirup);
countObject.files = fileNames;
countObject.path = fdirup;
countObject.numberOfFiles = fileNames.length;
countObject.clientPosition = clientPosition;
countObject.novosValue = novosValue;
this.makeDir(id);
function callConvert(
file,
path,
id,
countObject,
isComplaint,
clientPosition,
index
) {
tesseReader
.convert(file, countObject, isComplaint, clientPosition)
.then((text) => {
tesseReader.writeFile(
file,
text,
id,
countObject,
isComplaint,
clientPosition
);
});
}
countObject.files.forEach(async (file, index) => {
setTimeout(
callConvert,
index * 10,
file,
countObject.path,
id,
countObject,
isComplaint,
clientPosition
);
});
return JSON.stringify({ status: "OK" });
}
}
const tesseCont = new TesseController();
module.exports = new TesseController();
/*
const id = "5f9d7844-584d-46d5-bd0a-e1ac6ff0c06d";
const isComplaint = true;
tesseCont.executeReadWriteActions(id, isComplaint);
function sleep(ms) {
console.log("sleep called");
return new Promise((resolve) => setTimeout(resolve, ms));
}
*/

View File

@@ -0,0 +1,209 @@
const { createWorker } = require("tesseract.js");
const docParser = require("../docParserService/docParser.js");
const fs = require("fs");
const path = require("path");
const { v4: uuidv4 } = require("uuid");
const modelController = require("../agent/ModelController.js");
let countWrites = 0;
async function writeFile(
file,
text,
folder,
countObject,
isComplaint,
clientPosition
) {
const totalFiles = countObject.numberOfFiles;
const fdirup = path.join(__dirname, "..", "Documents", "Textfiles");
try {
fs.writeFile(
`${fdirup}/${folder}/${file.split(".")[0]}.txt`,
text,
function (err) {
if (err) {
console.log("err in tesseReader writeFile", err);
}
}
);
} catch (err) {
console.log("Error writing file:", err);
}
countWrites++;
console.log("_----------------------countWrites", countWrites);
console.log("_----------------------totalFiles", totalFiles);
if (countWrites == totalFiles) {
if (isComplaint == false) {
console.log(
"------------------------------------->isComplaint === false ELSE STATEMENT"
);
countWrites = 0;
const type = await docParser.readDir(
`../Documents/Textfiles/${folder}/`,
`${folder}`,
countObject
);
return type;
} else if (isComplaint == true) {
console.log(
"------------------------------------->isComplaint === true ELSE statement"
);
countObject.filePath = `../Documents/Textfiles/${folder}/`;
await modelController.createArrayOfInterrogatories(
folder,
clientPosition
);
return countObject;
}
}
}
async function writeSingle(folder, text) {
const fileName = uuidv4();
try {
fs.writeFile(
`../Documents/Textfiles/${folder}/${fileName}.txt`,
text,
function (err) {
if (err) {
console.log("error in writeSingle, ", err);
}
}
);
} catch (err) {
console.log("Error writing file:", err);
}
}
async function convert(file, countObject, isComplaint, clientPosition) {
//console.log("file in convert (id)", file);
const path = countObject?.path;
const worker = await createWorker();
const concatPath = `${path}/${file}`;
await worker.loadLanguage("eng");
await worker.initialize("eng");
await worker.setParameters({
tessedit_pageseg_mode: "4",
});
const {
data: { text },
} = await worker.recognize(concatPath);
//writeFile(file, text, folder, countObject, isComplaint, clientPosition);
await worker.terminate();
return text;
}
async function convertBurst(fullFilePath) {
const worker = await createWorker();
await worker.loadLanguage("eng");
await worker.initialize("eng");
await worker.setParameters({
tessedit_pageseg_mode: "4",
});
const {
data: { text },
} = await worker.recognize(fullFilePath);
await worker.terminate();
return text;
}
async function makeDir(folder) {
const fdirup = path.join(
__dirname,
"..",
"Documents",
"Textfiles",
`${folder}`
);
fs.mkdir(fdirup, function (err) {
if (err) {
console.log("Error Creating Directory: " + err);
}
});
}
async function readMultipleFiles(
path,
folder,
countObject,
isComplaint,
clientPosition
) {
makeDir(folder);
fs.readdirSync(path).forEach((file, index) => {
setTimeout(function () {
convert(file, path, folder, countObject, isComplaint, clientPosition);
}, index * 10);
});
}
async function getMultipleFiles(path, folder, countObject, isComplaint) {
const fileArr = fs.readdirSync(path);
//But do you really need readDirSnc at all? YES> Because uuids are generate/files are named in python module
return fileArr;
/*
1. Move below call to iterate with forEach => convert to controller,
2. Then reutrn a vaL, and call write files from controller\
3. Then call model controller from controller
.forEach((file, index) => {
setTimeout(function () {
convert(file, path, folder, countObject, isComplaint);
}, index * 10);
});
*/
}
async function readMultipleFilesLarge(path, folder, countObject, filenames) {
makeDir(folder);
const total = filenames.length;
const a = filenames.map((name) => {
return `${path}/${name}`;
});
const arrSize = 20;
let arrays = [];
while (a.length > 0) {
arrays.push(a.splice(0, arrSize));
}
let count = 0;
arrays.forEach((array, i) => {
setTimeout(function () {
array.forEach(async (fullFilePath) => {
const text = await convertBurst(fullFilePath);
writeSingle(folder, text);
count++;
if (count === total) {
determinedDocType = "combined-numbered";
const isRequests = true;
modelController.createArrayOfQuestionsLarge(
folder,
determinedDocType,
isRequests
);
}
});
}, i * 3000);
});
}
module.exports = {
writeFile,
convert,
readMultipleFiles,
readMultipleFilesLarge,
makeDir,
};

View File

@@ -0,0 +1,33 @@
const fs = require("fs");
const tesseReader = require("./tesseReader.js");
var sleep = require("system-sleep");
const directory = "../Documents/Converted/";
function countFiles(directory, file) {
let fileCount = {};
fileCount.fileName = file;
fs.readdir(directory, (err, files) => {
fileCount.numberOfFiles = files.length;
});
return fileCount;
}
async function watchOnce() {
const watcher = fs.watch(directory, (event, file) => {
watcher.close();
sleep(15000);
const fileCount = countFiles(`../Documents/Converted/${file}`, file);
//sleep(1000);
tesseReader.readMultipleFiles(
`../Documents/Converted/${file}`,
`${file}`,
fileCount
);
// Relaunch watcher after 1 sec ***
sleep(1000);
watchOnce();
});
}
watchOnce();