Skip to content

Commit 5e1f76f

Browse files
rikukissatareq89
authored andcommitted
import locations to analytics database on reindex
1 parent cd1e309 commit 5e1f76f

File tree

3 files changed

+73
-15
lines changed

3 files changed

+73
-15
lines changed

infrastructure/postgres/setup-analytics.sh

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,35 @@ PGPASSWORD="$POSTGRES_PASSWORD" psql -v ON_ERROR_STOP=1 -h "$POSTGRES_HOST" -p "
5050
5151
CREATE SCHEMA IF NOT EXISTS analytics;
5252
53-
CREATE OR REPLACE VIEW analytics.locations
54-
WITH (security_barrier)
55-
AS
56-
SELECT * FROM app.locations;
53+
CREATE TABLE IF NOT EXISTS analytics.locations (
54+
id uuid PRIMARY KEY,
55+
name text NOT NULL,
56+
parent_id uuid REFERENCES analytics.locations(id),
57+
location_type TEXT NOT NULL
58+
);
59+
60+
CREATE UNIQUE INDEX IF NOT EXISTS analytics_locations_pkey ON analytics.locations(id uuid_ops);
5761
5862
CREATE TABLE IF NOT EXISTS analytics.event_actions (
5963
event_type text NOT NULL,
60-
action_type app.action_type NOT NULL,
64+
action_type TEXT NOT NULL,
6165
annotation jsonb,
6266
assigned_to text,
6367
created_at timestamp with time zone NOT NULL DEFAULT now(),
64-
created_at_location uuid REFERENCES app.locations(id),
68+
created_at_location uuid,
6569
created_by text NOT NULL,
6670
created_by_role text NOT NULL,
6771
created_by_signature text,
68-
created_by_user_type app.user_type NOT NULL,
72+
created_by_user_type TEXT NOT NULL,
6973
declared_at timestamp with time zone,
7074
registered_at timestamp with time zone,
7175
declaration jsonb NOT NULL DEFAULT '{}'::jsonb,
72-
event_id uuid NOT NULL REFERENCES app.events(id),
76+
event_id uuid NOT NULL,
7377
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
74-
original_action_id uuid REFERENCES app.event_actions(id),
78+
original_action_id uuid,
7579
registration_number text UNIQUE,
7680
request_id text,
77-
status app.action_status NOT NULL,
81+
status TEXT NOT NULL,
7882
transaction_id text NOT NULL,
7983
content jsonb,
8084
UNIQUE (id, event_id)

src/analytics/analytics.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import {
2424
EventDocument,
2525
EventState,
2626
getActionAnnotationFields,
27-
getCurrentEventState
27+
getCurrentEventState,
28+
Location
2829
} from '@opencrvs/toolkit/events'
2930
import { differenceInDays } from 'date-fns'
3031
import { ExpressionBuilder, Kysely } from 'kysely'
@@ -232,6 +233,43 @@ export async function importEvent(event: EventDocument, trx: Kysely<any>) {
232233
logger.info(`Event with id "${event.id}" logged into analytics`)
233234
}
234235

236+
export async function importLocations(locations: Location[]) {
237+
const client = getClient()
238+
await client.transaction().execute(async (trx) => {
239+
for (const [index, batch] of chunk(
240+
locations,
241+
INSERT_MAX_CHUNK_SIZE
242+
).entries()) {
243+
logger.info(
244+
`Importing ${Math.min((index + 1) * INSERT_MAX_CHUNK_SIZE, locations.length)}/${locations.length} locations`
245+
)
246+
247+
await trx
248+
.insertInto('analytics.locations')
249+
.values(
250+
batch.map((l) => ({
251+
id: l.id,
252+
name: l.name,
253+
parentId: l.parentId,
254+
locationType: l.locationType
255+
}))
256+
)
257+
.onConflict((oc) =>
258+
oc
259+
.column('id')
260+
.doUpdateSet(
261+
(eb: ExpressionBuilder<any, 'analytics.locations'>) => ({
262+
name: eb.ref('excluded.name'),
263+
parentId: eb.ref('excluded.parentId'),
264+
locationType: eb.ref('excluded.locationType')
265+
})
266+
)
267+
)
268+
.execute()
269+
}
270+
})
271+
}
272+
235273
export async function importEvents(events: EventDocument[], trx: Kysely<any>) {
236274
for (const event of events) {
237275
await importEvent(event, trx)

src/index.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ import {
3030
COUNTRY_CONFIG_PORT,
3131
CHECK_INVALID_TOKEN,
3232
AUTH_URL,
33-
DEFAULT_TIMEOUT
33+
DEFAULT_TIMEOUT,
34+
GATEWAY_URL
3435
} from '@countryconfig/constants'
3536
import {
3637
contentHandler,
@@ -70,11 +71,13 @@ import getUserNotificationRoutes from './config/routes/userNotificationRoutes'
7071
import {
7172
importEvent,
7273
importEvents,
74+
importLocations,
7375
syncLocationLevels,
7476
syncLocationStatistics
7577
} from './analytics/analytics'
7678
import { getClient } from './analytics/postgres'
7779
import { env } from './environment'
80+
import { createClient } from '@opencrvs/toolkit/api'
7881

7982
export interface ITokenPayload {
8083
sub: string
@@ -605,6 +608,12 @@ export async function createServer() {
605608
if (queue.length > 0) {
606609
await importEvents(queue, trx)
607610
}
611+
612+
// Import locations
613+
const url = new URL('events', GATEWAY_URL).toString()
614+
const client = createClient(url, req.headers.authorization)
615+
const locations = await client.locations.list.query()
616+
await importLocations(locations)
608617
})
609618

610619
logger.info('Reindexed all events into analytics.')
@@ -687,6 +696,7 @@ export async function createServer() {
687696
const parsedPath = /^\/trigger\/events\/[^/]+\/actions\/([^/]+)$/.exec(
688697
request.route.path
689698
)
699+
690700
const actionType = parsedPath?.[1] as ActionType | null
691701
const wasRequestForActionConfirmation =
692702
actionType && request.method === 'post'
@@ -695,9 +705,15 @@ export async function createServer() {
695705
if (wasRequestForActionConfirmation && wasActionAcceptedImmediately) {
696706
const event = request.payload as EventDocument
697707
const client = getClient()
698-
await client.transaction().execute(async (trx) => {
699-
await importEvent(event, trx)
700-
})
708+
try {
709+
await client.transaction().execute(async (trx) => {
710+
await importEvent(event, trx)
711+
})
712+
} catch (error) {
713+
// eslint-disable-next-line no-console
714+
console.error(error)
715+
throw error
716+
}
701717
}
702718
return h.continue
703719
})

0 commit comments

Comments
 (0)