Skip to content

Commit

Permalink
opex: 2 more CBJ reports
Browse files Browse the repository at this point in the history
  • Loading branch information
jimlerza committed Jan 10, 2025
1 parent fa6858f commit 0ec140d
Show file tree
Hide file tree
Showing 4 changed files with 311 additions and 0 deletions.
113 changes: 113 additions & 0 deletions scripts/reports/attorneys-admitted-in-year.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env -S npx ts-node --transpile-only

import { type RawPractitioner } from '@shared/business/entities/Practitioner';
import {
type ScriptConfig,
parseArgsAndEnvVars,
} from '../helpers/parseArgsAndEnvVars';
import {
type ServerApplicationContext,
createApplicationContext,
} from '@web-api/applicationContext';
import { generateCsv } from '../helpers/generate-csv';
import { pick } from 'lodash';
import { searchAll } from '@web-api/persistence/elasticsearch/searchClient';

const scriptConfig: ScriptConfig = {
description:
'attorneys-admitted-in-year - Generates a CSV of attorneys admitted in the given year.',
environment: {
elasticsearchEndpoint: 'ELASTICSEARCH_ENDPOINT',
env: 'ENV',
},
parameters: {
fiscal: {
short: 'f',
type: 'boolean',
},
year: {
position: 0,
required: true,
transform: 'number',
type: 'string',
},
},
requireActiveAwsSession: true,
};

const OUTPUT_DIR = `${process.env.HOME}/Documents`;

const getAttorneysAdmittedInYear = async ({
applicationContext,
fiscal,
year,
}: {
applicationContext: ServerApplicationContext;
fiscal: boolean;
year: number;
}): Promise<RawPractitioner[]> => {
const { results } = await searchAll({
applicationContext,
searchParameters: {
body: {
query: {
bool: {
must: [
{
term: {
'practitionerType.S': 'Attorney',
},
},
{
range: {
'admissionsDate.S': {
gte: fiscal
? `${year - 1}-10-01T05:00:00Z`
: `${year}-01-01T04:00:00Z`,
lt: fiscal
? `${year}-10-01T05:00:00Z`
: `${year + 1}-01-01T04:00:00Z`,
},
},
},
],
},
},
sort: [{ 'admissionsDate.S': 'asc' }],
},
index: 'efcms-user',
},
});
return results;
};

// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
const applicationContext = createApplicationContext({});
const { fiscal, year } = parseArgsAndEnvVars(scriptConfig) as {
fiscal: boolean;
year: number;
};
const attorneys: RawPractitioner[] = await getAttorneysAdmittedInYear({
applicationContext,
fiscal,
year,
});
console.log(
`Found ${attorneys.length} attorneys admitted in ${fiscal ? 'fiscal' : 'calendar'} year ${year}.`,
);
const columns = [
{ header: 'Bar Number', key: 'barNumber' },
{ header: 'Name', key: 'name' },
{ header: 'Practice Type', key: 'practiceType' },
{ header: 'Firm', key: 'firmName' },
{ header: 'Admissions Date', key: 'admissionsDate' },
];
const rows = attorneys.map(attorney => ({
...pick(attorney, ['barNumber', 'firmName', 'name', 'practiceType']),
admissionsDate: attorney.admissionsDate.split('T')[0],
}));
const filename = `${OUTPUT_DIR}/attorneys-admitted-in${fiscal ? '-fiscal-year' : ''}-${year}.csv`;
generateCsv({ columns, filename, rows });
console.log(`Generated ${filename}`);
})();
192 changes: 192 additions & 0 deletions scripts/reports/documents-filed-by-nonattorneys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#!/usr/bin/env -S npx ts-node --transpile-only

import {
type ScriptConfig,
parseArgsAndEnvVars,
} from '../helpers/parseArgsAndEnvVars';
import {
type ServerApplicationContext,
createApplicationContext,
} from '@web-api/applicationContext';
import { generateCsv } from '../helpers/generate-csv';
import { pick } from 'lodash';
import { searchAll } from '@web-api/persistence/elasticsearch/searchClient';

const scriptConfig: ScriptConfig = {
description:
'documents-filed-by-non-attorneys - Generates a CSV of documents filed by non-attorneys.',
environment: {
elasticsearchEndpoint: 'ELASTICSEARCH_ENDPOINT',
env: 'ENV',
},
parameters: {
eventCode: {
default: 'P',
long: 'event-code',
required: false,
short: 'e',
type: 'string',
},
fiscal: {
default: false,
short: 'f',
type: 'boolean',
},
year: {
default: '2024',
required: false,
short: 'y',
transform: 'number',
type: 'string',
},
},
requireActiveAwsSession: true,
};

const OUTPUT_DIR = `${process.env.HOME}/Documents`;

const getNonAttorneys = async ({
applicationContext,
}: {
applicationContext: ServerApplicationContext;
}): Promise<{ [k: string]: string }> => {
const nonAttorneys = {};
const { results } = await searchAll({
applicationContext,
searchParameters: {
body: {
query: {
bool: {
must: [
{
term: {
'admissionsStatus.S': 'Active',
},
},
{
term: {
'practitionerType.S': 'Non-Attorney',
},
},
],
},
},
},
index: 'efcms-user',
},
});
for (const result of results) {
nonAttorneys[result.pk.replace('user|', '')] = result.name;
}
return nonAttorneys;
};

const getDocuments = async ({
applicationContext,
eventCode,
fiscal,
userIds,
year,
}: {
applicationContext: ServerApplicationContext;
eventCode: string;
fiscal: boolean;
userIds: string[];
year: number;
}): Promise<RawDocketEntry[]> => {
const { results } = await searchAll({
applicationContext,
searchParameters: {
body: {
query: {
bool: {
must: [
{
term: {
'entityName.S': 'DocketEntry',
},
},
{
term: {
'eventCode.S': eventCode,
},
},
{
terms: {
'userId.S': userIds,
},
},
{
range: {
'receivedAt.S': {
gte: fiscal
? `${year - 1}-10-01T05:00:00Z`
: `${year}-01-01T04:00:00Z`,
lt: fiscal
? `${year}-10-01T05:00:00Z`
: `${year + 1}-01-01T04:00:00Z`,
},
},
},
],
},
},
sort: [{ 'receivedAt.S': 'asc' }],
},
index: 'efcms-docket-entry',
},
});
return results;
};

// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
const applicationContext = createApplicationContext({});
const { eventCode, fiscal, year } = parseArgsAndEnvVars(scriptConfig) as {
eventCode: string;
fiscal: boolean;
year: number;
};
console.log(
`Looking for documents with event code ${eventCode} filed by non-attorneys ` +
`in ${fiscal ? 'fiscal' : 'calendar'} year ${year}...`,
);
const nonAttorneys = await getNonAttorneys({ applicationContext });
console.log(
`Found ${Object.keys(nonAttorneys).length} non-attorneys with active admissions status.`,
);
const documents = await getDocuments({
applicationContext,
eventCode,
fiscal,
userIds: Object.keys(nonAttorneys),
year,
});
if (!documents.length) {
console.log(
`Found 0 documents with event code ${eventCode} filed by non-attorneys ` +
`in ${fiscal ? 'fiscal' : 'calendar'} year ${year}.`,
);
return;
}
console.log(
`Found ${documents.length} ${documents[0].documentType}` +
`${documents.length === 1 ? '' : 's'} filed by non-attorneys ` +
`in ${fiscal ? 'fiscal' : 'calendar'} year ${year}.`,
);
const columns = [
{ header: 'Docket Number', key: 'docketNumber' },
{ header: 'Document Title', key: 'documentTitle' },
{ header: 'Filed On', key: 'filedOn' },
{ header: 'Filed By', key: 'filedBy' },
];
const rows = documents.map(de => ({
...pick(de, ['docketNumber', 'documentTitle']),
filedBy: nonAttorneys[de.userId!],
filedOn: de.receivedAt.split('T')[0],
}));
const docType = documents[0].documentType.replace(' ', '-').toLowerCase();
const filename = `${OUTPUT_DIR}/${docType}s-filed-by-non-attorneys-in${fiscal ? '-fiscal-year' : ''}-${year}.csv`;
generateCsv({ columns, filename, rows });
console.log(`Generated ${filename}`);
})();
3 changes: 3 additions & 0 deletions web-api/elasticsearch/efcms-docket-entry-mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ export const efcmsDocketEntryMappings = {
'status.S': {
type: 'keyword',
},
'userId.S': {
type: 'keyword',
},
},
};

Expand Down
3 changes: 3 additions & 0 deletions web-api/elasticsearch/efcms-user-mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { createHash } from 'crypto';

export const efcmsUserMappings = {
properties: {
'admissionsDate.S': {
type: 'date',
},
'admissionsStatus.S': {
type: 'keyword',
},
Expand Down

0 comments on commit 0ec140d

Please sign in to comment.