-
-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support to cht-datasource for getting a person with lineage
- Loading branch information
Showing
18 changed files
with
848 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,13 @@ | ||
import { DataObject, hasFields, isRecord } from './core'; | ||
import { DataObject, hasField, Identifiable, isIdentifiable, isRecord } from './core'; | ||
|
||
/** | ||
* A document from the database. | ||
*/ | ||
export interface Doc extends DataObject { | ||
readonly _id: string; | ||
export interface Doc extends DataObject, Identifiable { | ||
readonly _rev: string; | ||
} | ||
|
||
/** @internal */ | ||
export const isDoc = (value: unknown): value is Doc => { | ||
return isRecord(value) && hasFields(value, [ | ||
{ name: '_id', type: 'string' }, | ||
{ name: '_rev', type: 'string' } | ||
]); | ||
}; | ||
export const isDoc = (value: unknown): value is Doc => isRecord(value) | ||
&& isIdentifiable(value) | ||
&& hasField(value, { name: '_rev', type: 'string' }); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Contact, NormalizedParent } from '../../libs/contact'; | ||
import { | ||
DataObject, | ||
findById, | ||
isIdentifiable, | ||
isNonEmptyArray, | ||
isNotNull, | ||
NonEmptyArray, | ||
Nullable | ||
} from '../../libs/core'; | ||
import { Doc } from '../../libs/doc'; | ||
import { queryDocsByKey } from './doc'; | ||
|
||
/** | ||
* Returns the identified document along with the parent documents recorded for its lineage. The returned array is | ||
* sorted such that the identified document is the first element and the parent documents are in order of lineage. | ||
* @internal | ||
*/ | ||
export const getLineageDocsById = ( | ||
medicDb: PouchDB.Database<Doc> | ||
): (id: string) => Promise<Nullable<Doc>[]> => queryDocsByKey(medicDb, 'medic-client/docs_by_id_lineage'); | ||
|
||
/** @internal */ | ||
export const getPrimaryContactIds = (places: NonEmptyArray<Nullable<Doc>>): string[] => places | ||
.filter(isNotNull) | ||
.map(({ contact }) => contact) | ||
.filter(isIdentifiable) | ||
.map(({ _id }) => _id) | ||
.filter((_id) => _id.length > 0); | ||
|
||
/** @internal */ | ||
export const hydratePrimaryContact = (contacts: Doc[]) => (place: Nullable<Doc>): Nullable<Doc> => { | ||
if (!place || !isIdentifiable(place.contact)) { | ||
return place; | ||
} | ||
const contact = findById(contacts, place.contact._id); | ||
if (!contact) { | ||
return place; | ||
} | ||
return { | ||
...place, | ||
contact | ||
}; | ||
}; | ||
|
||
const getParentUuid = (index: number, contact?: NormalizedParent): Nullable<string> => { | ||
if (!contact) { | ||
return null; | ||
} | ||
if (index === 0) { | ||
return contact._id; | ||
} | ||
return getParentUuid(index - 1, contact.parent); | ||
}; | ||
|
||
const mergeLineage = (lineage: DataObject[], parent: DataObject): DataObject => { | ||
if (!isNonEmptyArray(lineage)) { | ||
return parent; | ||
} | ||
const child = lineage.at(-1)!; | ||
const mergedChild = { | ||
...child, | ||
parent: parent | ||
}; | ||
return mergeLineage(lineage.slice(0, -1), mergedChild); | ||
}; | ||
|
||
/** @internal */ | ||
export const hydrateLineage = ( | ||
contact: Contact, | ||
lineage: Nullable<Doc>[] | ||
): Contact => { | ||
const fullLineage = lineage | ||
.map((place, index) => { | ||
if (place) { | ||
return place; | ||
} | ||
// If no doc was found, just add a placeholder object with the id from the contact | ||
return { _id: getParentUuid(index, contact.parent) }; | ||
}); | ||
const hierarchy = [contact, ...fullLineage]; | ||
return mergeLineage(hierarchy.slice(0, -1), hierarchy.at(-1)!) as Contact; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.