Skip to content

Commit

Permalink
feat: allow searching with national id & pagination (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
naftis authored Sep 13, 2023
1 parent e8811bc commit 69af464
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 89 deletions.
99 changes: 36 additions & 63 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/dci-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"devDependencies": {
"@types/lodash": "^4.14.197",
"@types/node": "^20.5.3",
"msw": "0.0.0-fetch.rc-16",
"msw": "0.0.0-fetch.rc-19",
"nodemon": "^3.0.1",
"openapi-typescript": "^6.5.3",
"pino-pretty": "^10.2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/dci-api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ createServer().then(async (server) => {
})

export type * from './registry-core-api'
export type { SyncSearchRequest } from './validations'
export type { SyncSearchRequest, EventType } from './validations'
2 changes: 1 addition & 1 deletion packages/dci-api/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as Hapi from '@hapi/hapi'
import { HOST, PORT, DEFAULT_TIMEOUT_MS, NODE_ENV } from './constants'
import { routes } from './routes'
import { ParseError } from 'dci-opencrvs-bridge'
import { AuthorizationError } from 'opencrvs-api/src/error'
import { AuthorizationError } from 'opencrvs-api'
import pino from 'hapi-pino'
import { ValidationError, error } from './error'

Expand Down
5 changes: 4 additions & 1 deletion packages/dci-api/src/sync-search/test-payload.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
"reference_id": "123456789020211216223812",
"timestamp": "2022-12-04T17:20:07-04:00",
"registry_type": "civil",
"event_type": "1",
"search_criteria": {
"reg_event_type": {
"namespace": "?",
"value": "1"
},
"query_type": "idtype-value",
"query": {
"identifier_type": {
Expand Down
40 changes: 29 additions & 11 deletions packages/dci-api/src/validations.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { type TypeOf, z } from 'zod'
import { type TypeOf, z, type ZodType } from 'zod'
import { Event } from 'opencrvs-api'

const dateTime = z.string().datetime({ offset: true })

const paginationRequest = z.object({
page_size: z.number(),
page_number: z.number().optional()
page_size: z.number().positive().int(),
page_number: z.number().positive().int().optional()
})

const searchSort = z.object({
Expand Down Expand Up @@ -52,16 +53,32 @@ const header = z.object({
is_msg_encrypted: z.boolean().optional()
})

const reference = z.object({
namespace: z.string().optional(),
refUri: z.string().optional(),
value: z.string()
/**
* https://digital-convergence-initiative-d.gitbook.io/dci-standards-1/standards/1.-crvs/6.5-data-standards/6.5.2-code-directory#cd.04-vital_events
* OpenCRVS only supports [1 = Live Birth] [2 = Death] [4 = Marriage]
*/
const eventTypes = z.enum(['1', '2', '4']).transform((number) => {
switch (number) {
case '1':
return Event.Birth
case '2':
return Event.Death
case '4':
return Event.Marriage
}
})

const reference = (value: ZodType = z.string()) =>
z.object({
namespace: z.string().optional(),
refUri: z.string().optional(),
value
})

const attributeValue = z.string().or(z.number()).or(z.boolean())

const identifierTypeValue = z.object({
identifier_type: reference,
identifier_type: reference(),
identifier_value: attributeValue
})

Expand Down Expand Up @@ -101,9 +118,9 @@ const searchRequest = z.object({
search_criteria: z
.object({
version,
reg_type: reference.optional(),
reg_event_type: reference.optional(),
result_record_type: reference,
reg_type: reference().optional(),
reg_event_type: reference(eventTypes).optional(),
result_record_type: reference(),
sort: z.array(searchSort).optional(),
pagination: paginationRequest.optional(),
consent: consent.optional(),
Expand All @@ -123,3 +140,4 @@ export const requestSchema = z.object({
})

export type SyncSearchRequest = TypeOf<typeof requestSchema>
export type EventType = TypeOf<typeof eventTypes>
7 changes: 5 additions & 2 deletions packages/dci-opencrvs-bridge/src/dci-to-opencrvs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SearchEventsQueryVariables } from 'opencrvs-api'
import { type SearchEventsQueryVariables } from 'opencrvs-api'
import type { SyncSearchRequest } from 'dci-api'
import { ParseError } from './error'

Expand All @@ -19,7 +19,6 @@ export function searchRequestToAdvancedSearchParameters(
// let sortOrder: "asc" | "desc" = "asc";
// let sortColumn: string | undefined;

// TODO: Support more than one identifier
if (query.identifier_type.value === 'BRN') {
parameters.registrationNumber = query.identifier_value
} else if (query.identifier_type.value === 'DRN') {
Expand All @@ -28,10 +27,14 @@ export function searchRequestToAdvancedSearchParameters(
parameters.registrationNumber = query.identifier_value
} else if (query.identifier_type.value === 'OPENCRVS_RECORD_ID') {
parameters.recordId = query.identifier_value
} else if (query.identifier_type.value === 'NID') {
parameters.nationalId = query.identifier_value
} else {
throw new ParseError('Unsupported identifier type')
}

parameters.event = request.search_criteria.reg_event_type?.value

if ((sort?.length ?? 0) > 1) {
throw new ParseError('Sorting by more than one attribute is not supported')
}
Expand Down
Loading

0 comments on commit 69af464

Please sign in to comment.