From ecdcfe1642be6a5f1871811773508af9620dc05a Mon Sep 17 00:00:00 2001 From: Paul McPhee Date: Wed, 27 Mar 2024 15:33:45 +0000 Subject: [PATCH] PI-2035: Added activity log --- assets/scss/application.scss | 24 ------ assets/scss/components/_card.scss | 5 ++ assets/scss/components/_summary-card.scss | 26 +++++++ integration_tests/e2e/activityLog.cy.ts | 65 ++++++++++++++++ integration_tests/pages/activityLog.ts | 9 +++ integration_tests/pages/page.ts | 3 +- server/data/model/schedule.ts | 4 +- server/routes/activityLog.ts | 31 +++++++- server/services/index.ts | 1 - server/utils/nunjucksSetup.ts | 8 +- server/utils/utils.test.ts | 34 ++++++++ server/utils/utils.ts | 2 + .../_appointment-timeline-entry.njk | 3 +- .../_communication-timeline-entry.njk | 3 +- .../activity-log/_communication-title.njk | 1 - .../activity-log/_compact-timeline-entry.njk | 6 +- .../pages/activity-log/_compact-view.njk | 9 +-- server/views/pages/activity-log/_filters.njk | 78 ------------------- .../activity-log/_other-timeline-entry.njk | 3 +- .../pages/activity-log/_timeline-notes.njk | 29 +++---- server/views/pages/schedule/appointment.njk | 8 +- wiremock/mappings/X000001-activity-log.json | 77 ++++++++++-------- 22 files changed, 258 insertions(+), 171 deletions(-) create mode 100644 integration_tests/e2e/activityLog.cy.ts create mode 100644 integration_tests/pages/activityLog.ts diff --git a/assets/scss/application.scss b/assets/scss/application.scss index 6e27276c..0b1828f3 100755 --- a/assets/scss/application.scss +++ b/assets/scss/application.scss @@ -12,28 +12,4 @@ $govuk-page-width: $moj-page-width; @import './components/card'; @import 'assets/scss/local'; -.app-compliance-tag--compact { - width: 20px; - text-align: center; - float: right; -} - -.govuk-tag { - display: inline-block; - outline: 2px solid transparent; - outline-offset: -2px; - letter-spacing: 1px; - max-width: none; - text-decoration: none; - text-transform: uppercase; - font-family: "GDS Transport", arial, sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-weight: 700; - font-size: 1rem; - padding-top: 5px; - padding-right: 8px; - padding-bottom: 4px; - padding-left: 8px; -} diff --git a/assets/scss/components/_card.scss b/assets/scss/components/_card.scss index cfeac005..e5850241 100644 --- a/assets/scss/components/_card.scss +++ b/assets/scss/components/_card.scss @@ -19,3 +19,8 @@ color: govuk-shade(govuk-colour("dark-grey", $legacy: "grey-1"), 30); background: govuk-tint(govuk-colour("dark-grey", $legacy: "grey-1"), 90); } + +.note-panel { + background-color: #f3f2f1; + padding: 1.5rem +} \ No newline at end of file diff --git a/assets/scss/components/_summary-card.scss b/assets/scss/components/_summary-card.scss index 9270fad5..c0d31526 100644 --- a/assets/scss/components/_summary-card.scss +++ b/assets/scss/components/_summary-card.scss @@ -81,3 +81,29 @@ display: none; } } + +.app-compliance-tag--compact { + width: 20px; + text-align: center; + float: right; +} + +.govuk-tag { + display: inline-block; + outline: 2px solid transparent; + outline-offset: -2px; + letter-spacing: 1px; + max-width: none; + text-decoration: none; + text-transform: uppercase; + font-family: "GDS Transport", arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: 700; + font-size: 1rem; + padding-top: 5px; + padding-right: 8px; + padding-bottom: 4px; + padding-left: 8px; +} + diff --git a/integration_tests/e2e/activityLog.cy.ts b/integration_tests/e2e/activityLog.cy.ts new file mode 100644 index 00000000..36c5662b --- /dev/null +++ b/integration_tests/e2e/activityLog.cy.ts @@ -0,0 +1,65 @@ +import Page from '../pages/page' +import ActivityLogPage from '../pages/activityLog' + +context('Appointment', () => { + it('Activity log page is rendered in default view', () => { + cy.visit('/case/X000001/activity-log') + const page = Page.verifyOnPage(ActivityLogPage) + page.getRowData('timeline1', 'enforcement', 'Value').should('contain.text', 'Warning letter sent') + page.getRowData('timeline2', 'rarActivity', 'Value').should('contain.text', 'Stepping Stones') + page.getCardHeader('timeline3').should('contain.text', 'Waiting for evidence') + page.getRowData('timeline4', 'reschedule', 'Value').should('contain.text', 'Requested by Terry Jones') + page.getCardHeader('timeline5').should('contain.text', 'Office appointment at 10:15am') + page.getCardHeader('timeline6').should('contain.text', 'Phone call at 8:15am') + page.getCardHeader('timeline7').should('contain.text', 'Office appointment at 10:15am') + page.getCardHeader('timeline8').should('contain.text', 'Video call at 10:15am') + }) + it('Activity log page is rendered in compact view', () => { + cy.visit('/case/X000001/activity-log?view=compact') + const page = Page.verifyOnPage(ActivityLogPage) + page.getActivity('1').should('contain.text', 'Video call') + page.getActivity('2').should('contain.text', 'Phone call from Eula Schmeler') + page.getActivity('3').should('contain.text', 'Planned appointment') + page.getActivity('4').should('contain.text', 'Initial appointment') + page.getActivity('5').should('contain.text', 'Office appointment') + page.getActivity('6').should('contain.text', 'Phone call') + page.getActivity('7').should('contain.text', 'Office appointment') + page.getActivity('8').should('contain.text', 'Video call') + }) + + it('Activity log page is rendered with without-outcome filter', () => { + cy.visit('/case/X000001/activity-log/national-standard-appointments-without-outcome') + const page = Page.verifyOnPage(ActivityLogPage) + page.getCardHeader('timeline1').should('contain.text', 'Waiting for evidence') + }) + it('Activity log page is rendered with without-outcome filter', () => { + cy.visit('/case/X000001/activity-log/waiting-for-evidence') + const page = Page.verifyOnPage(ActivityLogPage) + page.getCardHeader('timeline1').should('contain.text', 'Waiting for evidence') + }) + it('Activity log page is rendered with complied-appointments filter', () => { + cy.visit('/case/X000001/activity-log/complied-appointments') + const page = Page.verifyOnPage(ActivityLogPage) + page.getCardHeader('timeline1').should('contain.text', 'Complied') + }) + it('Activity log page is rendered with failure to comply filter', () => { + cy.visit('/case/X000001/activity-log/all-failure-to-comply-appointments') + const page = Page.verifyOnPage(ActivityLogPage) + page.getCardHeader('timeline1').should('contain.text', 'Failed to comply') + }) + it('Activity log page is rendered with acceptable absence filter', () => { + cy.visit('/case/X000001/activity-log/acceptable-absence-appointments') + const page = Page.verifyOnPage(ActivityLogPage) + page.getCardHeader('timeline1').should('contain.text', 'Acceptable absence') + }) + it('Activity log page is rendered with rescheduled filter', () => { + cy.visit('/case/X000001/activity-log/all-rescheduled') + const page = Page.verifyOnPage(ActivityLogPage) + page.getCardHeader('timeline1').should('contain.text', 'Rescheduled') + }) + it('Activity log page is rendered with warning letter filter', () => { + cy.visit('/case/X000001/activity-log/warning-letters') + const page = Page.verifyOnPage(ActivityLogPage) + page.getRowData('timeline1', 'enforcement', 'Value').should('contain.text', 'Warning letter sent') + }) +}) diff --git a/integration_tests/pages/activityLog.ts b/integration_tests/pages/activityLog.ts new file mode 100644 index 00000000..ac8624fc --- /dev/null +++ b/integration_tests/pages/activityLog.ts @@ -0,0 +1,9 @@ +import Page, { PageElement } from './page' + +export default class ActivityLogPage extends Page { + constructor() { + super('Activity log') + } + + getActivity = (index: string): PageElement => cy.get(`[data-qa=timeline${index}Card]`) +} diff --git a/integration_tests/pages/page.ts b/integration_tests/pages/page.ts index bc37d572..1901fd21 100644 --- a/integration_tests/pages/page.ts +++ b/integration_tests/pages/page.ts @@ -25,7 +25,8 @@ export default abstract class Page { getTab = (tabName: string): PageElement => cy.get(`[data-qa=${tabName}Tab]`) - getCardHeader = (cardName: string): PageElement => cy.get(`[data-qa=${cardName}Card]`) + getCardHeader = (cardName: string): PageElement => + cy.get(`[class=app-summary-card__header]`).get(`[data-qa=${cardName}Card]`) getRowData = (cardName: string, rowName: string, type: string): PageElement => { return cy.get(`[data-qa=${cardName}Card]`).within(() => cy.get(`[data-qa=${rowName}${type}]`)) diff --git a/server/data/model/schedule.ts b/server/data/model/schedule.ts index d2f34d8b..793e36be 100644 --- a/server/data/model/schedule.ts +++ b/server/data/model/schedule.ts @@ -20,8 +20,8 @@ export interface Activity { isInitial?: boolean isNationalStandard?: boolean rescheduled?: boolean - rescheduledStaff?: boolean, - rescheduledPop?: boolean, + rescheduledStaff?: boolean + rescheduledPop?: boolean didTheyComply?: boolean absentWaitingEvidence?: boolean rearrangeOrCancelReason?: string diff --git a/server/routes/activityLog.ts b/server/routes/activityLog.ts index 71ed6005..720f2c98 100644 --- a/server/routes/activityLog.ts +++ b/server/routes/activityLog.ts @@ -4,7 +4,6 @@ import { v4 } from 'uuid' import asyncMiddleware from '../middleware/asyncMiddleware' import type { Services } from '../services' import MasApiClient from '../data/masApiClient' -import { Schedule } from '../data/model/schedule' export default function activityLogRoutes(router: Router, { hmppsAuthClient }: Services) { const get = (path: string | string[], handler: RequestHandler) => router.get(path, asyncMiddleware(handler)) @@ -67,4 +66,34 @@ export default function activityLogRoutes(router: Router, { hmppsAuthClient }: S crn, }) }) + + get('/case/:crn/activity-log/activity/:id', async (req, res, _next) => { + const { crn, id } = req.params + const token = await hmppsAuthClient.getSystemClientToken(res.locals.user.username) + + await auditService.sendAuditMessage({ + action: 'VIEW_MAS_ACTIVITY_LOG_DETAIL', + who: res.locals.user.username, + subjectId: crn, + subjectType: 'CRN', + correlationId: v4(), + service: 'hmpps-manage-a-supervision-ui', + }) + const masClient = new MasApiClient(token) + const personAppointment = await masClient.getPersonAppointment(crn, id) + const isActivityLog = true + const queryParams: string[] = [] + + const { category } = req.query + if (req.query.view) { + queryParams.push(`view=${req.query.view}`) + } + res.render('pages/schedule/appointment', { + category, + queryParams, + personAppointment, + crn, + isActivityLog, + }) + }) } diff --git a/server/services/index.ts b/server/services/index.ts index 27ebf1ad..5d5504e3 100644 --- a/server/services/index.ts +++ b/server/services/index.ts @@ -13,7 +13,6 @@ export const services = () => { environment: config.env, extraColumns: [], }) - return { applicationInfo, hmppsAuthClient, diff --git a/server/utils/nunjucksSetup.ts b/server/utils/nunjucksSetup.ts index 184d5fbd..8c6a0c06 100644 --- a/server/utils/nunjucksSetup.ts +++ b/server/utils/nunjucksSetup.ts @@ -3,8 +3,10 @@ import path from 'path' import nunjucks from 'nunjucks' import express from 'express' import { - activityLog, activityLogDate, - addressToList, compactActivityLogDate, + activityLog, + activityLogDate, + addressToList, + compactActivityLogDate, dateWithDayAndWithoutYear, dateWithNoDay, dateWithYear, @@ -12,7 +14,7 @@ import { dayOfWeek, deliusDateFormat, deliusDeepLinkUrl, - deliusHomepageUrl, filterEntriesByCategory, + deliusHomepageUrl, fullName, getAppointmentsToAction, getCurrentRisksToThemselves, diff --git a/server/utils/utils.test.ts b/server/utils/utils.test.ts index 8c414ad3..070e4fe4 100644 --- a/server/utils/utils.test.ts +++ b/server/utils/utils.test.ts @@ -2,6 +2,9 @@ import { DateTime } from 'luxon' import { + activityLog, + activityLogDate, + compactActivityLogDate, convertToTitleCase, dateWithDayAndWithoutYear, dateWithYear, @@ -39,11 +42,15 @@ const appointments = [ }, { startDateTime: DateTime.now().minus({ days: 1 }).toString(), + isNationalStandard: true, + isAppointment: true, hasOutcome: true, }, { startDateTime: DateTime.now().minus({ days: 2 }).toString(), + isNationalStandard: true, absentWaitingEvidence: true, + isAppointment: true, }, { startDateTime: DateTime.now().minus({ days: 3 }).toString(), @@ -306,3 +313,30 @@ describe('appointments to action', () => { expect(getAppointmentsToAction(a, b)[0]).toEqual(appointment) }) }) + +describe('compact Activity log date', () => { + it.each([ + ['Null', null, null], + ['gets day', '2024-05-25T09:08:34.123', 'Sat 25 May 2024'], + ])('%s compactActivityLogDate(%s, %s)', (_: string, a: string, expected: string) => { + expect(compactActivityLogDate(a)).toEqual(expected) + }) +}) + +describe('Activity log date', () => { + it.each([ + ['Null', null, null], + ['gets day', '2024-05-25T09:08:34.123', 'Saturday 25 May 2024'], + ])('%s activityLogDate(%s, %s)', (_: string, a: string, expected: string) => { + expect(activityLogDate(a)).toEqual(expected) + }) +}) + +describe('filters activity log', () => { + it.each([ + ['Filters absent awaiting evidence', appointments, 'waiting-for-evidence', appointments[4]], + ['Filters no outcome', appointments, 'national-standard-appointments-without-outcome', appointments[3]], + ])('%s activityLog(%s, %s)', (_: string, a: Activity[], b: string, appointment: Activity) => { + expect(activityLog(a, b)[0]).toEqual(appointment) + }) +}) diff --git a/server/utils/utils.ts b/server/utils/utils.ts index f70dcdeb..f677e12d 100644 --- a/server/utils/utils.ts +++ b/server/utils/utils.ts @@ -278,6 +278,7 @@ export const filterEntriesByCategory = (category: string) => { } export const activityLogDate = (datetimeString: string) => { + if (!datetimeString || isBlank(datetimeString)) return null const date = DateTime.fromISO(datetimeString) if (date.hasSame(DateTime.local(), 'day')) { return 'Today' @@ -289,6 +290,7 @@ export const activityLogDate = (datetimeString: string) => { } export const compactActivityLogDate = (datetimeString: string) => { + if (!datetimeString || isBlank(datetimeString)) return null const date = DateTime.fromISO(datetimeString) if (date.hasSame(DateTime.local(), 'day')) { return 'Today' diff --git a/server/views/pages/activity-log/_appointment-timeline-entry.njk b/server/views/pages/activity-log/_appointment-timeline-entry.njk index efd7a739..77c2f05c 100644 --- a/server/views/pages/activity-log/_appointment-timeline-entry.njk +++ b/server/views/pages/activity-log/_appointment-timeline-entry.njk @@ -5,7 +5,7 @@ {% set titleHtml %} - {{ entry.type }} at {{ entry.startDateTime | govukTime }} on {{ thisDate }} + {{ entry.type }} at {{ entry.startDateTime | govukTime }} on {{ thisDate }} @@ -26,6 +26,7 @@ {% endset %} {{ appSummaryCard({ + attributes: {'data-qa': 'timeline' + loop.index + 'Card'}, titleHtml: titleHtml, classes: 'govuk-!-margin-bottom-2', html: html, diff --git a/server/views/pages/activity-log/_communication-timeline-entry.njk b/server/views/pages/activity-log/_communication-timeline-entry.njk index 4b761c0b..b35ed340 100644 --- a/server/views/pages/activity-log/_communication-timeline-entry.njk +++ b/server/views/pages/activity-log/_communication-timeline-entry.njk @@ -1,5 +1,5 @@ {% set titleHtml %} - {% include './_communication-title.njk' %} at {{ entry.startDateTime | govukTime }} on {{ thisDate }} + {% include './_communication-title.njk' %} at {{ entry.startDateTime | govukTime }} on {{ thisDate }} {% endset %} {% set html %} @@ -7,6 +7,7 @@ {% endset %} {{ appSummaryCard({ + attributes: {'data-qa': 'timeline' + loop.index + 'Card'}, titleHtml: titleHtml, classes: 'govuk-!-margin-bottom-2 app-summary-card--white-header', html: html, diff --git a/server/views/pages/activity-log/_communication-title.njk b/server/views/pages/activity-log/_communication-title.njk index aa21fbcb..66c7cfcf 100644 --- a/server/views/pages/activity-log/_communication-title.njk +++ b/server/views/pages/activity-log/_communication-title.njk @@ -16,5 +16,4 @@ {% if entry.isPhoneCallFromPop === true %} Phone call from {{ personSummary.name | fullName }} {% endif %} - {%- endif -%} \ No newline at end of file diff --git a/server/views/pages/activity-log/_compact-timeline-entry.njk b/server/views/pages/activity-log/_compact-timeline-entry.njk index dd491d7b..8c8271f6 100644 --- a/server/views/pages/activity-log/_compact-timeline-entry.njk +++ b/server/views/pages/activity-log/_compact-timeline-entry.njk @@ -3,13 +3,13 @@ {% set shouldPromptToRecordAnOutcome = (not hasOutcomeBeenConfirmed) and hasAppointmentStartTimePassed %} {% set titleHtml %} -

- +

+ {% if entry.isAppointment === true %} {{ appComplianceTag({ entry: entry, classes: 'govuk-!-margin-left-2', compact: true }) }} {{ entry.type }} at {{ entry.startDateTime | govukTime }} {% elseif entry.isCommunication %} - {% include './_communication-title.njk' %} at {{ entry.startDateTime | govukTime }} + {% include './_communication-title.njk' %} at {{ entry.startDateTime | govukTime }} {% else %} {{ entry.type }} {% endif %} diff --git a/server/views/pages/activity-log/_compact-view.njk b/server/views/pages/activity-log/_compact-view.njk index af3fdf19..4f0b7405 100644 --- a/server/views/pages/activity-log/_compact-view.njk +++ b/server/views/pages/activity-log/_compact-view.njk @@ -10,14 +10,13 @@ {% set lastDate = lastEntry.startDateTime | compactActivityLogDate %} {% set thisDate = entry.startDateTime | compactActivityLogDate %} {% if lastDate != thisDate %} - + {{ thisDate }}

- + + diff --git a/server/views/pages/activity-log/_filters.njk b/server/views/pages/activity-log/_filters.njk index c6a36dcc..fe5dd78a 100644 --- a/server/views/pages/activity-log/_filters.njk +++ b/server/views/pages/activity-log/_filters.njk @@ -4,7 +4,6 @@ text: 'Add to log', href: '/case/' + crn + '/handoff/delius' }) }} - {% if category %}

Remove all filters @@ -26,82 +25,5 @@

  • Rescheduled
  • Warning letters
  • - - {% if data.features.filters %} - {{ govukButton({ - html: 'Apply filters', - classes: 'govuk-button--secondary', - href: '#' - }) }} - - {{ govukCheckboxes({ - classes: "govuk-checkboxes--small", - fieldset: { - legend: { - text: "Type of contact", - classes: "govuk-fieldset__legend--s" - } - }, - items: [ - { - text: "Appointment" - }, - { - text: "Communication" - }, - { - text: "Notes" - } - ] - } | decorateFormAttributes(['contact-filter-type'])) }} - - {{ govukCheckboxes({ - classes: "govuk-checkboxes--small", - fieldset: { - legend: { - text: "Appointments", - classes: "govuk-fieldset__legend--s" - } - }, - items: [ - { - text: "Complied" - }, - { - text: "Failed to comply" - }, - { - text: "Absent" - }, - { - text: "RAR" - }, - { - text: "No notes" - } - ] - } | decorateFormAttributes(['contact-filter-type'])) }} - - {{ govukCheckboxes({ - classes: "govuk-checkboxes--small", - fieldset: { - legend: { - text: "Communications", - classes: "govuk-fieldset__legend--s" - } - }, - items: [ - { - text: "Phone call" - }, - { - text: "Text message" - }, - { - text: "Email" - } - ] - } | decorateFormAttributes(['contact-filter-type'])) }} - {% endif %} diff --git a/server/views/pages/activity-log/_other-timeline-entry.njk b/server/views/pages/activity-log/_other-timeline-entry.njk index 44883f17..5e933059 100644 --- a/server/views/pages/activity-log/_other-timeline-entry.njk +++ b/server/views/pages/activity-log/_other-timeline-entry.njk @@ -1,5 +1,5 @@ {% set titleHtml %} - + {{ entry.type }} on {{ thisDate }} {% endset %} @@ -31,6 +31,7 @@ {% endset %} {{ appSummaryCard({ + attributes: {'data-qa': 'timeline' + loop.index + 'Card' }, titleHtml: titleHtml, classes: 'govuk-!-margin-bottom-2 app-summary-card--white-header', html: html, diff --git a/server/views/pages/activity-log/_timeline-notes.njk b/server/views/pages/activity-log/_timeline-notes.njk index 414dc3b2..3aef1d8e 100644 --- a/server/views/pages/activity-log/_timeline-notes.njk +++ b/server/views/pages/activity-log/_timeline-notes.njk @@ -27,39 +27,40 @@ rows: [ { key: { - text: 'Description' + html: 'Description' }, value: { - text: entry.description + html: '' + entry.description + '' } } if entry.description, { key: { - text: 'RAR activity' + html: 'RAR activity' }, value: { - text: entry.rarCategory + html: '' + entry.rarCategory + '' } } if entry.rarCategory, { - key: { text: "Reschedule" }, - value: { text: "Requested by " + personSummary.name | fullName if entry.rescheduledPop == true else entry.rescheduledBy | fullName } + key: { html: 'Reschedule'}, + value: { html: 'Requested by ' + personSummary.name | fullName + '' if entry.rescheduledPop == true + else 'Requested by ' + entry.rescheduledBy | fullName + 'Reason for not complying' }, + value: { html: ' + entry.nonComplianceReason + '' } } if entry.didTheyComply === false, { - key: { text: "Reason for absence" }, - value: { text: entry.acceptableAbsenceReason if entry.acceptableAbsence === true } + key: { html: 'Reason for absence' }, + value: { html: '' + entry.acceptableAbsenceReason + '' if entry.acceptableAbsence === true } } if entry.acceptableAbsenceReason, { - key: { text: "Enforcement" }, - value: { html: entry.action } + key: { html: 'Enforcement' }, + value: { html: '' + entry.action + ''} } if entry.action, { - key: { text: "Documents" }, - value: { html: documents } + key: { html: 'Documents' }, + value: { html: '' + documents + '' } } if entry.documents.length > 0 } }) }} diff --git a/server/views/pages/schedule/appointment.njk b/server/views/pages/schedule/appointment.njk index d7a005f2..fc8a3e1e 100644 --- a/server/views/pages/schedule/appointment.njk +++ b/server/views/pages/schedule/appointment.njk @@ -1,5 +1,9 @@ {% extends "../../partials/layout.njk" %} {% set appointment = personAppointment.appointment %} + +{% set extraBreadcrumb = '?' + queryParams.join('&') if queryParams.length > 0 else '' %} +{% set category = '/' + category + '/' + extraBreadcrumb if category else extraBreadcrumb %} + {% block beforeContent %} {{ govukBreadcrumbs({ items: [ @@ -12,8 +16,8 @@ href: "/case/" + crn }, { - text: "Schedule", - href: "/case/" + crn + "/schedule" + text: "Schedule" if not isActivityLog else "Activity log", + href: "/case/" + crn + "/schedule" if not isActivityLog else "/case/" + crn + "/activity-log" + category }, { text: appointment.type diff --git a/wiremock/mappings/X000001-activity-log.json b/wiremock/mappings/X000001-activity-log.json index ef966a9b..4f3747dd 100644 --- a/wiremock/mappings/X000001-activity-log.json +++ b/wiremock/mappings/X000001-activity-log.json @@ -232,7 +232,8 @@ "Content-Type": "application/json" } } - },{ + }, + { "request": { "urlPattern": "/mas/schedule/X000001/appointment/11", "method": "GET" @@ -376,13 +377,13 @@ "status": 200, "jsonBody": { "personSummary": { - "name": { - "forename": "Eula", - "surname": "Schmeler" + "name": { + "forename": "Eula", + "surname": "Schmeler" + }, + "crn": "X000001", + "dateOfBirth": "1979-08-18" }, - "crn": "X000001", - "dateOfBirth": "1979-08-18" - }, "appointment": { "id": 14, "type": "Phone call", @@ -422,12 +423,12 @@ "status": 200, "jsonBody": { "personSummary": { - "name": { - "forename": "Eula", - "surname": "Schmeler" - }, - "crn": "X000001", - "dateOfBirth": "1979-08-18" + "name": { + "forename": "Eula", + "surname": "Schmeler" + }, + "crn": "X000001", + "dateOfBirth": "1979-08-18" }, "appointment": { "id": 15, @@ -465,27 +466,37 @@ "response": { "status": 200, "jsonBody": { - "id": 16, - "type": "Office appointment", - "startDateTime": "2024-02-21T10:15:00.382936Z[Europe/London]", - "endDateTime": "2024-02-21T10:30:00.382936Z[Europe/London]", - "rarToolKit": "Choices and Changes", - "isSensitive": false, - "hasOutcome": false, - "wasAbsent": true, - "nonComplianceReason": "Was very argumentative and left the appointment", - "didTheyComply": false, - "isAppointment": true, - "isNationalStandard": true, - "notes": "Some notes", - "lastUpdated": "2023-03-20", - "officerName": { - "forename": "Terry", - "surname": "Jones" + "personSummary": { + "name": { + "forename": "Eula", + "surname": "Schmeler" + }, + "crn": "X000001", + "dateOfBirth": "1979-08-18" }, - "lastUpdatedBy": { - "forename": "Paul", - "surname": "Smith" + "appointment": { + "id": 16, + "type": "Office appointment", + "startDateTime": "2024-02-21T10:15:00.382936Z[Europe/London]", + "endDateTime": "2024-02-21T10:30:00.382936Z[Europe/London]", + "rarToolKit": "Choices and Changes", + "isSensitive": false, + "hasOutcome": false, + "wasAbsent": true, + "nonComplianceReason": "Was very argumentative and left the appointment", + "didTheyComply": false, + "isAppointment": true, + "isNationalStandard": true, + "notes": "Some notes", + "lastUpdated": "2023-03-20", + "officerName": { + "forename": "Terry", + "surname": "Jones" + }, + "lastUpdatedBy": { + "forename": "Paul", + "surname": "Smith" + } } }, "headers": {