Skip to content

Commit

Permalink
New action delete-contacts
Browse files Browse the repository at this point in the history
  • Loading branch information
kennsippell committed Dec 7, 2024
1 parent 0a9db49 commit 956c092
Show file tree
Hide file tree
Showing 6 changed files with 652 additions and 484 deletions.
59 changes: 59 additions & 0 deletions src/fn/delete-contacts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const minimist = require('minimist');
const path = require('path');

const environment = require('../lib/environment');
const pouch = require('../lib/db');
const { info } = require('../lib/log');

const HierarchyOperations = require('../lib/hierarchy-operations');

module.exports = {
requiresInstance: true,
execute: () => {
const args = parseExtraArgs(environment.pathToProject, environment.extraArgs);
const db = pouch();
const options = {
docDirectoryPath: args.docDirectoryPath,
force: args.force,
};
return HierarchyOperations(db, options).delete(args.sourceIds);
}
};

// Parses extraArgs and asserts if required parameters are not present
const parseExtraArgs = (projectDir, extraArgs = []) => {
const args = minimist(extraArgs, { boolean: true });

const sourceIds = (args.ids || args.id || '')
.split(',')
.filter(id => id);

if (sourceIds.length === 0) {
usage();
throw Error('Action "delete-contacts" is missing required list of contacts to be deleted');
}

return {
sourceIds,
docDirectoryPath: path.resolve(projectDir, args.docDirectoryPath || 'json_docs'),
force: !!args.force,
};
};

const bold = text => `\x1b[1m${text}\x1b[0m`;
const usage = () => {
info(`
${bold('cht-conf\'s delete-contacts action')}
When combined with 'upload-docs' this action recursively deletes a contact and all of their descendant contacts and data. ${bold('This operation is permanent. It cannot be undone.')}
${bold('USAGE')}
cht --local delete-contacts -- --ids=<id1>,<id2>
${bold('OPTIONS')}
--ids=<id1>,<id2>
A comma delimited list of ids of contacts to be deleted.
--docDirectoryPath=<path to stage docs>
Specifies the folder used to store the documents representing the changes in hierarchy.
`);
};
42 changes: 42 additions & 0 deletions src/lib/hierarchy-operations/delete-hierarchy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const DataSource = require('./hierarchy-data-source');
const JsDocs = require('./jsdocFolder');
const { trace, info } = require('../log');

const prettyPrintDocument = doc => `'${doc.name}' (${doc._id})`;
async function deleteHierarchy(db, options, sourceIds) {
console.log(db, options, sourceIds);
const sourceDocs = await DataSource.getContactsByIds(db, sourceIds);
for (const sourceId of sourceIds) {
const sourceDoc = sourceDocs[sourceId];
trace(`Deleting descendants and reports under: ${prettyPrintDocument(sourceDoc)}`);
const descendantsAndSelf = await DataSource.getContactWithDescendants(db, sourceId);

let affectedReportCount = 0;
for (const descendant of descendantsAndSelf) {
JsDocs.deleteDoc(options, descendant);
affectedReportCount += await deleteReportsForContact(db, options, descendant);
}

const affectedContactCount = descendantsAndSelf.length;

info(`Staged updates to delete ${prettyPrintDocument(sourceDoc)}. ${affectedContactCount.length} contact(s) and ${affectedReportCount} report(s).`);
}
}

async function deleteReportsForContact(db, options, contact) {
let skip = 0;
let reportBatch;
do {
reportBatch = await DataSource.getReportsForContacts(db, [], contact._id, skip);

for (const report of reportBatch) {
JsDocs.deleteDoc(options, report);
}

skip += reportBatch.length;
} while (reportBatch.length >= DataSource.BATCH_SIZE);

return skip + reportBatch.length;
}

module.exports = deleteHierarchy;
16 changes: 6 additions & 10 deletions src/lib/hierarchy-operations/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const DataSource = require('./hierarchy-data-source');
const deleteHierarchy = require('./delete-hierarchy');
const JsDocs = require('./jsdocFolder');
const lineageManipulation = require('./lineage-manipulation');
const LineageConstraints = require('./lineage-constraints');
const { trace, info } = require('../log');

const JsDocs = require('./jsdocFolder');
const DataSource = require('./hierarchy-data-source');

function moveHierarchy(db, options) {
return async function (sourceIds, destinationId) {
JsDocs.prepareFolder(options);
Expand All @@ -28,11 +28,7 @@ function moveHierarchy(db, options) {
};

if (options.merge) {
JsDocs.writeDoc(options, {
_id: sourceDoc._id,
_rev: sourceDoc._rev,
_deleted: true,
});
JsDocs.deleteDoc(options, sourceDoc);
}

const prettyPrintDocument = doc => `'${doc.name}' (${doc._id})`;
Expand Down Expand Up @@ -186,11 +182,11 @@ function replaceLineageInContacts(options, moveContext) {
return result;
}

module.exports = (db, options) => {
module.exports = (db, options = {}) => {
return {
HIERARCHY_ROOT: DataSource.HIERARCHY_ROOT,
move: moveHierarchy(db, { ...options, merge: false }),
merge: moveHierarchy(db, { ...options, merge: true }),
delete: async (sourceIds) => deleteHierarchy(db, options, sourceIds),
};
};

9 changes: 9 additions & 0 deletions src/lib/hierarchy-operations/jsdocFolder.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ function deleteAfterConfirmation(docDirectoryPath) {
fs.deleteFilesInFolder(docDirectoryPath);
}

function deleteDoc(options, doc) {
writeDoc(options, {
_id: doc._id,
_rev: doc._rev,
_deleted: true,
});
}

module.exports = {
deleteDoc,
prepareFolder,
writeDoc,
};
Expand Down
2 changes: 1 addition & 1 deletion test/fn/upload-docs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ describe('upload-docs', function() {
expect(res.rows.map(doc => doc.id)).to.deep.eq(['one', 'three', 'two']);
});

describe('kenn --disable-users', () => {
describe('--disable-users', () => {
beforeEach(async () => {
sinon.stub(environment, 'extraArgs').get(() => ['--disable-users']);
await assertDbEmpty();
Expand Down
Loading

0 comments on commit 956c092

Please sign in to comment.