From 32306944063ac85740dd3a95f073f3d129999b44 Mon Sep 17 00:00:00 2001 From: R Ranathunga Date: Thu, 2 Jan 2025 20:43:47 -0800 Subject: [PATCH] feat: enable history on ccbc communities --- .../History/CbcHistoryCommunitiesTable.tsx | 45 +-- .../Analyst/History/HistoryContent.tsx | 41 +++ .../Analyst/History/HistoryIcon.tsx | 1 + .../Analyst/History/HistoryTable.tsx | 11 + app/components/DiffTable.tsx | 44 +++ .../uiSchema/history/communities.ts | 14 + app/package.json | 2 + app/yarn.lock | 7 + cron/shp/sql/create_application_rd.sql | 34 ++- .../computed_columns/application_history.sql | 12 + .../application_history@1.218.3.sql | 268 ++++++++++++++++++ .../computed_columns/application_history.sql | 2 +- .../application_history@1.218.3.sql | 268 ++++++++++++++++++ db/sqitch.plan | 1 + 14 files changed, 725 insertions(+), 25 deletions(-) create mode 100644 app/formSchema/uiSchema/history/communities.ts create mode 100644 db/deploy/computed_columns/application_history@1.218.3.sql create mode 100644 db/revert/computed_columns/application_history@1.218.3.sql diff --git a/app/components/Analyst/CBC/History/CbcHistoryCommunitiesTable.tsx b/app/components/Analyst/CBC/History/CbcHistoryCommunitiesTable.tsx index addf4d3866..95a7605bd6 100644 --- a/app/components/Analyst/CBC/History/CbcHistoryCommunitiesTable.tsx +++ b/app/components/Analyst/CBC/History/CbcHistoryCommunitiesTable.tsx @@ -3,6 +3,12 @@ import styled from 'styled-components'; interface Props { action: string; communities: any[]; + isCbc: boolean; +} + +interface TableProps { + isCbc: boolean; + isDeleted?: boolean; } const StyledCommunitiesContainer = styled.div` @@ -10,21 +16,22 @@ const StyledCommunitiesContainer = styled.div` align-items: center; `; -const StyledLeftContainer = styled.div` +const StyledLeftContainer = styled.div` padding-right: 2%; - width: 250px; + width: ${(props) => (props.isCbc ? '250px' : '300px')}; `; -const StyledTable = styled.table` +const StyledTable = styled.table` th { border: none; } tbody > tr { border-bottom: thin dashed; + text-decoration: ${(props) => (props.isDeleted ? 'line-through' : 'none')}; border-color: ${(props) => props.theme.color.borderGrey}; td { - width: 200px; - max-width: 200px; + width: ${(props) => (props.isCbc ? '200px' : '350px')}; + max-width: ${(props) => (props.isCbc ? '200px' : '350px')}; border: none; } } @@ -37,22 +44,26 @@ const StyledIdCell = styled.td` const CbcHistoryCommunitiesTable: React.FC = ({ action, - communities, + communities = [], + isCbc = true, }) => { return ( - {`${action} community location data`} + {`${action} community location data`}
- + Economic Region Regional District - Geographic Name - Type - ID + {isCbc && Geographic Name} + {isCbc && Type} + {isCbc && ID} @@ -64,11 +75,13 @@ const CbcHistoryCommunitiesTable: React.FC = ({ > {community.economic_region} {community.regional_district} - {community.bc_geographic_name} - {community.geographic_type} - - {community.communities_source_data_id} - + {isCbc && {community.bc_geographic_name}} + {isCbc && {community.geographic_type}} + {isCbc && ( + + {community.communities_source_data_id} + + )} ))} diff --git a/app/components/Analyst/History/HistoryContent.tsx b/app/components/Analyst/History/HistoryContent.tsx index aeb7b853c7..2cde730cd5 100644 --- a/app/components/Analyst/History/HistoryContent.tsx +++ b/app/components/Analyst/History/HistoryContent.tsx @@ -13,10 +13,13 @@ import gis from 'formSchema/uiSchema/history/gis'; import gisAssessmentHhSchema from 'formSchema/uiSchema/history/gisAssessmentHh'; import applicationSowDataSchema from 'formSchema/uiSchema/history/applicationSowData'; import applicationAnnounced from 'formSchema/uiSchema/history/applicationAnnounced'; +import { processArrayDiff } from 'components/DiffTable'; +import communities from 'formSchema/uiSchema/history/communities'; import StatusPill from '../../StatusPill'; import HistoryDetails from './HistoryDetails'; import HistoryAttachment from './HistoryAttachment'; import HistoryFile from './HistoryFile'; +import CbcHistoryCommunitiesTable from '../CBC/History/CbcHistoryCommunitiesTable'; const StyledContent = styled.span` display: flex; @@ -68,6 +71,13 @@ const filterArrays = (obj: Record): Record => { return Object.fromEntries(filteredEntries); }; +const processCommunity = (values) => { + return values?.map((community) => ({ + economic_region: community.er, + regional_district: community.rd, + })); +}; + const HistoryContent = ({ historyItem, prevHistoryItem, @@ -972,6 +982,37 @@ const HistoryContent = ({ ); } + if (tableName === 'communities') { + const user = + createdBy === 1 && op === 'INSERT' ? 'The system' : displayName; + const changes = diff(prevHistoryItem?.record || {}, record); + const [newArray, oldArray] = processArrayDiff( + changes, + communities.applicationCommunities + ); + + return ( + <> + + + {user} updated the coverage area for the project which resulted in a + change to Community Location Data on {createdAtFormatted} + + + + + + ); + } + return null; }; diff --git a/app/components/Analyst/History/HistoryIcon.tsx b/app/components/Analyst/History/HistoryIcon.tsx index 7a440ff39b..85faccb935 100644 --- a/app/components/Analyst/History/HistoryIcon.tsx +++ b/app/components/Analyst/History/HistoryIcon.tsx @@ -53,6 +53,7 @@ const iconMap = { application_community_progress_report_data: faTreeCity, application_milestone_data: faSignsPost, application_project_type: faWifi, + communities: faClipboardList, }; interface Props { diff --git a/app/components/Analyst/History/HistoryTable.tsx b/app/components/Analyst/History/HistoryTable.tsx index 5dc10e9628..499953b627 100644 --- a/app/components/Analyst/History/HistoryTable.tsx +++ b/app/components/Analyst/History/HistoryTable.tsx @@ -3,6 +3,7 @@ import { graphql, useFragment } from 'react-relay'; import { getFiscalQuarter, getFiscalYear } from 'utils/fiscalFormat'; import { HistoryTable_query$key } from '__generated__/HistoryTable_query.graphql'; import { useMemo, useState } from 'react'; +import isEqual from 'lodash.isequal'; import HistoryRow from './HistoryRow'; import HistoryFilter, { filterByType, @@ -240,6 +241,16 @@ const HistoryTable: React.FC = ({ query }) => { } const prevHistoryItem = prevItems.length > 0 ? prevItems[0] : {}; + // Skipping duplicate history items for communities + if ( + historyItem?.tableName === 'communities' && + isEqual( + prevHistoryItem.record?.application_er, + historyItem.record?.application_er + ) + ) { + return null; + } // using index + recordId for key as just recordId was causing strange duplicate record bug for delete history item until page refresh return ( { + acc[key] = data[key]; + return acc; + }, {}); +} + +export const processArrayDiff = (changes, schema) => { + const newArray = []; + const oldArray = []; + + const entries = Object.entries(changes); + entries.forEach(([key, value]) => { + if (key.endsWith('__added') && Array.isArray(value)) { + newArray.push(...value); + } else if (key.endsWith('__deleted') && Array.isArray(value)) { + oldArray.push(...value); + } else if (Array.isArray(value)) { + value.forEach(([prefix, diffValue]) => { + if (prefix === '-') { + oldArray.push(diffValue); + } else if (prefix === '~') { + ['__old', '__new'].forEach((childKey, idx) => { + const newObject = createObjectFromSchema(schema, { + er: diffValue.er[childKey], + rd: diffValue.rd[childKey], + }); + if (idx === 0) { + oldArray.push(newObject); + } else { + newArray.push(newObject); + } + }); + } else if (prefix === '+') { + newArray.push(diffValue); + } + }); + } + }); + + return [newArray, oldArray]; +}; + interface Props { changes: any; diffSchema: any; diff --git a/app/formSchema/uiSchema/history/communities.ts b/app/formSchema/uiSchema/history/communities.ts new file mode 100644 index 0000000000..eb93a5b110 --- /dev/null +++ b/app/formSchema/uiSchema/history/communities.ts @@ -0,0 +1,14 @@ +const communities = { + applicationCommunities: { + properties: { + er: { + title: 'Economic Regions', + }, + rd: { + title: 'Regional Districts', + }, + }, + }, +}; + +export default communities; diff --git a/app/package.json b/app/package.json index 252868aec1..6a81cfdcdb 100644 --- a/app/package.json +++ b/app/package.json @@ -86,6 +86,7 @@ "jsonlint": "^1.6.3", "jsonwebtoken": "^9.0.2", "lightship": "7.2.0", + "lodash.isequal": "^4.5.0", "luxon": "^3.5.0", "material-react-table": "2.13", "morgan": "^1.10.0", @@ -131,6 +132,7 @@ "@types/express": "^4.17.21", "@types/jest": "^28.1.6", "@types/json-diff": "^1.0.3", + "@types/lodash.isequal": "^4.5.8", "@types/luxon": "^3.4.2", "@types/node": "20.14.14", "@types/react": "18.3.12", diff --git a/app/yarn.lock b/app/yarn.lock index 99a880a181..d3b9dae5b7 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -4033,6 +4033,13 @@ dependencies: "@types/node" "*" +"@types/lodash.isequal@^4.5.8": + version "4.5.8" + resolved "https://registry.yarnpkg.com/@types/lodash.isequal/-/lodash.isequal-4.5.8.tgz#b30bb6ff6a5f6c19b3daf389d649ac7f7a250499" + integrity sha512-uput6pg4E/tj2LGxCZo9+y27JNyB2OZuuI/T5F+ylVDYuqICLG2/ktjxx0v6GvVntAf8TvEzeQLcV0ffRirXuA== + dependencies: + "@types/lodash" "*" + "@types/lodash.template@4.5.0": version "4.5.0" resolved "https://registry.yarnpkg.com/@types/lodash.template/-/lodash.template-4.5.0.tgz#277654af717ed37ce2687c69f8f221c550276b7a" diff --git a/cron/shp/sql/create_application_rd.sql b/cron/shp/sql/create_application_rd.sql index 8bb860d438..d6616f9741 100644 --- a/cron/shp/sql/create_application_rd.sql +++ b/cron/shp/sql/create_application_rd.sql @@ -1,26 +1,44 @@ -- Step 1: Drop the table if it exists DROP TABLE IF EXISTS ccbc_public.application_rd; --- Step 2: Create table for Regional Districts (RD) +-- Step 2: Create the table explicitly with an auto-incrementing primary key and audit columns +CREATE TABLE ccbc_public.application_rd ( + id SERIAL PRIMARY KEY, -- Auto-incrementing primary key + application_id INTEGER, + ccbc_number TEXT, + rd TEXT, + er TEXT, + created_by INTEGER DEFAULT NULL, -- User ID who created the record + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), -- Timestamp when the record was created + updated_by INTEGER DEFAULT NULL, -- User ID who last updated the record + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NULL, -- Timestamp when the record was last updated + archived_by INTEGER DEFAULT NULL, -- User ID who archived the record + archived_at TIMESTAMP WITH TIME ZONE DEFAULT NULL -- Timestamp when the record was archived +); + +SELECT audit.enable_tracking('ccbc_public.application_rd'::regclass); + +-- Step 3: Populate the table with data WITH rd_regions AS ( SELECT s.ccbc_numbe AS ccbc_number, - r.aa_name AS rd + r.aa_name AS rd, + er.cnmcrgnnm AS er FROM ccbc_public.ccbc_applications_coverages s LEFT JOIN ccbc_public.regional_districts r ON ST_Intersects(ST_makeValid(s.geom), r.geom) - ORDER BY + LEFT JOIN + ccbc_public.economic_regions er ON (ST_Area(ST_Intersection(ST_MakeValid(er.geom), ST_MakeValid(r.geom))) / ST_Area(ST_MakeValid(r.geom))) > 0.8 + ORDER BY s.ccbc_numbe ) - --- Step 3: Join with the application table to get the application_id and insert into new table +INSERT INTO ccbc_public.application_rd (application_id, ccbc_number, rd, er) SELECT a.id as application_id, rd.ccbc_number, - rd.rd -INTO - ccbc_public.application_rd + rd.rd, + rd.er FROM rd_regions rd JOIN diff --git a/db/deploy/computed_columns/application_history.sql b/db/deploy/computed_columns/application_history.sql index 317af7b905..72445d89f5 100644 --- a/db/deploy/computed_columns/application_history.sql +++ b/db/deploy/computed_columns/application_history.sql @@ -258,6 +258,18 @@ union all where v.op='UPDATE' and v.table_name='application_dependencies' and v.record->>'archived_by' is null and v.record->>'application_id'=application.id::varchar(10); + union all + select application.id, v.created_at, v.op, v.table_name, (array_agg(v.record_id))[1] AS record_id, + jsonb_build_object('application_rd', jsonb_agg(jsonb_build_object('er', v.record->'er', 'rd', v.record->'rd'))) as record, + jsonb_agg(v.old_record) AS old_record, + MAX(v.record->>'application_rd') AS item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_rd' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + group by v.created_at, v.op, v.table_name, u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by; + $$ language sql stable; grant execute on function ccbc_public.application_history to ccbc_admin; diff --git a/db/deploy/computed_columns/application_history@1.218.3.sql b/db/deploy/computed_columns/application_history@1.218.3.sql new file mode 100644 index 0000000000..317af7b905 --- /dev/null +++ b/db/deploy/computed_columns/application_history@1.218.3.sql @@ -0,0 +1,268 @@ +-- Deploy ccbc:computed_columns/application_history to pg + +begin; + +create or replace function ccbc_public.application_history(application ccbc_public.application) +returns setof ccbc_public.history_item as $$ + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, 'application' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application' and v.record->>'id'=application.id::varchar(10) + union all + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, v.record->>'status' as item, + COALESCE(u.family_name,'Automated process'), COALESCE(u.given_name,''), COALESCE(u.session_sub,'robot@idir'), COALESCE(u.external_analyst,null), v.created_by + from ccbc_public.record_version as v + left join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_status' + and v.record->>'application_id'=application.id::varchar(10) + union all + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, v.record->>'file_name' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='attachment' + and v.record->>'application_id'=application.id::varchar(10) and v.record->>'archived_by' is null + + union all + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, v.record->>'assessment_data_type' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='assessment_data' + and v.record->>'application_id'=application.id::varchar(10) and v.record->>'archived_by' is null + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record-> 'json_data' ->>'rfiType' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='rfi_data' and v.record->>'archived_by' is null + and v.record->>'id' in (select rd.id::varchar(10) from ccbc_public.rfi_data as rd + inner join ccbc_public.application_rfi_data arf + on arf.rfi_data_id = rd.id + where arf.application_id = application.id) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record-> 'json_data' ->>'rfiType' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='rfi_data' and v.record->>'archived_by' is null + and v.record->>'id' in (select rd.id::varchar(10) from ccbc_public.rfi_data as rd + inner join ccbc_public.application_rfi_data arf + on arf.rfi_data_id = rd.id + where arf.application_id = application.id) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + concat_ws(' ', a.given_name, a.family_name) as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + left join ccbc_public.analyst a on v.record->>'analyst_id' = a.id::varchar(10) + where v.op='INSERT' and v.table_name='application_analyst_lead' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'package' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_package' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'conditional_approval_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='conditional_approval_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record-> 'json_data' ->>'reason_for_change' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='form_data' and v.record->>'archived_by' is null + and v.record->>'id' in ( + select fd.id::varchar(10) from ccbc_public.form_data as fd, + ccbc_public.form as f, ccbc_public.application_form_data as af + where + fd.form_schema_id = f.id and + f.form_type = 'intake' and + af.application_id = application.id and + fd.id = af.form_data_id ) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'conditional_approval_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_gis_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by = u.id + where (v.op='INSERT' or v.op='UPDATE') and v.table_name='application_gis_assessment_hh' + and v.record->>'archived_by' is null and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where (v.op='INSERT' or v.op='UPDATE') and v.table_name='application_announced' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_announcement' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='project_information_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + +union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by = u.id + where v.op ='INSERT' and v.table_name = 'application_sow_data' and v.record->>'archived_by' is null + and v.record->>'application_id' = application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where (v.op='INSERT' or v.op='UPDATE') and v.table_name='change_request_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.table_name='application_announcement' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_community_progress_report_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_community_progress_report_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_community_progress_report_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='application_community_progress_report_data' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_claims_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='application_claims_data' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_community_claims_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_claims_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_milestone_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_milestone_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_milestone_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='application_milestone_data' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_project_type' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_project_type' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_dependencies' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_dependencies' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_dependencies' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on u.id = (v.record->>'updated_by')::int + where v.op='UPDATE' and v.table_name='application_dependencies' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10); + +$$ language sql stable; + +grant execute on function ccbc_public.application_history to ccbc_admin; +grant execute on function ccbc_public.application_history to ccbc_analyst; + +comment on function ccbc_public.application_history is 'Computed column that returns list of audit records for application'; + +commit; diff --git a/db/revert/computed_columns/application_history.sql b/db/revert/computed_columns/application_history.sql index 281a8780bf..317af7b905 100644 --- a/db/revert/computed_columns/application_history.sql +++ b/db/revert/computed_columns/application_history.sql @@ -172,7 +172,7 @@ union all v.record->>'history_operation' as item, u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by from ccbc_public.record_version as v - inner join ccbc_public.ccbc_user u on v.created_by=u.id + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id where v.table_name='application_announcement' and v.record->>'history_operation'='deleted' and v.record->>'application_id'=application.id::varchar(10) diff --git a/db/revert/computed_columns/application_history@1.218.3.sql b/db/revert/computed_columns/application_history@1.218.3.sql new file mode 100644 index 0000000000..281a8780bf --- /dev/null +++ b/db/revert/computed_columns/application_history@1.218.3.sql @@ -0,0 +1,268 @@ +-- Deploy ccbc:computed_columns/application_history to pg + +begin; + +create or replace function ccbc_public.application_history(application ccbc_public.application) +returns setof ccbc_public.history_item as $$ + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, 'application' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application' and v.record->>'id'=application.id::varchar(10) + union all + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, v.record->>'status' as item, + COALESCE(u.family_name,'Automated process'), COALESCE(u.given_name,''), COALESCE(u.session_sub,'robot@idir'), COALESCE(u.external_analyst,null), v.created_by + from ccbc_public.record_version as v + left join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_status' + and v.record->>'application_id'=application.id::varchar(10) + union all + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, v.record->>'file_name' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='attachment' + and v.record->>'application_id'=application.id::varchar(10) and v.record->>'archived_by' is null + + union all + + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, v.record->>'assessment_data_type' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='assessment_data' + and v.record->>'application_id'=application.id::varchar(10) and v.record->>'archived_by' is null + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record-> 'json_data' ->>'rfiType' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='rfi_data' and v.record->>'archived_by' is null + and v.record->>'id' in (select rd.id::varchar(10) from ccbc_public.rfi_data as rd + inner join ccbc_public.application_rfi_data arf + on arf.rfi_data_id = rd.id + where arf.application_id = application.id) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record-> 'json_data' ->>'rfiType' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='rfi_data' and v.record->>'archived_by' is null + and v.record->>'id' in (select rd.id::varchar(10) from ccbc_public.rfi_data as rd + inner join ccbc_public.application_rfi_data arf + on arf.rfi_data_id = rd.id + where arf.application_id = application.id) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + concat_ws(' ', a.given_name, a.family_name) as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + left join ccbc_public.analyst a on v.record->>'analyst_id' = a.id::varchar(10) + where v.op='INSERT' and v.table_name='application_analyst_lead' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'package' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_package' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'conditional_approval_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='conditional_approval_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record-> 'json_data' ->>'reason_for_change' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='form_data' and v.record->>'archived_by' is null + and v.record->>'id' in ( + select fd.id::varchar(10) from ccbc_public.form_data as fd, + ccbc_public.form as f, ccbc_public.application_form_data as af + where + fd.form_schema_id = f.id and + f.form_type = 'intake' and + af.application_id = application.id and + fd.id = af.form_data_id ) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'conditional_approval_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_gis_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by = u.id + where (v.op='INSERT' or v.op='UPDATE') and v.table_name='application_gis_assessment_hh' + and v.record->>'archived_by' is null and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where (v.op='INSERT' or v.op='UPDATE') and v.table_name='application_announced' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_announcement' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='project_information_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + +union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by = u.id + where v.op ='INSERT' and v.table_name = 'application_sow_data' and v.record->>'archived_by' is null + and v.record->>'application_id' = application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where (v.op='INSERT' or v.op='UPDATE') and v.table_name='change_request_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'history_operation' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.table_name='application_announcement' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_community_progress_report_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_community_progress_report_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_community_progress_report_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='application_community_progress_report_data' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_claims_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='application_claims_data' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_community_claims_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_claims_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_milestone_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_milestone_data' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_milestone_data' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on (v.record->>'updated_by')::integer=u.id + where v.op='UPDATE' and v.table_name='application_milestone_data' and v.record->>'history_operation'='deleted' + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_project_type' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_project_type' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_dependencies' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on v.created_by=u.id + where v.op='INSERT' and v.table_name='application_dependencies' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10) + + union all + select application.id, v.created_at, v.op, v.table_name, v.record_id, v.record, v.old_record, + v.record->>'application_dependencies' as item, + u.family_name, u.given_name, u.session_sub, u.external_analyst, v.created_by + from ccbc_public.record_version as v + inner join ccbc_public.ccbc_user u on u.id = (v.record->>'updated_by')::int + where v.op='UPDATE' and v.table_name='application_dependencies' and v.record->>'archived_by' is null + and v.record->>'application_id'=application.id::varchar(10); + +$$ language sql stable; + +grant execute on function ccbc_public.application_history to ccbc_admin; +grant execute on function ccbc_public.application_history to ccbc_analyst; + +comment on function ccbc_public.application_history is 'Computed column that returns list of audit records for application'; + +commit; diff --git a/db/sqitch.plan b/db/sqitch.plan index 5e2f3e13ab..122d45adc6 100644 --- a/db/sqitch.plan +++ b/db/sqitch.plan @@ -770,3 +770,4 @@ computed_columns/application_history [computed_columns/application_history@1.213 @1.218.3 2024-12-24T20:06:08Z CCBC Service Account # release v1.218.3 @1.219.0 2025-01-02T15:53:33Z CCBC Service Account # release v1.219.0 @1.220.0 2025-01-02T19:26:33Z CCBC Service Account # release v1.220.0 +computed_columns/application_history [computed_columns/application_history@1.218.3] 2025-01-03T04:14:09Z ,,, # combine locations history to ccbc history