Refactor to pull all text enteries into single location
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
import { CardHeader } from './Card'
|
||||
import { skills } from '@/data/skills'
|
||||
import { useDetailPanel } from '@/contexts/DetailPanelContext'
|
||||
import { getSkillsUICopy } from '@/lib/profile-content'
|
||||
import type { SkillMedication, SkillCategory } from '@/types/pmr'
|
||||
|
||||
const iconMap: Record<string, LucideIcon> = {
|
||||
@@ -21,19 +22,14 @@ const iconMap: Record<string, LucideIcon> = {
|
||||
|
||||
const SKILLS_PER_CATEGORY = 4
|
||||
|
||||
const categoryConfig: { id: SkillCategory; label: string }[] = [
|
||||
{ id: 'Technical', label: 'Technical' },
|
||||
{ id: 'Domain', label: 'Healthcare Domain' },
|
||||
{ id: 'Leadership', label: 'Strategic & Leadership' },
|
||||
]
|
||||
|
||||
interface SkillRowProps {
|
||||
skill: SkillMedication
|
||||
yearsSuffix: string
|
||||
onClick: () => void
|
||||
onHighlight?: (id: string | null) => void
|
||||
}
|
||||
|
||||
function SkillRow({ skill, onClick, onHighlight }: SkillRowProps) {
|
||||
function SkillRow({ skill, yearsSuffix, onClick, onHighlight }: SkillRowProps) {
|
||||
const IconComponent = iconMap[skill.icon]
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
@@ -106,7 +102,7 @@ function SkillRow({ skill, onClick, onHighlight }: SkillRowProps) {
|
||||
fontFamily: '"Geist Mono", monospace',
|
||||
}}
|
||||
>
|
||||
{skill.frequency} · {skill.yearsOfExperience} yrs
|
||||
{skill.frequency} · {skill.yearsOfExperience} {yearsSuffix}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -135,6 +131,9 @@ interface CategorySectionProps {
|
||||
label: string
|
||||
categoryId: SkillCategory
|
||||
skills: SkillMedication[]
|
||||
itemCountSuffix: string
|
||||
yearsSuffix: string
|
||||
viewAllLabel: string
|
||||
onSkillClick: (skill: SkillMedication) => void
|
||||
onViewAll: (category: SkillCategory) => void
|
||||
isFirst: boolean
|
||||
@@ -145,6 +144,9 @@ function CategorySection({
|
||||
label,
|
||||
categoryId,
|
||||
skills: categorySkills,
|
||||
itemCountSuffix,
|
||||
yearsSuffix,
|
||||
viewAllLabel,
|
||||
onSkillClick,
|
||||
onViewAll,
|
||||
isFirst,
|
||||
@@ -190,7 +192,7 @@ function CategorySection({
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{categorySkills.length} items
|
||||
{categorySkills.length} {itemCountSuffix}
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||
@@ -198,6 +200,7 @@ function CategorySection({
|
||||
<SkillRow
|
||||
key={skill.id}
|
||||
skill={skill}
|
||||
yearsSuffix={yearsSuffix}
|
||||
onClick={() => onSkillClick(skill)}
|
||||
onHighlight={onNodeHighlight}
|
||||
/>
|
||||
@@ -228,9 +231,9 @@ function CategorySection({
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.color = 'var(--accent)'
|
||||
}}
|
||||
aria-label={`View all ${categorySkills.length} ${label} skills`}
|
||||
aria-label={`${viewAllLabel} ${categorySkills.length} ${label} skills`}
|
||||
>
|
||||
View all ({categorySkills.length})
|
||||
{viewAllLabel} ({categorySkills.length})
|
||||
<ChevronRight size={12} />
|
||||
</button>
|
||||
)}
|
||||
@@ -244,8 +247,9 @@ interface RepeatMedicationsSubsectionProps {
|
||||
|
||||
export function RepeatMedicationsSubsection({ onNodeHighlight }: RepeatMedicationsSubsectionProps) {
|
||||
const { openPanel } = useDetailPanel()
|
||||
const skillsCopy = getSkillsUICopy()
|
||||
|
||||
const groupedSkills = categoryConfig.map(({ id, label }) => ({
|
||||
const groupedSkills = skillsCopy.categories.map(({ id, label }) => ({
|
||||
id,
|
||||
label,
|
||||
skills: skills
|
||||
@@ -265,8 +269,8 @@ export function RepeatMedicationsSubsection({ onNodeHighlight }: RepeatMedicatio
|
||||
<div>
|
||||
<CardHeader
|
||||
dotColor="amber"
|
||||
title="REPEAT MEDICATIONS"
|
||||
rightText="Active prescriptions"
|
||||
title={skillsCopy.sectionTitle}
|
||||
rightText={skillsCopy.rightText}
|
||||
/>
|
||||
<div className="medications-grid">
|
||||
{groupedSkills.map((group) => (
|
||||
@@ -275,6 +279,9 @@ export function RepeatMedicationsSubsection({ onNodeHighlight }: RepeatMedicatio
|
||||
label={group.label}
|
||||
categoryId={group.id}
|
||||
skills={group.skills}
|
||||
itemCountSuffix={skillsCopy.itemCountSuffix}
|
||||
yearsSuffix={skillsCopy.yearsSuffix}
|
||||
viewAllLabel={skillsCopy.viewAllLabel}
|
||||
onSkillClick={handleSkillClick}
|
||||
onViewAll={handleViewAll}
|
||||
isFirst
|
||||
|
||||
+17
-15
@@ -17,6 +17,7 @@ import cvmisLogo from '../../cvmis-logo.svg'
|
||||
import { patient } from '@/data/patient'
|
||||
import { tags } from '@/data/tags'
|
||||
import { alerts } from '@/data/alerts'
|
||||
import { getSidebarCopy } from '@/lib/profile-content'
|
||||
import type { Tag, Alert } from '@/types/pmr'
|
||||
|
||||
interface SidebarProps {
|
||||
@@ -163,6 +164,7 @@ function AlertFlag({ alert }: AlertFlagProps) {
|
||||
}
|
||||
|
||||
export default function Sidebar({ activeSection, onNavigate, onSearchClick }: SidebarProps) {
|
||||
const sidebarCopy = getSidebarCopy()
|
||||
const [isDesktop, setIsDesktop] = useState(() => window.matchMedia('(min-width: 1024px)').matches)
|
||||
const [isMobileExpanded, setIsMobileExpanded] = useState(false)
|
||||
|
||||
@@ -257,7 +259,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
{isExpanded && <span style={{ fontSize: '12px', fontWeight: 600 }}>Menu</span>}
|
||||
{isExpanded && <span style={{ fontSize: '12px', fontWeight: 600 }}>{sidebarCopy.menuLabel}</span>}
|
||||
{isExpanded ? <X size={17} strokeWidth={2.4} /> : <Menu size={18} strokeWidth={2.4} />}
|
||||
</button>
|
||||
)}
|
||||
@@ -287,7 +289,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
type="button"
|
||||
onClick={onSearchClick}
|
||||
className="sidebar-control"
|
||||
aria-label="Search. Press Control plus K"
|
||||
aria-label={sidebarCopy.searchAriaLabel}
|
||||
style={{
|
||||
width: '100%',
|
||||
minHeight: '44px',
|
||||
@@ -305,7 +307,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
>
|
||||
<Search size={16} style={{ color: 'var(--text-tertiary)', flexShrink: 0 }} aria-hidden="true" />
|
||||
<span style={{ flex: 1, textAlign: 'left', fontSize: '13px' }}>
|
||||
Search
|
||||
{sidebarCopy.searchLabel}
|
||||
</span>
|
||||
<kbd
|
||||
style={{
|
||||
@@ -318,7 +320,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
Ctrl+K
|
||||
{sidebarCopy.searchShortcut}
|
||||
</kbd>
|
||||
</button>
|
||||
|
||||
@@ -326,7 +328,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
|
||||
|
||||
|
||||
<SectionTitle>Patient Data</SectionTitle>
|
||||
<SectionTitle>{sidebarCopy.sectionTitle}</SectionTitle>
|
||||
|
||||
<div
|
||||
style={{
|
||||
@@ -367,7 +369,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
marginTop: '2px',
|
||||
}}
|
||||
>
|
||||
Pharmacy Data Technologist
|
||||
{sidebarCopy.roleTitle}
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -387,7 +389,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
padding: '4px 0',
|
||||
}}
|
||||
>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>GPhC No.</span>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>{sidebarCopy.gphcLabel}</span>
|
||||
<span
|
||||
style={{
|
||||
color: 'var(--text-primary)',
|
||||
@@ -410,7 +412,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
padding: '4px 0',
|
||||
}}
|
||||
>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>Education</span>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>{sidebarCopy.educationLabel}</span>
|
||||
<span style={{ color: 'var(--text-primary)', fontWeight: 500, textAlign: 'right' }}>
|
||||
{patient.qualification}
|
||||
</span>
|
||||
@@ -425,7 +427,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
padding: '4px 0',
|
||||
}}
|
||||
>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>Location</span>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>{sidebarCopy.locationLabel}</span>
|
||||
<span style={{ color: 'var(--text-primary)', fontWeight: 500, textAlign: 'right' }}>
|
||||
{patient.address}
|
||||
</span>
|
||||
@@ -440,7 +442,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
padding: '4px 0',
|
||||
}}
|
||||
>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>Phone</span>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>{sidebarCopy.phoneLabel}</span>
|
||||
<a
|
||||
href={`tel:${patient.phone}`}
|
||||
style={{
|
||||
@@ -465,7 +467,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
padding: '4px 0',
|
||||
}}
|
||||
>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>Email</span>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>{sidebarCopy.emailLabel}</span>
|
||||
<a
|
||||
href={`mailto:${patient.email}`}
|
||||
style={{
|
||||
@@ -490,7 +492,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
padding: '4px 0',
|
||||
}}
|
||||
>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>Registered</span>
|
||||
<span style={{ color: 'var(--text-tertiary)', fontWeight: 400 }}>{sidebarCopy.registeredLabel}</span>
|
||||
<span style={{ color: 'var(--text-primary)', fontWeight: 500, textAlign: 'right' }}>
|
||||
{patient.registrationYear}
|
||||
</span>
|
||||
@@ -500,7 +502,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
)}
|
||||
|
||||
<section>
|
||||
{isExpanded && <SectionTitle>Navigation</SectionTitle>}
|
||||
{isExpanded && <SectionTitle>{sidebarCopy.navigationTitle}</SectionTitle>}
|
||||
<nav aria-label="Sidebar navigation" style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
|
||||
{navSections.map((section) => {
|
||||
const isActive = activeSection === section.id
|
||||
@@ -546,7 +548,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
{isExpanded && (
|
||||
<>
|
||||
<section style={{ paddingTop: '8px' }}>
|
||||
<SectionTitle>Tags</SectionTitle>
|
||||
<SectionTitle>{sidebarCopy.tagsTitle}</SectionTitle>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '5px' }}>
|
||||
{tags.map((tag) => (
|
||||
<TagPill key={tag.label} tag={tag} />
|
||||
@@ -555,7 +557,7 @@ export default function Sidebar({ activeSection, onNavigate, onSearchClick }: Si
|
||||
</section>
|
||||
|
||||
<section style={{ padding: '8px 0 4px' }}>
|
||||
<SectionTitle>Alerts / Highlights</SectionTitle>
|
||||
<SectionTitle>{sidebarCopy.alertsTitle}</SectionTitle>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
|
||||
{alerts.map((alert, index) => (
|
||||
<AlertFlag key={index} alert={alert} />
|
||||
|
||||
@@ -3,6 +3,7 @@ import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { ChevronRight } from 'lucide-react'
|
||||
import { useDetailPanel } from '@/contexts/DetailPanelContext'
|
||||
import { timelineEntities, timelineConsultations } from '@/data/timeline'
|
||||
import { getExperienceEducationUICopy } from '@/lib/profile-content'
|
||||
import type { TimelineEntity } from '@/types/pmr'
|
||||
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||
@@ -33,8 +34,9 @@ function TimelineInterventionItem({
|
||||
onViewFull,
|
||||
onHighlight,
|
||||
}: TimelineInterventionItemProps) {
|
||||
const experienceEducationCopy = getExperienceEducationUICopy()
|
||||
const isEducation = entity.kind === 'education'
|
||||
const interventionLabel = isEducation ? 'Education' : 'Employment'
|
||||
const interventionLabel = isEducation ? experienceEducationCopy.educationLabel : experienceEducationCopy.employmentLabel
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(e: React.KeyboardEvent) => {
|
||||
@@ -284,7 +286,7 @@ function TimelineInterventionItem({
|
||||
e.currentTarget.style.opacity = '1'
|
||||
}}
|
||||
>
|
||||
View full record
|
||||
{experienceEducationCopy.viewFullRecordLabel}
|
||||
<ChevronRight size={12} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useState, useCallback } from 'react'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { ChevronRight } from 'lucide-react'
|
||||
import { CardHeader } from './Card'
|
||||
import { consultations } from '@/data/consultations'
|
||||
import { timelineConsultations } from '@/data/timeline'
|
||||
import { useDetailPanel } from '@/contexts/DetailPanelContext'
|
||||
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||
@@ -15,7 +15,7 @@ function hexToRgba(hex: string, opacity: number): string {
|
||||
}
|
||||
|
||||
interface RoleItemProps {
|
||||
consultation: typeof consultations[0]
|
||||
consultation: typeof timelineConsultations[0]
|
||||
isExpanded: boolean
|
||||
isHighlightedFromGraph: boolean
|
||||
onToggle: () => void
|
||||
@@ -279,7 +279,7 @@ export function WorkExperienceSubsection({ onNodeHighlight, highlightedRoleId }:
|
||||
}, [])
|
||||
|
||||
const handleViewFull = useCallback(
|
||||
(consultation: typeof consultations[0]) => {
|
||||
(consultation: typeof timelineConsultations[0]) => {
|
||||
openPanel({ type: 'career-role', consultation })
|
||||
},
|
||||
[openPanel],
|
||||
@@ -287,9 +287,9 @@ export function WorkExperienceSubsection({ onNodeHighlight, highlightedRoleId }:
|
||||
|
||||
return (
|
||||
<div>
|
||||
<CardHeader dotColor="teal" title="WORK EXPERIENCE" rightText={`${consultations.length} roles`} />
|
||||
<CardHeader dotColor="teal" title="WORK EXPERIENCE" rightText={`${timelineConsultations.length} roles`} />
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
|
||||
{consultations.map((c) => (
|
||||
{timelineConsultations.map((c) => (
|
||||
<RoleItem
|
||||
key={c.id}
|
||||
consultation={c}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from 'lucide-react'
|
||||
import { skills } from '@/data/skills'
|
||||
import { useDetailPanel } from '@/contexts/DetailPanelContext'
|
||||
import { getSkillsUICopy } from '@/lib/profile-content'
|
||||
import type { SkillMedication, SkillCategory } from '@/types/pmr'
|
||||
|
||||
const iconMap: Record<string, LucideIcon> = {
|
||||
@@ -18,12 +19,6 @@ const iconMap: Record<string, LucideIcon> = {
|
||||
MessageSquare, UserPlus, RefreshCw, Calculator, Presentation,
|
||||
}
|
||||
|
||||
const categoryConfig: { id: SkillCategory; label: string }[] = [
|
||||
{ id: 'Technical', label: 'Technical' },
|
||||
{ id: 'Domain', label: 'Healthcare Domain' },
|
||||
{ id: 'Leadership', label: 'Strategic & Leadership' },
|
||||
]
|
||||
|
||||
interface SkillsAllDetailProps {
|
||||
category?: SkillCategory
|
||||
}
|
||||
@@ -31,6 +26,7 @@ interface SkillsAllDetailProps {
|
||||
export function SkillsAllDetail({ category }: SkillsAllDetailProps) {
|
||||
const { openPanel } = useDetailPanel()
|
||||
const categoryRefs = useRef<Record<string, HTMLDivElement | null>>({})
|
||||
const skillsCopy = getSkillsUICopy()
|
||||
|
||||
// Scroll to highlighted category on mount
|
||||
useEffect(() => {
|
||||
@@ -39,7 +35,7 @@ export function SkillsAllDetail({ category }: SkillsAllDetailProps) {
|
||||
}
|
||||
}, [category])
|
||||
|
||||
const groupedSkills = categoryConfig.map(({ id, label }) => ({
|
||||
const groupedSkills = skillsCopy.categories.map(({ id, label }) => ({
|
||||
id,
|
||||
label,
|
||||
skills: skills
|
||||
@@ -91,17 +87,17 @@ export function SkillsAllDetail({ category }: SkillsAllDetailProps) {
|
||||
background: 'var(--border-light)',
|
||||
}}
|
||||
/>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '10px',
|
||||
color: 'var(--text-tertiary)',
|
||||
fontFamily: '"Geist Mono", monospace',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{group.skills.length} items
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '10px',
|
||||
color: 'var(--text-tertiary)',
|
||||
fontFamily: '"Geist Mono", monospace',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{group.skills.length} {skillsCopy.itemCountSuffix}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Skill rows */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
|
||||
@@ -109,6 +105,7 @@ export function SkillsAllDetail({ category }: SkillsAllDetailProps) {
|
||||
<SkillRow
|
||||
key={skill.id}
|
||||
skill={skill}
|
||||
yearsSuffix={skillsCopy.yearsSuffix}
|
||||
onClick={() => handleSkillClick(skill)}
|
||||
/>
|
||||
))}
|
||||
@@ -122,10 +119,11 @@ export function SkillsAllDetail({ category }: SkillsAllDetailProps) {
|
||||
|
||||
interface SkillRowProps {
|
||||
skill: SkillMedication
|
||||
yearsSuffix: string
|
||||
onClick: () => void
|
||||
}
|
||||
|
||||
function SkillRow({ skill, onClick }: SkillRowProps) {
|
||||
function SkillRow({ skill, yearsSuffix, onClick }: SkillRowProps) {
|
||||
const IconComponent = iconMap[skill.icon]
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
@@ -198,7 +196,7 @@ function SkillRow({ skill, onClick }: SkillRowProps) {
|
||||
fontFamily: '"Geist Mono", monospace',
|
||||
}}
|
||||
>
|
||||
{skill.frequency} · {skill.yearsOfExperience} yrs
|
||||
{skill.frequency} · {skill.yearsOfExperience} {yearsSuffix}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ParentSection } from '../ParentSection'
|
||||
import { kpis } from '@/data/kpis'
|
||||
import type { KPI } from '@/types/pmr'
|
||||
import { useDetailPanel } from '@/contexts/DetailPanelContext'
|
||||
import { getLatestResultsCopy, getProfileSectionTitle, getProfileSummaryText } from '@/lib/profile-content'
|
||||
|
||||
const colorMap: Record<KPI['colorVariant'], string> = {
|
||||
green: '#059669',
|
||||
@@ -18,6 +19,7 @@ interface MetricCardProps {
|
||||
|
||||
function MetricCard({ kpi }: MetricCardProps) {
|
||||
const { openPanel } = useDetailPanel()
|
||||
const latestResultsCopy = getLatestResultsCopy()
|
||||
|
||||
const handleClick = () => {
|
||||
openPanel({ type: 'kpi', kpi })
|
||||
@@ -102,7 +104,7 @@ function MetricCard({ kpi }: MetricCardProps) {
|
||||
fontFamily: 'var(--font-geist-mono)',
|
||||
}}
|
||||
>
|
||||
Click to view evidence
|
||||
{latestResultsCopy.evidenceCta}
|
||||
<ChevronRight size={12} />
|
||||
</div>
|
||||
</button>
|
||||
@@ -110,6 +112,10 @@ function MetricCard({ kpi }: MetricCardProps) {
|
||||
}
|
||||
|
||||
export function PatientSummaryTile() {
|
||||
const summaryText = getProfileSummaryText()
|
||||
const latestResultsCopy = getLatestResultsCopy()
|
||||
const sectionTitle = getProfileSectionTitle()
|
||||
|
||||
const profileTextStyles: React.CSSProperties = {
|
||||
fontSize: '15px',
|
||||
lineHeight: '1.65',
|
||||
@@ -123,22 +129,14 @@ export function PatientSummaryTile() {
|
||||
}
|
||||
|
||||
return (
|
||||
<ParentSection title="Patient Summary" tileId="patient-summary">
|
||||
<ParentSection title={sectionTitle} tileId="patient-summary">
|
||||
{/* Profile text */}
|
||||
<div style={profileTextStyles}>
|
||||
<strong>Healthcare leader</strong> combining clinical pharmacy expertise with proficiency in{' '}
|
||||
<strong>Python, SQL, and data analytics</strong>, self-taught over the past decade through a drive to find root causes in data and build the most efficient solutions to complex problems. Currently{' '}
|
||||
<strong>leading population health analytics for NHS Norfolk & Waveney ICB</strong>, serving a population of 1.2 million. Experienced in working with messy, real-world prescribing data at scale to deliver actionable insights—from{' '}
|
||||
<strong>financial scenario modelling</strong> and <strong>pharmaceutical rebate negotiation</strong> to{' '}
|
||||
<strong>algorithm design</strong> and <strong>population-level pathway development</strong>. Proven track record of identifying and prioritising efficiency programmes worth{' '}
|
||||
<strong>£14.6M+</strong> through automated, data-driven analysis. Skilled at translating complex clinical, financial, and analytical requirements into clear recommendations for{' '}
|
||||
<strong>executive stakeholders</strong>.
|
||||
</div>
|
||||
<div style={profileTextStyles}>{summaryText}</div>
|
||||
|
||||
{/* Latest Results subsection */}
|
||||
<div style={{ marginTop: '28px' }}>
|
||||
<div className="latest-results-header">
|
||||
<CardHeader dotColor="teal" title="LATEST RESULTS (CLICK TO VIEW FULL REFERENCE RANGE)" rightText="Updated May 2025" />
|
||||
<CardHeader dotColor="teal" title={latestResultsCopy.title} rightText={latestResultsCopy.rightText} />
|
||||
<p
|
||||
style={{
|
||||
margin: 0,
|
||||
@@ -147,7 +145,7 @@ export function PatientSummaryTile() {
|
||||
fontFamily: 'var(--font-geist-mono)',
|
||||
}}
|
||||
>
|
||||
Select a metric to inspect methodology, impact, and outcomes.
|
||||
{latestResultsCopy.helperText}
|
||||
</p>
|
||||
</div>
|
||||
<div className="latest-results-grid" style={kpiGridStyles}>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { Consultation } from '@/types/pmr'
|
||||
import { timelineConsultations } from '@/data/timeline'
|
||||
|
||||
// Compatibility export for existing consultation consumers.
|
||||
export const consultations: Consultation[] = timelineConsultations
|
||||
+36
-36
@@ -7,17 +7,17 @@ export const kpis: KPI[] = [
|
||||
label: 'Budget Oversight',
|
||||
sub: 'NHS prescribing',
|
||||
colorVariant: 'green',
|
||||
explanation: 'Managed the ICB\'s total prescribing budget with sophisticated forecasting models identifying cost pressures and enabling proactive financial planning across Norfolk & Waveney.',
|
||||
explanation: 'Full analytical accountability for the ICB\'s total prescribing budget, with sophisticated forecasting models identifying cost pressures and enabling proactive financial planning across Norfolk & Waveney.',
|
||||
story: {
|
||||
context: 'Total prescribing budget for NHS Norfolk & Waveney ICB, covering primary care prescriptions for a population of 1.2 million across the integrated care system.',
|
||||
role: 'Managed with sophisticated forecasting models, identifying cost pressures and enabling proactive financial planning. Full analytical accountability to ICB board for budget oversight and variance analysis.',
|
||||
context: 'Total primary care prescribing budget for NHS Norfolk & Waveney ICB, covering prescriptions for a population of 1.2 million across the integrated care system. Expenditure driven by GP prescribing patterns, NICE technology appraisal mandates, patent expiry timelines, and pharmaceutical pricing changes.',
|
||||
role: 'Full analytical accountability to ICB board for budget oversight and variance analysis. Built sophisticated forecasting models integrating prescribing trend data, cost pressure drivers, and efficiency programme trajectories. Delivered monthly financial reporting to the executive team and presented budget position to Chief Medical Officer bimonthly.',
|
||||
outcomes: [
|
||||
'Sophisticated forecasting models identifying cost pressures ahead of time',
|
||||
'Proactive financial planning enabled across the system',
|
||||
'Interactive dashboard tracking expenditure patterns in real-time',
|
||||
'Monthly variance analysis and financial reporting to executive team',
|
||||
'Forecasting models identifying cost pressures ahead of materialisation',
|
||||
'Proactive financial planning embedded across the medicines optimisation programme',
|
||||
'Interactive Power BI dashboard tracking expenditure patterns against plan',
|
||||
'Monthly variance analysis and financial reporting to executive team and ICB board',
|
||||
],
|
||||
period: 'Jul 2024 — Present',
|
||||
period: 'Jul 2024 – Present',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -26,36 +26,36 @@ export const kpis: KPI[] = [
|
||||
label: 'Efficiency Savings',
|
||||
sub: 'Identified & tracked',
|
||||
colorVariant: 'amber',
|
||||
explanation: 'Identified and prioritised a £14.6M efficiency programme through comprehensive data analysis; achieved over-target performance through targeted, evidence-based interventions across the integrated care system.',
|
||||
explanation: 'Identified and prioritised a £14.6M efficiency programme through comprehensive prescribing data analysis; achieved over-target performance through targeted, evidence-based interventions across the integrated care system.',
|
||||
story: {
|
||||
context: 'System-wide efficiency programme identified through comprehensive analysis of real-world prescribing data, targeting high-cost medicines with cost-effective alternatives and evidence-based switching opportunities.',
|
||||
role: 'Led data analysis to identify, prioritise, and track the efficiency programme. Built automated analysis tools to compress months of manual work into days, enabling targeted interventions across the integrated care system.',
|
||||
context: 'System-wide efficiency programme identified through comprehensive analysis of real-world GP prescribing data, targeting high-cost medicines with cost-effective alternatives, generic switching opportunities, and evidence-based formulary optimisation across all practices in the integrated care system.',
|
||||
role: 'Led the data analysis to identify, quantify, and prioritise efficiency opportunities. Built automated analytical tools compressing months of manual work into days. Designed the programme structure, set targets, and tracked delivery against plan. Created a novel GP incentive scheme linking payment to demonstrated savings.',
|
||||
outcomes: [
|
||||
'Identified £14.6M efficiency programme through automated data analysis',
|
||||
'Identified and prioritised £14.6M efficiency programme through automated prescribing data analysis',
|
||||
'Achieved over-target performance by October 2025',
|
||||
'Built Python switching algorithm identifying 14,000 patients and £2.6M savings',
|
||||
'Automated incentive scheme analysis with novel GP payment system',
|
||||
'Built Python-based switching algorithm identifying 14,000 patients and £2.6M in annual savings',
|
||||
'Automated incentive scheme with novel GP payment system: 50% prescribing reduction in 2 months',
|
||||
],
|
||||
period: 'May 2025 — Nov 2025',
|
||||
period: 'May 2025 – Nov 2025',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'years',
|
||||
value: '9+',
|
||||
label: 'Years in NHS',
|
||||
sub: 'Since 2016',
|
||||
id: 'algorithm',
|
||||
value: '£2.6M',
|
||||
label: 'Algorithm Savings',
|
||||
sub: '14,000 patients in 3 days',
|
||||
colorVariant: 'teal',
|
||||
explanation: 'Continuous NHS service since August 2016, progressing from community pharmacy through prescribing data analysis to system-level population health data leadership.',
|
||||
explanation: 'Built a Python-based switching algorithm using real-world GP prescribing data to automatically identify patients on expensive drugs suitable for cost-effective alternatives, compressing months of manual analysis into 3 days.',
|
||||
story: {
|
||||
context: 'Career journey spanning community pharmacy, hospital interface, and system-level population health analytics across NHS Norfolk & Waveney, demonstrating continuous progression and expanding scope of impact.',
|
||||
role: 'Progressed from frontline community pharmacy through prescribing data analysis roles to system-level population health leadership, consistently taking on greater analytical and strategic responsibility across the integrated care system.',
|
||||
context: 'The annual medicines switching scheme previously required the optimisation team to spend months manually searching for opportunities across hundreds of thousands of prescriptions, identifying generic availability, price changes, and clinically appropriate alternatives one drug at a time.',
|
||||
role: 'Designed and built a Python algorithm ingesting real-world GP prescribing data, cross-referencing dm+d product information, clinical safety rules, and cost-effectiveness thresholds to automatically identify the optimal set of patient switches for maximum savings with minimum clinical intervention. Created the accompanying GP incentive payment system linking rewards to delivered savings.',
|
||||
outcomes: [
|
||||
'Community pharmacy foundation: patient care and medicines optimisation (2016-2022)',
|
||||
'High-cost drugs and interface: NICE implementation and pathway development (2022-2024)',
|
||||
'Population health leadership: data-driven decision making at system scale (2024-present)',
|
||||
'Self-taught Python, SQL, and analytics to solve complex problems at scale',
|
||||
'14,000 patients identified for cost-effective switching in 3 days versus months manually',
|
||||
'£2.6M in annual savings identified, with £2M on target for delivery',
|
||||
'Novel GP payment system linking incentive rewards to actual savings delivered',
|
||||
'50% reduction in targeted prescribing within the first two months of deployment',
|
||||
],
|
||||
period: 'Aug 2016 — Present',
|
||||
period: '2025',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -64,17 +64,17 @@ export const kpis: KPI[] = [
|
||||
label: 'Population Served',
|
||||
sub: 'Norfolk & Waveney ICS',
|
||||
colorVariant: 'teal',
|
||||
explanation: 'Leading population health analytics and data-driven medicines optimisation for Norfolk & Waveney Integrated Care System, covering 1.2 million people across the region.',
|
||||
explanation: 'Leading population health analytics and data-driven medicines optimisation for Norfolk & Waveney Integrated Care System, serving 1.2 million people across the region.',
|
||||
story: {
|
||||
context: 'Norfolk & Waveney Integrated Care System serves a population of 1.2 million people across Norfolk and parts of Suffolk, with responsibility for coordinating health and care services across primary care, secondary care, and community services.',
|
||||
role: 'Lead population health analytics, developing patient-level datasets and analytical frameworks from real-world GP prescribing data to identify efficiency opportunities, address health inequalities, and support data-driven decision making at system scale.',
|
||||
context: 'Norfolk & Waveney Integrated Care System serves a population of 1.2 million people across Norfolk and parts of Suffolk, coordinating health and care services across primary care, secondary care, community services, and mental health provision.',
|
||||
role: 'Lead population health analytics for the medicines optimisation function, developing patient-level datasets and analytical frameworks from real-world GP prescribing data to identify efficiency opportunities, monitor medicines safety, address health inequalities, and support evidence-based decision-making at system scale.',
|
||||
outcomes: [
|
||||
'Transformed analytics from practice-level to patient-level SQL analysis',
|
||||
'Built comprehensive medicines data table integrating all dm+d products',
|
||||
'Developed population-scale controlled drug monitoring system',
|
||||
'Created self-serve analytical tools enabling wider team data fluency',
|
||||
'Transformed analytics from practice-level aggregate reporting to patient-level SQL analysis',
|
||||
'Built comprehensive dm+d medicines data table: standardised strengths, morphine equivalents, Anticholinergic Burden scoring',
|
||||
'Developed population-scale controlled drug monitoring system tracking patient-level opioid exposure',
|
||||
'Created self-serve Power BI tools improving data fluency across the wider team',
|
||||
],
|
||||
period: 'Jul 2024 — Present',
|
||||
period: 'Jul 2024 – Present',
|
||||
},
|
||||
},
|
||||
]
|
||||
]
|
||||
+261
-69
@@ -1,17 +1,18 @@
|
||||
import type { ProfileContent } from '@/types/profile-content'
|
||||
import type { DeepReadonly, ProfileContent } from '@/types/profile-content'
|
||||
|
||||
export const profileContent = {
|
||||
export const profileContent: DeepReadonly<ProfileContent> = {
|
||||
profile: {
|
||||
patientSummaryNarrative: 'Healthcare leader combining clinical pharmacy expertise with proficiency in Python, SQL, and data analytics, self-taught over the past decade through a drive to find root causes in data and build the most efficient solutions to complex problems. Currently leading population health analytics for NHS Norfolk & Waveney ICB, serving a population of 1.2 million. Experienced in working with messy, real-world prescribing data at scale to deliver actionable insights, from financial scenario modelling and pharmaceutical rebate negotiation to algorithm design and population-level pathway development. Proven track record of identifying and prioritising efficiency programmes worth £14.6M+ through automated, data-driven analysis. Skilled at translating complex clinical, financial, and analytical requirements into clear recommendations for executive stakeholders.',
|
||||
sectionTitle: 'Patient Summary',
|
||||
patientSummaryNarrative: 'Informatics pharmacist combining clinical expertise with advanced proficiency in Python, SQL, Power BI, and healthcare data analytics, self-taught over the past decade through a drive to find root causes in messy, real-world data and engineer the most efficient solutions to complex problems. Currently leading population health analytics and prescribing intelligence for NHS Norfolk & Waveney ICB, serving a population of 1.2 million across an integrated care system. Experienced in transforming large-scale GP prescribing data into actionable insight: from financial scenario modelling, pharmaceutical rebate negotiation, and health technology assessment to algorithm design, clinical decision support tooling, and population-level pathway development. Proven track record of identifying and prioritising efficiency programmes worth £14.6M+ through automated, data-driven analysis. Skilled at translating complex clinical, financial, and analytical requirements into clear, evidence-based recommendations for executive stakeholders, bridging primary care, secondary care, and commissioning perspectives.',
|
||||
latestResults: {
|
||||
title: 'LATEST RESULTS (CLICK TO VIEW FULL REFERENCE RANGE)',
|
||||
rightText: 'Updated May 2025',
|
||||
rightText: 'Updated February 2026',
|
||||
helperText: 'Select a metric to inspect methodology, impact, and outcomes.',
|
||||
evidenceCta: 'Click to view evidence',
|
||||
},
|
||||
sidebar: {
|
||||
sectionTitle: 'Patient Data',
|
||||
roleTitle: 'Pharmacy Data Technologist',
|
||||
roleTitle: 'Informatics Pharmacist',
|
||||
gphcLabel: 'GPhC No.',
|
||||
educationLabel: 'Education',
|
||||
locationLabel: 'Location',
|
||||
@@ -30,54 +31,71 @@ export const profileContent = {
|
||||
experienceEducation: {
|
||||
educationEntries: [
|
||||
{
|
||||
title: 'NHS Leadership Academy — Mary Seacole Programme',
|
||||
title: 'NHS Leadership Academy – Mary Seacole Programme',
|
||||
subtitle: 'NHS Leadership Academy · 2018',
|
||||
keywords: 'nhs leadership academy mary seacole programme 2018 qualification management',
|
||||
keywords: 'nhs leadership academy mary seacole programme 2018 qualification management change leadership healthcare system-level thinking',
|
||||
},
|
||||
{
|
||||
title: 'MPharm (Hons) — 2:1',
|
||||
title: 'MPharm (Hons) – 2:1',
|
||||
subtitle: 'University of East Anglia · 2011–2015',
|
||||
keywords: 'mpharm hons 2:1 university east anglia uea 2011 2015 pharmacy degree',
|
||||
keywords: 'mpharm hons 2:1 university east anglia uea 2011 2015 pharmacy degree pharmaceutical sciences clinical pharmacy pharmacology therapeutics drug delivery cocrystals research',
|
||||
},
|
||||
{
|
||||
title: 'A-Levels',
|
||||
subtitle: 'Highworth Grammar School · 2009–2011',
|
||||
keywords: 'a-levels mathematics chemistry politics highworth grammar school 2009 2011',
|
||||
keywords: 'a-levels mathematics a* chemistry b politics c highworth grammar school 2009 2011',
|
||||
},
|
||||
{
|
||||
title: 'GPhC Registration',
|
||||
subtitle: 'General Pharmaceutical Council · August 2016',
|
||||
keywords: 'gphc registration general pharmaceutical council 2016 registered pharmacist',
|
||||
keywords: 'gphc registration general pharmaceutical council 2016 registered pharmacist professional licence clinical governance',
|
||||
},
|
||||
],
|
||||
ui: {
|
||||
educationLabel: 'Education',
|
||||
employmentLabel: 'Employment',
|
||||
viewFullRecordLabel: 'View full record',
|
||||
},
|
||||
},
|
||||
skillsNarrative: {
|
||||
summary: 'Technical, domain, and leadership capabilities spanning data analysis, medicines optimisation, and executive communication with practical delivery across population-scale NHS prescribing programmes.',
|
||||
summary: 'Technical, healthcare domain, and strategic leadership capabilities spanning data engineering, prescribing analytics, medicines optimisation, health technology assessment, clinical decision support, and executive communication, with practical delivery across population-scale NHS programmes serving 1.2 million people.',
|
||||
ui: {
|
||||
sectionTitle: 'REPEAT MEDICATIONS',
|
||||
rightText: 'Active prescriptions',
|
||||
itemCountSuffix: 'items',
|
||||
yearsSuffix: 'yrs',
|
||||
viewAllLabel: 'View all',
|
||||
categories: [
|
||||
{ id: 'Technical', label: 'Technical' },
|
||||
{ id: 'Domain', label: 'Healthcare Domain' },
|
||||
{ id: 'Leadership', label: 'Strategic & Leadership' },
|
||||
],
|
||||
},
|
||||
},
|
||||
resultsNarrative: {
|
||||
achievements: [
|
||||
{
|
||||
title: '£14.6M Efficiency Savings Identified',
|
||||
subtitle: 'Data-driven prescribing interventions',
|
||||
keywords: '14.6m efficiency savings identified data-driven prescribing interventions money cost',
|
||||
subtitle: 'Data-driven prescribing interventions across ICS',
|
||||
keywords: '14.6m efficiency savings identified data-driven prescribing interventions cost improvement programme medicines optimisation qipp',
|
||||
kpiId: 'savings',
|
||||
},
|
||||
{
|
||||
title: '£220M Budget Oversight',
|
||||
subtitle: 'Full analytical accountability to ICB board',
|
||||
keywords: '220m budget oversight analytical accountability icb board',
|
||||
keywords: '220m budget oversight analytical accountability icb board financial planning forecasting prescribing expenditure',
|
||||
kpiId: 'budget',
|
||||
},
|
||||
{
|
||||
title: 'Power BI Dashboards for 200+ Users',
|
||||
subtitle: 'Clinicians & commissioners across ICB',
|
||||
keywords: 'power bi dashboards 200 users clinicians commissioners',
|
||||
title: '£2.6M Savings via Automated Algorithm',
|
||||
subtitle: '14,000 patients identified in 3 days',
|
||||
keywords: '2.6m savings automated algorithm python switching 14000 patients cost-effective alternatives prescribing analytics',
|
||||
kpiId: 'years',
|
||||
},
|
||||
{
|
||||
title: '1.2M Population Served',
|
||||
subtitle: 'Norfolk & Waveney Integrated Care System',
|
||||
keywords: '1.2m population served norfolk waveney ics integrated care system',
|
||||
keywords: '1.2m population served norfolk waveney ics integrated care system primary care secondary care commissioning',
|
||||
kpiId: 'population',
|
||||
},
|
||||
],
|
||||
@@ -87,7 +105,7 @@ export const profileContent = {
|
||||
{
|
||||
title: 'Download CV',
|
||||
subtitle: 'Export as PDF',
|
||||
keywords: 'download cv export pdf resume',
|
||||
keywords: 'download cv export pdf resume curriculum vitae',
|
||||
type: 'download',
|
||||
},
|
||||
{
|
||||
@@ -100,14 +118,14 @@ export const profileContent = {
|
||||
{
|
||||
title: 'View LinkedIn',
|
||||
subtitle: 'Professional profile',
|
||||
keywords: 'view linkedin professional profile social',
|
||||
keywords: 'view linkedin professional profile social networking',
|
||||
type: 'link',
|
||||
url: 'https://linkedin.com/in/andycharlwood',
|
||||
},
|
||||
{
|
||||
title: 'View Projects',
|
||||
subtitle: 'GitHub & portfolio',
|
||||
keywords: 'view projects github portfolio code repositories',
|
||||
keywords: 'view projects github portfolio code repositories open source',
|
||||
type: 'link',
|
||||
url: 'https://github.com/andycharlwood',
|
||||
},
|
||||
@@ -116,91 +134,108 @@ export const profileContent = {
|
||||
systemPrompt: `You are a helpful assistant on Andy Charlwood's portfolio website. Answer questions about Andy's professional background using ONLY the information below.
|
||||
|
||||
## Profile
|
||||
Andy Charlwood — MPharm, GPhC Registered Pharmacist. Norwich, UK.
|
||||
Healthcare leader combining clinical pharmacy with Python, SQL, and data analytics (self-taught). Leading population health analytics for NHS Norfolk & Waveney ICB, serving 1.2M people. Specialises in prescribing data at scale — financial modelling, algorithm design, pathway development. Identified efficiency programmes worth £14.6M+ through automated analysis.
|
||||
Andy Charlwood, Informatics Pharmacist. MPharm, GPhC Registered Pharmacist. Norwich, UK.
|
||||
Informatics pharmacist combining clinical expertise with Python, SQL, Power BI, and healthcare data analytics (self-taught). Leading population health analytics and prescribing intelligence for NHS Norfolk & Waveney ICB, serving 1.2M people. Specialises in transforming large-scale prescribing data into actionable insight: financial scenario modelling, algorithm design, health technology assessment, clinical decision support tooling, and population-level pathway development. Identified efficiency programmes worth £14.6M+ through automated analysis.
|
||||
|
||||
## Employment Timeline (IMPORTANT)
|
||||
- **NHS employment**: May 2022–present (all roles at NHS Norfolk & Waveney ICB). Total NHS service: ~4 years.
|
||||
- **Private sector**: Nov 2017–May 2022 at Tesco PLC (community pharmacy). This was NOT NHS employment.
|
||||
- **NHS employment**: May 2022 to present (all roles at NHS Norfolk & Waveney ICB). Total NHS service: approximately 3 years 9 months as of February 2026.
|
||||
- **Private sector**: August 2016 to May 2022 at Tesco PLC (community pharmacy). Started as Duty Pharmacy Manager (Aug 2016), promoted to Pharmacy Manager (Nov 2017). This was NOT NHS employment.
|
||||
- **Pre-registration**: July 2015 to July 2016 at Paydens Pharmacy (community pharmacy, Kent). Training year prior to GPhC registration.
|
||||
- GPhC registration (Aug 2016) is a professional licence, NOT an employer or NHS role.
|
||||
|
||||
## Career History
|
||||
|
||||
### [exp-interim-head-2025] Interim Head, Population Health & Data Analysis
|
||||
NHS Norfolk & Waveney ICB | May–Nov 2025
|
||||
Led population health initiatives and data-driven medicines optimisation, reporting to Associate Director of Pharmacy with accountability to CMO.
|
||||
- Identified £14.6M efficiency programme; achieved over-target performance by October 2025
|
||||
- Built Python switching algorithm: real-world GP prescribing data, 14,000 patients, £2.6M annual savings (£2M on target), compressed months into 3 days
|
||||
- Novel GP payment system linking rewards to savings; 50% prescribing reduction within 2 months
|
||||
- Presented to CMO bimonthly; led transformation to patient-level SQL analytics
|
||||
NHS Norfolk & Waveney ICB | May to Nov 2025
|
||||
Led population health initiatives and data-driven medicines optimisation, reporting to Associate Director of Pharmacy with accountability to CMO. Returned to substantive Deputy Head role following commencement of ICB-wide organisational consultation.
|
||||
- Identified and prioritised a £14.6M efficiency programme through comprehensive prescribing data analysis; achieved over-target performance by October 2025 through targeted, evidence-based interventions across the integrated care system
|
||||
- Built Python-based switching algorithm using real-world GP prescribing data to automatically identify patients on expensive drugs suitable for cost-effective alternatives, compressing months of manual analysis into 3 days, identifying 14,000 patients and £2.6M in annual savings (£2M on target for delivery)
|
||||
- Automated incentive scheme analysis, enabling a novel GP payment system linking rewards to delivered savings; achieved 50% reduction in targeted prescribing within the first two months of deployment
|
||||
- Presented strategy, programme progress, and financial position to Chief Medical Officer bimonthly, providing evidence-based recommendations to inform executive decision-making
|
||||
- Led transformation from practice-level aggregate reporting to patient-level SQL analytics, enabling targeted clinical interventions and a self-serve analytics model for the wider team
|
||||
|
||||
### [exp-deputy-head-2024] Deputy Head, Population Health & Data Analysis
|
||||
NHS Norfolk & Waveney ICB | Jul 2024–Present (substantive role)
|
||||
Data analytics strategy for medicines optimisation from real-world GP prescribing data.
|
||||
- Managed £220M prescribing budget with forecasting models for proactive financial planning
|
||||
- Created comprehensive dm+d medicines data table: standardised strengths, morphine equivalents, Anticholinergic Burden scoring — single source of truth for all medicines analytics
|
||||
- Led DOAC switching financial modelling: interactive dashboard with rebate mechanics, patent expiry timelines
|
||||
- Renegotiated pharmaceutical rebate terms ahead of patent expiry
|
||||
- Tirzepatide commissioning (NICE TA1026): financial projections, cohort identification; authored executive paper advocating primary care model, driving system shift to GP-led delivery
|
||||
- Built Python controlled drug monitoring: oral morphine equivalents across all opioid prescriptions, patient-level tracking, high-risk identification, diversion detection
|
||||
- Improved team data fluency through training and self-serve tools
|
||||
NHS Norfolk & Waveney ICB | Jul 2024 to Present (substantive role)
|
||||
Driving data analytics strategy for medicines optimisation, developing bespoke datasets and analytical frameworks from messy, real-world GP prescribing data to identify efficiency opportunities and address health inequalities across the integrated care system.
|
||||
- Managed £220M prescribing budget with sophisticated forecasting models identifying cost pressures and enabling proactive financial planning for ICB board reporting
|
||||
- Collaborated with the ICB data engineering team to create a comprehensive dm+d medicines data table integrating all Dictionary of Medicines and Devices products with standardised strength calculations, oral morphine equivalent conversions, and Anticholinergic Burden scoring, providing a single source of truth for all medicines analytics
|
||||
- Led financial scenario modelling for a system-wide DOAC switching programme, building an interactive Power BI dashboard incorporating rebate mechanics, clinician switching capacity, workforce constraints, and patent expiry timelines to quantify risk trade-offs for senior decision-makers
|
||||
- Renegotiated pharmaceutical rebate terms ahead of patent expiry, securing improved commercial position for the ICB
|
||||
- Supported commissioning of tirzepatide (NICE TA1026) including financial projections identifying eligible cohorts from real-world prescribing data; authored the initial executive paper advocating a primary care delivery model over a specialist provider on cost-effectiveness and accessibility grounds, driving the system shift to GP-led delivery following executive sign-off
|
||||
- Developed Python-based controlled drug monitoring system calculating oral morphine equivalents (OME) across all opioid prescriptions, tracking patient-level exposure over time to identify high-risk patients and potential diversion, enabling previously impossible patient safety analysis at population scale
|
||||
- Improved team data fluency through training, documentation, and self-serve Power BI tools
|
||||
|
||||
### [exp-high-cost-drugs-2022] High-Cost Drugs & Interface Pharmacist
|
||||
NHS Norfolk & Waveney ICB | May 2022–Jul 2024
|
||||
Led NICE TA implementation and high-cost drug pathways across the ICS. Pathways spanning: rheumatology, ophthalmology (wet AMD, DMO, RVO), dermatology, gastroenterology, neurology, migraine.
|
||||
- Blueteq automation: 70% form reduction, 200 hours immediate savings, 7–8 hours ongoing weekly gains
|
||||
- Integrated Blueteq with secondary care databases for accurate high-cost drug spend tracking
|
||||
- Python Sankey chart tool for patient pathway visualisation and trust compliance auditing
|
||||
NHS Norfolk & Waveney ICB | May 2022 to Jul 2024
|
||||
Led implementation of NICE technology appraisals and high-cost drug pathways across the ICS. Authored most of the system's high-cost drug pathways spanning rheumatology, ophthalmology (wet AMD, DMO, RVO), dermatology, gastroenterology, neurology, and migraine, balancing legal requirements to implement TAs against financial costs, formulary management, and local clinical preferences. Engaged clinical leads across primary care, secondary care, and commissioning to agree pathways and secure system-wide adoption.
|
||||
- Developed software automating Blueteq prior authorisation form creation: 70% reduction in required forms, 200 hours immediate savings, and ongoing 7 to 8 hours weekly efficiency gains
|
||||
- Integrated Blueteq data with secondary care activity databases, resolving critical data-matching limitations and enabling accurate high-cost drug spend tracking
|
||||
- Created Python-based Sankey chart analysis tool visualising patient journeys through high-cost drug pathways, enabling trusts to audit compliance and identify improvement opportunities
|
||||
|
||||
### [exp-pharmacy-manager-2017] Pharmacy Manager
|
||||
Tesco PLC (private sector, NOT NHS) | Nov 2017–May 2022
|
||||
Community pharmacy with full operational autonomy (100-hour contract). LPC representative for Norfolk.
|
||||
- Asthma screening process adopted nationally (~300 branches): reduced pharmacist time 60→6 hours/store/month, ~£1M revenue
|
||||
- Leadership training: Created national induction training plan and eLearning modules for Tesco pharmacy staff
|
||||
- Leadership development: Supervised two staff through NVQ3 to pharmacy technician registration; full HR responsibilities
|
||||
Tesco PLC (private sector, NOT NHS) | Nov 2017 to May 2022
|
||||
Community pharmacy with full operational autonomy (100-hour contract). Local Pharmaceutical Committee representative for Norfolk.
|
||||
- Identified and shared an asthma screening process adopted nationally across the Tesco pharmacy estate (approximately 300 branches): reduced pharmacist time from 60 hours to 6 hours per store per month, enabling the network to claim approximately £1M in revenue
|
||||
- Led creation of national induction training plan and eLearning modules for all new Tesco pharmacy staff, with enhanced focus on leadership development for non-pharmacist team members
|
||||
- Supervised two staff members through NVQ3 qualifications to pharmacy technician registration; full HR responsibilities including recruitment, performance management, and grievances
|
||||
|
||||
### [exp-duty-pharmacy-manager-2016] Duty Pharmacy Manager
|
||||
Tesco PLC (private sector, NOT NHS) | Aug 2016 to Oct 2017
|
||||
Progressed rapidly from newly qualified pharmacist to acting pharmacy manager within two months. Provided clinical leadership across community pharmacy services whilst developing early expertise in service development and quality improvement.
|
||||
- Led NMS and asthma referral service development, improving uptake and patient outcomes across the store
|
||||
- Devised a quality payments solution adopted nationally across the Tesco pharmacy estate
|
||||
- Built clinical foundation in medicines optimisation, patient safety, and community pharmacy operations
|
||||
|
||||
### [exp-pre-reg-2015] Pre-Registration Pharmacist
|
||||
Paydens Pharmacy (community pharmacy, Kent) | Jul 2015 to Jul 2016
|
||||
Completed pre-registration training across multiple community pharmacy sites in Tunbridge Wells and Ashford, developing core clinical competencies and demonstrating initiative through expanding clinical services.
|
||||
- Expanded PGD clinical services: NRT, EHC, and chlamydia screening programmes across multiple Paydens branches
|
||||
- Improved NMS audit completion rate from under 10% to 50 to 60% through process redesign
|
||||
- Developed a palliative care screening pathway for community pharmacy setting
|
||||
|
||||
## Projects
|
||||
|
||||
### [proj-inv-pharmetrics] PharMetrics Interactive Platform (2024, Live)
|
||||
Real-time medicines expenditure dashboard for NHS decision-makers. Tech: Power BI, SQL, DAX. Tracks £220M prescribing budget.
|
||||
NHS decision-makers lacked a unified, real-time view of prescribing expenditure across the system. PharMetrics provides an interactive Power BI dashboard tracking the full £220M prescribing budget, enabling commissioners and clinical leads to drill into practice-level variation, identify cost pressures, and monitor efficiency programme delivery. Tech: Power BI, SQL, DAX. Serves clinicians and commissioners across the ICB.
|
||||
|
||||
### [proj-inv-switching-algorithm] Patient Switching Algorithm (2025, Complete)
|
||||
Python algorithm using GP prescribing data to auto-identify patients for cost-effective alternatives. Tech: Python, Pandas, SQL. 14,000 patients, £2.6M annual savings, novel GP payment system.
|
||||
Annual medicines switching schemes previously required months of manual data trawling by the optimisation team. This Python algorithm ingests real-world GP prescribing data, cross-references dm+d product information, and automatically identifies patients on expensive drugs who could be switched to cost-effective alternatives, with built-in clinical safety rules. Tech: Python, Pandas, SQL. 14,000 patients identified, £2.6M annual savings, novel GP payment system linking incentives to delivered savings.
|
||||
|
||||
### [proj-inv-blueteq-gen] Blueteq Generator (2023, Complete)
|
||||
Automated Blueteq prior approval form creation. Tech: Python, SQL. 70% form reduction, 200 hours immediate savings, 7–8 hours ongoing weekly gains.
|
||||
Prior authorisation forms for high-cost drugs were manually created and maintained, consuming significant clinical pharmacist time. This tool automates Blueteq form generation from structured pathway data, reducing form count by 70% and freeing over 200 hours immediately with ongoing weekly savings of 7 to 8 hours. Tech: Python, SQL.
|
||||
|
||||
### [proj-inv-cd-monitoring] CD Monitoring System (2024, Complete)
|
||||
Controlled drug monitoring calculating oral morphine equivalents (OME) across all opioid prescriptions. Tech: Python, SQL. Patient-level tracking, high-risk identification, diversion detection.
|
||||
Population-level controlled drug monitoring was previously impossible due to the complexity of converting between opioid formulations. This system calculates oral morphine equivalents (OME) across all opioid prescriptions at patient level, tracking exposure over time to identify high-risk patients and potential diversion patterns. Tech: Python, SQL, dm+d integration.
|
||||
|
||||
### [proj-inv-sankey-tool] Sankey Chart Analysis Tool (2023, Complete)
|
||||
Patient journey visualisation through high-cost drug pathways. Tech: Python, Matplotlib, SQL. Trust compliance auditing.
|
||||
Trusts had no way to visualise how patients moved through high-cost drug treatment pathways or audit compliance against agreed formulary positions. This Python tool generates interactive Sankey diagrams from prescribing and Blueteq data, revealing treatment sequences, pathway deviations, and opportunities for improvement. Tech: Python, Matplotlib, SQL.
|
||||
|
||||
## Education
|
||||
|
||||
### [edu-0] NHS Mary Seacole Programme (2018)
|
||||
NHS Leadership Academy. Score: 78%. Covers change management, healthcare leadership, system-level thinking.
|
||||
NHS Leadership Academy. Score: 78%. Covers change management, healthcare leadership, system-level thinking, leading without authority.
|
||||
|
||||
### [edu-1] MPharm (Hons) 2:1 — University of East Anglia (2011–2015)
|
||||
4-year integrated Master's degree. Research project on drug delivery and cocrystals: 75.1% (Distinction).
|
||||
### [edu-1] MPharm (Hons) 2:1 – University of East Anglia (2011 to 2015)
|
||||
4-year integrated Master's degree in pharmacy. Research project on drug delivery and cocrystals: 75.1% (Distinction). 4th year OSCE: 80%. President of UEA Pharmacy Society.
|
||||
|
||||
### [edu-2] A-Levels — Highworth Grammar School (2009–2011)
|
||||
### [edu-2] A-Levels – Highworth Grammar School (2009 to 2011)
|
||||
Mathematics A*, Chemistry B, Politics C.
|
||||
|
||||
### [edu-3] GPhC Registration — General Pharmaceutical Council (August 2016–Present)
|
||||
### [edu-3] GPhC Registration – General Pharmaceutical Council (August 2016 to Present)
|
||||
Professional registration required to practise as a pharmacist in Great Britain.
|
||||
|
||||
## Skills
|
||||
Technical: [skill-data-analysis] Data Analysis (9yr, 95%), [skill-python] Python (6yr, 90%), [skill-sql] SQL (7yr, 88%), [skill-power-bi] Power BI (5yr, 92%), [skill-javascript-typescript] JavaScript/TypeScript (3yr, 70%), [skill-excel] Excel (9yr, 85%), [skill-algorithm-design] Algorithm Design (3yr, 82%), [skill-data-pipelines] Data Pipelines (2yr, 75%)
|
||||
Domain: [skill-medicines-optimisation] Medicines Optimisation (9yr, 95%), [skill-population-health] Population Health (3yr, 90%), [skill-nice-ta] NICE TA Implementation (3yr, 92%), [skill-health-economics] Health Economics (3yr, 80%), [skill-clinical-pathways] Clinical Pathways (3yr, 88%), [skill-controlled-drugs] Controlled Drugs (1yr, 85%)
|
||||
Leadership: [skill-budget-management] Budget Management (1yr, 90%), [skill-stakeholder-engagement] Stakeholder Engagement (3yr, 88%), [skill-pharma-negotiation] Pharmaceutical Negotiation (1yr, 82%), [skill-team-development] Team Development (8yr, 85%), [skill-change-management] Change Management (7yr, 80%), [skill-financial-modelling] Financial Modelling (1yr, 78%), [skill-executive-comms] Executive Communication (1yr, 85%)
|
||||
Technical: [skill-data-analysis] Data Analysis & Prescribing Analytics (9yr, 95%), [skill-python] Python inc. Pandas (6yr, 90%), [skill-sql] SQL & Database Design (7yr, 88%), [skill-power-bi] Power BI, DAX & Dashboard Development (5yr, 92%), [skill-javascript-typescript] JavaScript/TypeScript (3yr, 70%), [skill-excel] Excel & Spreadsheet Modelling (9yr, 85%), [skill-algorithm-design] Algorithm Design & Clinical Decision Support (3yr, 82%), [skill-data-pipelines] Data Pipelines & ETL (2yr, 75%), [skill-snomed-dmd] SNOMED CT, dm+d & Clinical Coding (3yr, 80%), [skill-ehr-systems] EHR Systems: SystmOne, EMIS, Blueteq (3yr, 78%)
|
||||
Domain: [skill-medicines-optimisation] Medicines Optimisation & Formulary Management (9yr, 95%), [skill-population-health] Population Health Analytics & Real-World Evidence (3yr, 90%), [skill-nice-ta] NICE TA Implementation & Health Technology Assessment (3yr, 92%), [skill-health-economics] Health Economics & Cost-Effectiveness Analysis (3yr, 80%), [skill-clinical-pathways] Clinical Pathway Development & Prior Authorisation (3yr, 88%), [skill-controlled-drugs] Controlled Drugs & Medicines Safety (1yr, 85%), [skill-commissioning] Commissioning & Primary/Secondary Care Interface (3yr, 82%)
|
||||
Leadership: [skill-budget-management] Budget Management & Financial Planning (1yr, 90%), [skill-stakeholder-engagement] Stakeholder Engagement & Cross-Organisational Collaboration (3yr, 88%), [skill-pharma-negotiation] Pharmaceutical Negotiation & Commercial Awareness (1yr, 82%), [skill-team-development] Team Development, Training & Coaching (8yr, 85%), [skill-change-management] Change Management & System Transformation (7yr, 80%), [skill-financial-modelling] Financial Scenario Modelling & Forecasting (1yr, 78%), [skill-executive-comms] Executive Communication & Board Reporting (1yr, 85%), [skill-matrix-leadership] Matrix Leadership & Leading Without Authority (3yr, 80%)
|
||||
|
||||
## Response Rules
|
||||
1. Answer ONLY from the data above. If the answer is not in the data, say "I don't have that information" — never invent facts, roles, dates, achievements, URLs, or contact details.
|
||||
2. Distinguish NHS employment (May 2022–present, ~4 years, all at Norfolk & Waveney ICB) from private sector (Tesco PLC, Nov 2017–May 2022, community pharmacy). Never conflate the two. GPhC registration is a professional licence, not NHS employment.
|
||||
3. When asked broad questions about tools, skills, projects, or achievements across Andy's career, aggregate from ALL roles — do not limit your answer to one position.
|
||||
1. Answer ONLY from the data above. If the answer is not in the data, say "I don't have that information" – never invent facts, roles, dates, achievements, URLs, or contact details.
|
||||
2. Distinguish NHS employment (May 2022 to present, approximately 3 years 9 months, all at Norfolk & Waveney ICB) from private sector (Tesco PLC, Aug 2016 to May 2022, community pharmacy) and pre-registration (Paydens Pharmacy, Jul 2015 to Jul 2016). Never conflate these. GPhC registration is a professional licence, not NHS employment.
|
||||
3. When asked broad questions about tools, skills, projects, or achievements across Andy's career, aggregate from ALL roles. Do not limit your answer to one position.
|
||||
4. Cite exact numbers, dates, percentages, and outcomes. Never say "approximately" or "around" when exact figures exist in the data.
|
||||
5. For detailed or list-based questions, give a thorough answer covering all relevant items. For simple questions, be concise (2-4 sentences).
|
||||
5. For detailed or list-based questions, give a thorough answer covering all relevant items. For simple questions, be concise (2 to 4 sentences).
|
||||
6. When describing projects, lead with the problem they solve and who they serve, then explain the technical approach and outcomes.
|
||||
|
||||
## Item References
|
||||
End your response with a single line listing relevant item IDs from the square-bracketed IDs above:
|
||||
@@ -208,4 +243,161 @@ End your response with a single line listing relevant item IDs from the square-b
|
||||
Only include IDs that directly support your answer. Omit the line if none are relevant.`,
|
||||
},
|
||||
},
|
||||
} as const satisfies ProfileContent
|
||||
timelineNarrative: {
|
||||
'interim-head-2025': {
|
||||
description: 'Led strategic delivery of population health initiatives and data-driven medicines optimisation across Norfolk & Waveney ICS, reporting to Associate Director of Pharmacy with presentation accountability to Chief Medical Officer and system-level programme boards. Responsible for setting analytical priorities, directing the efficiency programme, and ensuring evidence-based recommendations reached executive decision-makers. Returned to substantive Deputy Head role following commencement of ICB-wide organisational consultation.',
|
||||
details: [
|
||||
'Identified and prioritised a £14.6M efficiency programme through comprehensive prescribing data analysis, targeting the highest-value, lowest-risk interventions across the integrated care system',
|
||||
'Built Python-based switching algorithm using real-world GP prescribing data: 14,000 patients identified, £2.6M annual savings, compressing months of manual analysis into 3 days',
|
||||
'Automated incentive scheme analysis, enabling a novel GP payment system linking rewards to delivered savings; achieved 50% reduction in targeted prescribing within 2 months',
|
||||
'Led transformation from practice-level aggregate reporting to patient-level SQL analytics, enabling targeted clinical interventions and a self-serve model for the wider team',
|
||||
],
|
||||
outcomes: [
|
||||
'Achieved over-target performance by October 2025',
|
||||
'£2M on target for delivery in the current financial year',
|
||||
'Presented strategy and financial position to CMO bimonthly with evidence-based recommendations',
|
||||
'Self-serve analytics model adopted, reducing analytical bottlenecks across the team',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'EFF001', description: 'Efficiency programme: £14.6M identified and prioritised' },
|
||||
{ code: 'ALG001', description: 'Algorithm: 14,000 patients, £2.6M savings, 3-day turnaround' },
|
||||
{ code: 'AUT001', description: 'Incentive automation: 50% prescribing reduction in 2 months' },
|
||||
{ code: 'SQL001', description: 'Data transformation: practice-level to patient-level analytics' },
|
||||
],
|
||||
},
|
||||
'deputy-head-2024': {
|
||||
description: 'Driving data analytics strategy for medicines optimisation, developing bespoke datasets and analytical frameworks from messy, real-world GP prescribing data to identify efficiency opportunities, monitor medicines safety, and address health inequalities across the integrated care system. Responsible for the analytical infrastructure underpinning all prescribing intelligence, from dm+d product data to population-level monitoring tools.',
|
||||
details: [
|
||||
'Managed £220M prescribing budget with sophisticated forecasting models identifying cost pressures and enabling proactive financial planning for ICB board reporting',
|
||||
'Collaborated with ICB data engineering to create a comprehensive dm+d medicines data table: standardised strength calculations, oral morphine equivalent conversions, and Anticholinergic Burden scoring, providing a single source of truth for all medicines analytics',
|
||||
'Led financial scenario modelling for a system-wide DOAC switching programme, building an interactive Power BI dashboard incorporating rebate mechanics, clinician switching capacity, workforce constraints, and patent expiry timelines',
|
||||
'Renegotiated pharmaceutical rebate terms ahead of patent expiry, securing improved commercial position for the ICB',
|
||||
'Supported commissioning of tirzepatide (NICE TA1026): financial projections from real-world data, cohort identification, and an executive paper advocating primary care delivery on cost-effectiveness grounds',
|
||||
'Developed Python-based controlled drug monitoring system calculating oral morphine equivalents across all opioid prescriptions, tracking patient-level exposure over time, identifying high-risk patients and potential diversion',
|
||||
],
|
||||
outcomes: [
|
||||
'Single source of truth established for all medicines analytics across the system',
|
||||
'GP-led delivery model adopted for tirzepatide following executive sign-off',
|
||||
'Population-scale medicines safety analysis enabled for the first time',
|
||||
'Team data fluency improved through training, documentation, and self-serve Power BI tools',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'BUD001', description: 'Budget management: £220M prescribing oversight' },
|
||||
{ code: 'DAT001', description: 'Data infrastructure: dm+d integration, single source of truth' },
|
||||
{ code: 'MOD001', description: 'Financial modelling: DOAC switching, rebate negotiation' },
|
||||
{ code: 'MON001', description: 'CD monitoring: population-scale OME tracking' },
|
||||
{ code: 'COM001', description: 'Commissioning: tirzepatide TA1026, primary care model' },
|
||||
{ code: 'LEA001', description: 'Team development: data literacy programme' },
|
||||
],
|
||||
},
|
||||
'high-cost-drugs-2022': {
|
||||
description: 'Led implementation of NICE technology appraisals and high-cost drug pathways across the ICS. Authored most of the system\'s high-cost drug pathways spanning rheumatology, ophthalmology (wet AMD, DMO, RVO), dermatology, gastroenterology, neurology, and migraine, balancing the legal requirement to implement TAs against financial costs, formulary management, and local clinical preferences. Engaged clinical leads across primary care, secondary care, and commissioning to agree pathways and secure system-wide adoption.',
|
||||
details: [
|
||||
'Developed software automating Blueteq prior authorisation form creation: 70% reduction in required forms, 200 hours immediate savings, and ongoing 7 to 8 hours weekly efficiency gains',
|
||||
'Integrated Blueteq data with secondary care activity databases, resolving critical data-matching limitations and enabling accurate high-cost drug spend tracking across the system',
|
||||
'Created Python-based Sankey chart analysis tool visualising patient journeys through high-cost drug pathways, enabling trusts to audit compliance and identify formulary adherence opportunities',
|
||||
'Negotiated pathway agreements with consultant clinical leads, GP prescribing leads, and pharmaceutical company representatives across multiple therapeutic areas',
|
||||
],
|
||||
outcomes: [
|
||||
'70% reduction in prior authorisation forms, 200 hours immediate savings',
|
||||
'Ongoing 7 to 8 hours weekly efficiency gains sustained across the system',
|
||||
'Accurate high-cost drug spend tracking enabled for the first time',
|
||||
'Trust-level compliance auditing and pathway optimisation made possible through visual analytics',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'AUT002', description: 'Automation: Blueteq form generation, 70% reduction' },
|
||||
{ code: 'DAT002', description: 'Data integration: Blueteq plus secondary care activity' },
|
||||
{ code: 'VIS001', description: 'Visualisation: Sankey pathway analysis tool' },
|
||||
{ code: 'HTA001', description: 'HTA implementation: multi-specialty pathways across ICS' },
|
||||
],
|
||||
},
|
||||
'pharmacy-manager-2017': {
|
||||
description: 'Managed all pharmacy operations with full autonomy across a 100-hour contract at Tesco PLC, leading regional KPI delivery initiatives and contributing to national operational improvements. Served as Local Pharmaceutical Committee representative for Norfolk, engaging with wider system stakeholders on behalf of the community pharmacy network.',
|
||||
details: [
|
||||
'Identified and shared an asthma screening process adopted nationally across the Tesco pharmacy estate (approximately 300 branches): reduced pharmacist time from 60 hours to 6 hours per store per month, enabling the network to claim approximately £1M in revenue',
|
||||
'Led creation of national induction training plan and eLearning modules for all new pharmacy staff, with enhanced focus on leadership development for non-pharmacist team members',
|
||||
'Supervised two staff members through NVQ3 qualifications to pharmacy technician registration; full HR responsibilities including recruitment, performance management, and grievances',
|
||||
],
|
||||
outcomes: [
|
||||
'National process adoption across approximately 300 Tesco pharmacy branches',
|
||||
'Approximately £1M revenue enabled through streamlined asthma screening',
|
||||
'54 hours per store per month freed through process improvement',
|
||||
'Two team members developed to pharmacy technician registration',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'INN001', description: 'Innovation: asthma screening, national adoption, approximately £1M revenue' },
|
||||
{ code: 'TRN001', description: 'Training: national induction programme and eLearning' },
|
||||
{ code: 'LEA002', description: 'Leadership: staff development to technician registration' },
|
||||
],
|
||||
},
|
||||
'duty-pharmacy-manager-2016': {
|
||||
description: 'Provided clinical leadership and operational management across community pharmacy services at Tesco PLC in Great Yarmouth, progressing from newly qualified pharmacist to acting pharmacy manager within two months. Developed early expertise in service development, quality improvement, and the intersection of clinical practice and operational efficiency that would define the trajectory of the career ahead.',
|
||||
details: [
|
||||
'Led NMS and asthma referral service development, improving uptake and patient outcomes',
|
||||
'Devised a quality payments solution adopted nationally across the Tesco pharmacy estate',
|
||||
'Built clinical foundation in medicines optimisation, patient safety, and community pharmacy operations',
|
||||
],
|
||||
outcomes: [
|
||||
'Service development leadership recognised regionally',
|
||||
'National adoption of quality payments approach across Tesco estate',
|
||||
'Strong clinical grounding established for progression to pharmacy management',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'SVC001', description: 'Service development: NMS and asthma referrals' },
|
||||
{ code: 'INN002', description: 'Innovation: national quality payments solution' },
|
||||
],
|
||||
},
|
||||
'pre-reg-pharmacist-2015': {
|
||||
description: 'Completed pre-registration training at Paydens Pharmacy across multiple community pharmacy sites in Tunbridge Wells and Ashford, Kent. Developed core clinical competencies and demonstrated initiative through expanding clinical services and delivering measurable quality improvements during the training year.',
|
||||
details: [
|
||||
'Expanded PGD clinical services: NRT, EHC, and chlamydia screening programmes across multiple Paydens branches',
|
||||
'Improved NMS audit completion rate from under 10% to 50 to 60% through process redesign',
|
||||
'Developed a palliative care screening pathway for community pharmacy setting',
|
||||
'Gained broad operational experience across multiple pharmacy sites',
|
||||
],
|
||||
outcomes: [
|
||||
'Successfully registered with GPhC in August 2016',
|
||||
'Clinical service expansion adopted across multiple Paydens branches',
|
||||
'Established reputation for quality improvement and proactive service development',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'PGD001', description: 'Clinical services: NRT, EHC, chlamydia PGDs' },
|
||||
{ code: 'AUD001', description: 'Audit: NMS completion under 10% to 50 to 60%' },
|
||||
{ code: 'PAL001', description: 'Palliative care: community screening pathway' },
|
||||
],
|
||||
},
|
||||
'uea-mpharm-2011': {
|
||||
description: 'Completed four-year integrated Master of Pharmacy degree at the University of East Anglia, building a strong foundation in pharmaceutical sciences, clinical pharmacy, pharmacology, therapeutics, and research methodology. Demonstrated academic excellence through a distinction-grade research project and active engagement in university leadership.',
|
||||
details: [
|
||||
'Independent research project on drug delivery and cocrystals: 75.1% (Distinction)',
|
||||
'4th year OSCE: 80%',
|
||||
'President of UEA Pharmacy Society',
|
||||
],
|
||||
outcomes: [
|
||||
'Strong academic foundation in pharmaceutical sciences and therapeutics',
|
||||
'Research skills developed through independent project work',
|
||||
'Leadership experience through society presidency',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'RES001', description: 'Research: drug delivery and cocrystals (Distinction)' },
|
||||
{ code: 'SOC001', description: 'Leadership: UEA Pharmacy Society President' },
|
||||
],
|
||||
},
|
||||
'highworth-alevels-2009': {
|
||||
description: 'Completed A-Level studies at Highworth Grammar School in Ashford, Kent, achieving strong results in mathematics and sciences that provided the academic foundation for pursuing pharmacy.',
|
||||
details: [
|
||||
'Mathematics: A*',
|
||||
'Chemistry: B',
|
||||
'Politics: C',
|
||||
],
|
||||
outcomes: [
|
||||
'Strong mathematical foundation for data-driven career',
|
||||
'Science grounding for pharmacy degree entry',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'MATH01', description: 'Mathematics A*' },
|
||||
{ code: 'CHEM01', description: 'Chemistry B' },
|
||||
],
|
||||
},
|
||||
},
|
||||
} as const satisfies ProfileContent
|
||||
+33
-133
@@ -1,4 +1,5 @@
|
||||
import { skills } from '@/data/skills'
|
||||
import { getTimelineNarrativeEntry } from '@/lib/profile-content'
|
||||
import type {
|
||||
CodedEntry,
|
||||
Consultation,
|
||||
@@ -23,24 +24,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2025,
|
||||
endYear: 2025,
|
||||
},
|
||||
description: 'Returned to substantive Deputy Head role following commencement of ICB-wide organisational consultation. Led strategic delivery of population health initiatives and data-driven medicines optimisation across Norfolk & Waveney ICS, reporting to Associate Director of Pharmacy with presentation accountability to Chief Medical Officer and system-level programme boards.',
|
||||
details: [
|
||||
'Identified £14.6M efficiency programme through comprehensive data analysis',
|
||||
'Built Python-based switching algorithm: 14,000 patients identified, £2.6M annual savings',
|
||||
'Automated incentive scheme analysis: 50% reduction in targeted prescribing within 2 months',
|
||||
],
|
||||
outcomes: [
|
||||
'Achieved over-target performance by October 2025',
|
||||
'£2M on target for delivery this financial year',
|
||||
'Presented to CMO bimonthly with evidence-based recommendations',
|
||||
'Led transformation to patient-level SQL analytics',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'EFF001', description: 'Efficiency programme: £14.6M identified' },
|
||||
{ code: 'ALG001', description: 'Algorithm: 14,000 patients, £2.6M savings' },
|
||||
{ code: 'AUT001', description: 'Automation: 50% prescribing reduction in 2mo' },
|
||||
{ code: 'SQL001', description: 'Data transformation: practice→patient level' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('interim-head-2025').description,
|
||||
details: [...getTimelineNarrativeEntry('interim-head-2025').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('interim-head-2025').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('interim-head-2025').codedEntries],
|
||||
skills: [
|
||||
'population-health',
|
||||
'medicines-optimisation',
|
||||
@@ -84,26 +71,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2024,
|
||||
endYear: null,
|
||||
},
|
||||
description: 'Driving data analytics strategy for medicines optimisation, developing bespoke datasets and analytical frameworks from messy, real-world GP prescribing data to identify efficiency opportunities and address health inequalities across the integrated care system.',
|
||||
details: [
|
||||
'Managed £220M prescribing budget with sophisticated forecasting models',
|
||||
'Created comprehensive medicines data table with dm+d integration, morphine equivalents, Anticholinergic Burden scoring',
|
||||
'Led financial scenario modelling for DOAC switching programme',
|
||||
'Renegotiated pharmaceutical rebate terms securing improved commercial position',
|
||||
'Supported commissioning of tirzepatide (NICE TA1026) with financial projections',
|
||||
'Developed Python-based controlled drug monitoring system for population-scale OME tracking',
|
||||
],
|
||||
outcomes: [
|
||||
'Single source of truth established for all medicines analytics',
|
||||
'GP-led model adopted for tirzepatide delivery following executive sign-off',
|
||||
'Team data fluency improved through training, documentation, and self-serve tools',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'BUD001', description: 'Budget management: £220M oversight' },
|
||||
{ code: 'DAT001', description: 'Data infrastructure: dm+d integration' },
|
||||
{ code: 'LEA001', description: 'Leadership: team data literacy programme' },
|
||||
{ code: 'MON001', description: 'Monitoring: CD OME tracking system' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('deputy-head-2024').description,
|
||||
details: [...getTimelineNarrativeEntry('deputy-head-2024').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('deputy-head-2024').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('deputy-head-2024').codedEntries],
|
||||
skills: [
|
||||
'population-health',
|
||||
'medicines-optimisation',
|
||||
@@ -149,23 +120,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2022,
|
||||
endYear: 2024,
|
||||
},
|
||||
description: 'Led implementation of NICE technology appraisals and high-cost drug pathways across the ICS. Wrote most of the system\'s high-cost drug pathways—spanning rheumatology, ophthalmology (wet AMD, DMO, RVO), dermatology, gastroenterology, neurology, and migraine—balancing legal requirements to implement TAs against financial costs and local clinical preferences.',
|
||||
details: [
|
||||
'Developed software automating Blueteq prior approval form creation',
|
||||
'Integrated Blueteq data with secondary care activity databases',
|
||||
'Created Python-based Sankey chart analysis tool for patient pathway visualisation',
|
||||
],
|
||||
outcomes: [
|
||||
'70% reduction in required Blueteq forms, 200 hours immediate savings',
|
||||
'Ongoing 7–8 hours weekly efficiency gains',
|
||||
'Accurate high-cost drug spend tracking enabled',
|
||||
'Trusts enabled to audit compliance and identify improvement opportunities',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'AUT002', description: 'Automation: Blueteq form generation, 70% reduction' },
|
||||
{ code: 'DAT002', description: 'Data integration: Blueteq + secondary care' },
|
||||
{ code: 'VIS001', description: 'Visualisation: Sankey pathway analysis tool' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('high-cost-drugs-2022').description,
|
||||
details: [...getTimelineNarrativeEntry('high-cost-drugs-2022').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('high-cost-drugs-2022').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('high-cost-drugs-2022').codedEntries],
|
||||
skills: [
|
||||
'medicines-optimisation',
|
||||
'nice-ta',
|
||||
@@ -203,23 +161,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2017,
|
||||
endYear: 2022,
|
||||
},
|
||||
description: 'Managed all pharmacy operations with full autonomy across a 100-hour contract, leading regional KPI delivery initiatives and contributing to national operational improvements. Served as Local Pharmaceutical Committee representative for Norfolk.',
|
||||
details: [
|
||||
'Identified and shared asthma screening process adopted nationally across Tesco pharmacy estate (~300 branches)',
|
||||
'Led creation of national induction training plan and eLearning modules',
|
||||
'Supervised two staff members through NVQ3 qualifications to pharmacy technician registration',
|
||||
],
|
||||
outcomes: [
|
||||
'Reduced pharmacist time from ~60 hours to 6 hours per store per month',
|
||||
'Network enabled to claim approximately £1M in revenue',
|
||||
'Enhanced leadership development for non-pharmacist team members',
|
||||
'Full HR responsibilities including recruitment, performance management, grievances',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'INN001', description: 'Innovation: Asthma screening, ~£1M national revenue' },
|
||||
{ code: 'TRN001', description: 'Training: National induction programme' },
|
||||
{ code: 'LEA002', description: 'Leadership: Staff development to technician registration' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('pharmacy-manager-2017').description,
|
||||
details: [...getTimelineNarrativeEntry('pharmacy-manager-2017').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('pharmacy-manager-2017').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('pharmacy-manager-2017').codedEntries],
|
||||
skills: [
|
||||
'medicines-optimisation',
|
||||
'team-development',
|
||||
@@ -253,21 +198,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2016,
|
||||
endYear: 2017,
|
||||
},
|
||||
description: 'Provided clinical leadership and operational management across community pharmacy services, developing early expertise in service development and quality improvement. Contributed to national clinical innovation initiatives while building foundational skills in medicines optimisation and stakeholder engagement.',
|
||||
details: [
|
||||
'Led NMS and asthma referral service development, improving uptake and patient outcomes',
|
||||
'Devised quality payments solution adopted nationally across Tesco pharmacy estate',
|
||||
'Built clinical foundation in medicines optimisation, patient safety, and community pharmacy operations',
|
||||
],
|
||||
outcomes: [
|
||||
'Service development leadership recognised regionally',
|
||||
'National adoption of quality payments approach',
|
||||
'Strong clinical grounding established for progression to management',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'SVC001', description: 'Service development: NMS & asthma referrals' },
|
||||
{ code: 'INN002', description: 'Innovation: National quality payments solution' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('duty-pharmacy-manager-2016').description,
|
||||
details: [...getTimelineNarrativeEntry('duty-pharmacy-manager-2016').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('duty-pharmacy-manager-2016').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('duty-pharmacy-manager-2016').codedEntries],
|
||||
skills: [
|
||||
'medicines-optimisation',
|
||||
'data-analysis',
|
||||
@@ -297,23 +231,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2015,
|
||||
endYear: 2016,
|
||||
},
|
||||
description: 'Completed pre-registration training across multiple community pharmacy sites, developing core clinical competencies and service delivery skills. Demonstrated initiative through expanding clinical services and delivering measurable quality improvements during the training year.',
|
||||
details: [
|
||||
'Expanded PGD clinical services: NRT, EHC, and chlamydia screening programmes',
|
||||
'Improved NMS audit completion rate from under 10% to 50–60% through process redesign',
|
||||
'Developed palliative care screening pathway for community pharmacy setting',
|
||||
'Gained broad operational experience across multiple pharmacy sites',
|
||||
],
|
||||
outcomes: [
|
||||
'Successfully registered with GPhC in August 2016',
|
||||
'Clinical service expansion adopted across multiple Paydens branches',
|
||||
'Established reputation for quality improvement and service development',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'PGD001', description: 'Clinical services: NRT, EHC, chlamydia PGDs' },
|
||||
{ code: 'AUD001', description: 'Audit: NMS completion <10% → 50-60%' },
|
||||
{ code: 'PAL001', description: 'Palliative care: Community screening pathway' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('pre-reg-pharmacist-2015').description,
|
||||
details: [...getTimelineNarrativeEntry('pre-reg-pharmacist-2015').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('pre-reg-pharmacist-2015').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('pre-reg-pharmacist-2015').codedEntries],
|
||||
skills: [
|
||||
'medicines-optimisation',
|
||||
'change-management',
|
||||
@@ -339,21 +260,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2011,
|
||||
endYear: 2015,
|
||||
},
|
||||
description: 'Completed four-year Master of Pharmacy degree at the University of East Anglia, building a strong foundation in pharmaceutical sciences, clinical pharmacy, and research methodology. Demonstrated academic excellence through a distinction-grade research project and active engagement in university life.',
|
||||
details: [
|
||||
'Independent research project on drug delivery and cocrystals: 75.1% (Distinction)',
|
||||
'4th year OSCE: 80%',
|
||||
'President of UEA Pharmacy Society',
|
||||
],
|
||||
outcomes: [
|
||||
'Strong academic foundation in pharmaceutical sciences',
|
||||
'Research skills developed through independent project work',
|
||||
'Leadership experience through society presidency',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'RES001', description: 'Research: Drug delivery & cocrystals (Distinction)' },
|
||||
{ code: 'SOC001', description: 'Leadership: UEA Pharmacy Society President' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('uea-mpharm-2011').description,
|
||||
details: [...getTimelineNarrativeEntry('uea-mpharm-2011').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('uea-mpharm-2011').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('uea-mpharm-2011').codedEntries],
|
||||
skills: ['medicines-optimisation', 'data-analysis'],
|
||||
skillStrengths: {
|
||||
'medicines-optimisation': 0.5,
|
||||
@@ -374,20 +284,10 @@ const timelineEntitySeeds: TimelineEntity[] = [
|
||||
startYear: 2009,
|
||||
endYear: 2011,
|
||||
},
|
||||
description: 'Completed A-Level studies at Highworth Grammar School in Ashford, Kent, achieving strong results in mathematics and sciences that provided the academic foundation for pursuing pharmacy.',
|
||||
details: [
|
||||
'Mathematics: A*',
|
||||
'Chemistry: B',
|
||||
'Politics: C',
|
||||
],
|
||||
outcomes: [
|
||||
'Strong mathematical foundation for data-driven career',
|
||||
'Science grounding for pharmacy degree entry',
|
||||
],
|
||||
codedEntries: [
|
||||
{ code: 'MATH01', description: 'Mathematics A*' },
|
||||
{ code: 'CHEM01', description: 'Chemistry B' },
|
||||
],
|
||||
description: getTimelineNarrativeEntry('highworth-alevels-2009').description,
|
||||
details: [...getTimelineNarrativeEntry('highworth-alevels-2009').details],
|
||||
outcomes: [...getTimelineNarrativeEntry('highworth-alevels-2009').outcomes],
|
||||
codedEntries: [...getTimelineNarrativeEntry('highworth-alevels-2009').codedEntries],
|
||||
skills: ['data-analysis'],
|
||||
skillStrengths: {
|
||||
'data-analysis': 0.2,
|
||||
|
||||
+3
-93
@@ -1,3 +1,5 @@
|
||||
import { getLLMCopy } from '@/lib/profile-content'
|
||||
|
||||
export interface ChatMessage {
|
||||
role: 'user' | 'assistant'
|
||||
content: string
|
||||
@@ -17,99 +19,7 @@ export function isLLMAvailable(): boolean {
|
||||
}
|
||||
|
||||
export function buildSystemPrompt(): string {
|
||||
return `You are a helpful assistant on Andy Charlwood's portfolio website. Answer questions about Andy's professional background using ONLY the information below.
|
||||
|
||||
## Profile
|
||||
Andy Charlwood — MPharm, GPhC Registered Pharmacist. Norwich, UK.
|
||||
Healthcare leader combining clinical pharmacy with Python, SQL, and data analytics (self-taught). Leading population health analytics for NHS Norfolk & Waveney ICB, serving 1.2M people. Specialises in prescribing data at scale — financial modelling, algorithm design, pathway development. Identified efficiency programmes worth £14.6M+ through automated analysis.
|
||||
|
||||
## Employment Timeline (IMPORTANT)
|
||||
- **NHS employment**: May 2022–present (all roles at NHS Norfolk & Waveney ICB). Total NHS service: ~4 years.
|
||||
- **Private sector**: Nov 2017–May 2022 at Tesco PLC (community pharmacy). This was NOT NHS employment.
|
||||
- GPhC registration (Aug 2016) is a professional licence, NOT an employer or NHS role.
|
||||
|
||||
## Career History
|
||||
|
||||
### [exp-interim-head-2025] Interim Head, Population Health & Data Analysis
|
||||
NHS Norfolk & Waveney ICB | May–Nov 2025
|
||||
Led population health initiatives and data-driven medicines optimisation, reporting to Associate Director of Pharmacy with accountability to CMO.
|
||||
- Identified £14.6M efficiency programme; achieved over-target performance by October 2025
|
||||
- Built Python switching algorithm: real-world GP prescribing data, 14,000 patients, £2.6M annual savings (£2M on target), compressed months into 3 days
|
||||
- Novel GP payment system linking rewards to savings; 50% prescribing reduction within 2 months
|
||||
- Presented to CMO bimonthly; led transformation to patient-level SQL analytics
|
||||
|
||||
### [exp-deputy-head-2024] Deputy Head, Population Health & Data Analysis
|
||||
NHS Norfolk & Waveney ICB | Jul 2024–Present (substantive role)
|
||||
Data analytics strategy for medicines optimisation from real-world GP prescribing data.
|
||||
- Managed £220M prescribing budget with forecasting models for proactive financial planning
|
||||
- Created comprehensive dm+d medicines data table: standardised strengths, morphine equivalents, Anticholinergic Burden scoring — single source of truth for all medicines analytics
|
||||
- Led DOAC switching financial modelling: interactive dashboard with rebate mechanics, patent expiry timelines
|
||||
- Renegotiated pharmaceutical rebate terms ahead of patent expiry
|
||||
- Tirzepatide commissioning (NICE TA1026): financial projections, cohort identification; authored executive paper advocating primary care model, driving system shift to GP-led delivery
|
||||
- Built Python controlled drug monitoring: oral morphine equivalents across all opioid prescriptions, patient-level tracking, high-risk identification, diversion detection
|
||||
- Improved team data fluency through training and self-serve tools
|
||||
|
||||
### [exp-high-cost-drugs-2022] High-Cost Drugs & Interface Pharmacist
|
||||
NHS Norfolk & Waveney ICB | May 2022–Jul 2024
|
||||
Led NICE TA implementation and high-cost drug pathways across the ICS. Pathways spanning: rheumatology, ophthalmology (wet AMD, DMO, RVO), dermatology, gastroenterology, neurology, migraine.
|
||||
- Blueteq automation: 70% form reduction, 200 hours immediate savings, 7–8 hours ongoing weekly gains
|
||||
- Integrated Blueteq with secondary care databases for accurate high-cost drug spend tracking
|
||||
- Python Sankey chart tool for patient pathway visualisation and trust compliance auditing
|
||||
|
||||
### [exp-pharmacy-manager-2017] Pharmacy Manager
|
||||
Tesco PLC (private sector, NOT NHS) | Nov 2017–May 2022
|
||||
Community pharmacy with full operational autonomy (100-hour contract). LPC representative for Norfolk.
|
||||
- Asthma screening process adopted nationally (~300 branches): reduced pharmacist time 60→6 hours/store/month, ~£1M revenue
|
||||
- Leadership training: Created national induction training plan and eLearning modules for Tesco pharmacy staff
|
||||
- Leadership development: Supervised two staff through NVQ3 to pharmacy technician registration; full HR responsibilities
|
||||
|
||||
## Projects
|
||||
|
||||
### [proj-inv-pharmetrics] PharMetrics Interactive Platform (2024, Live)
|
||||
Real-time medicines expenditure dashboard for NHS decision-makers. Tech: Power BI, SQL, DAX. Tracks £220M prescribing budget.
|
||||
|
||||
### [proj-inv-switching-algorithm] Patient Switching Algorithm (2025, Complete)
|
||||
Python algorithm using GP prescribing data to auto-identify patients for cost-effective alternatives. Tech: Python, Pandas, SQL. 14,000 patients, £2.6M annual savings, novel GP payment system.
|
||||
|
||||
### [proj-inv-blueteq-gen] Blueteq Generator (2023, Complete)
|
||||
Automated Blueteq prior approval form creation. Tech: Python, SQL. 70% form reduction, 200 hours immediate savings, 7–8 hours ongoing weekly gains.
|
||||
|
||||
### [proj-inv-cd-monitoring] CD Monitoring System (2024, Complete)
|
||||
Controlled drug monitoring calculating oral morphine equivalents (OME) across all opioid prescriptions. Tech: Python, SQL. Patient-level tracking, high-risk identification, diversion detection.
|
||||
|
||||
### [proj-inv-sankey-tool] Sankey Chart Analysis Tool (2023, Complete)
|
||||
Patient journey visualisation through high-cost drug pathways. Tech: Python, Matplotlib, SQL. Trust compliance auditing.
|
||||
|
||||
## Education
|
||||
|
||||
### [edu-0] NHS Mary Seacole Programme (2018)
|
||||
NHS Leadership Academy. Score: 78%. Covers change management, healthcare leadership, system-level thinking.
|
||||
|
||||
### [edu-1] MPharm (Hons) 2:1 — University of East Anglia (2011–2015)
|
||||
4-year integrated Master's degree. Research project on drug delivery and cocrystals: 75.1% (Distinction).
|
||||
|
||||
### [edu-2] A-Levels — Highworth Grammar School (2009–2011)
|
||||
Mathematics A*, Chemistry B, Politics C.
|
||||
|
||||
### [edu-3] GPhC Registration — General Pharmaceutical Council (August 2016–Present)
|
||||
Professional registration required to practise as a pharmacist in Great Britain.
|
||||
|
||||
## Skills
|
||||
Technical: [skill-data-analysis] Data Analysis (9yr, 95%), [skill-python] Python (6yr, 90%), [skill-sql] SQL (7yr, 88%), [skill-power-bi] Power BI (5yr, 92%), [skill-javascript-typescript] JavaScript/TypeScript (3yr, 70%), [skill-excel] Excel (9yr, 85%), [skill-algorithm-design] Algorithm Design (3yr, 82%), [skill-data-pipelines] Data Pipelines (2yr, 75%)
|
||||
Domain: [skill-medicines-optimisation] Medicines Optimisation (9yr, 95%), [skill-population-health] Population Health (3yr, 90%), [skill-nice-ta] NICE TA Implementation (3yr, 92%), [skill-health-economics] Health Economics (3yr, 80%), [skill-clinical-pathways] Clinical Pathways (3yr, 88%), [skill-controlled-drugs] Controlled Drugs (1yr, 85%)
|
||||
Leadership: [skill-budget-management] Budget Management (1yr, 90%), [skill-stakeholder-engagement] Stakeholder Engagement (3yr, 88%), [skill-pharma-negotiation] Pharmaceutical Negotiation (1yr, 82%), [skill-team-development] Team Development (8yr, 85%), [skill-change-management] Change Management (7yr, 80%), [skill-financial-modelling] Financial Modelling (1yr, 78%), [skill-executive-comms] Executive Communication (1yr, 85%)
|
||||
|
||||
## Response Rules
|
||||
1. Answer ONLY from the data above. If the answer is not in the data, say "I don't have that information" — never invent facts, roles, dates, achievements, URLs, or contact details.
|
||||
2. Distinguish NHS employment (May 2022–present, ~4 years, all at Norfolk & Waveney ICB) from private sector (Tesco PLC, Nov 2017–May 2022, community pharmacy). Never conflate the two. GPhC registration is a professional licence, not NHS employment.
|
||||
3. When asked broad questions about tools, skills, projects, or achievements across Andy's career, aggregate from ALL roles — do not limit your answer to one position.
|
||||
4. Cite exact numbers, dates, percentages, and outcomes. Never say "approximately" or "around" when exact figures exist in the data.
|
||||
5. For detailed or list-based questions, give a thorough answer covering all relevant items. For simple questions, be concise (2-4 sentences).
|
||||
|
||||
## Item References
|
||||
End your response with a single line listing relevant item IDs from the square-bracketed IDs above:
|
||||
[ITEMS: exp-deputy-head-2024, skill-python]
|
||||
Only include IDs that directly support your answer. Omit the line if none are relevant.`
|
||||
return getLLMCopy().systemPrompt
|
||||
}
|
||||
|
||||
function buildRequestBody(
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import { profileContent } from '@/data/profile-content'
|
||||
import type {
|
||||
AchievementCopyEntry,
|
||||
DeepReadonly,
|
||||
EducationCopyEntry,
|
||||
ExperienceEducationUICopy,
|
||||
LatestResultsCopy,
|
||||
LLMCopy,
|
||||
ProfileContent,
|
||||
QuickActionCopyEntry,
|
||||
SidebarCopy,
|
||||
SkillsUICopy,
|
||||
TimelineNarrativeId,
|
||||
TimelineNarrativeEntry,
|
||||
} from '@/types/profile-content'
|
||||
|
||||
export function getProfileContent(): ProfileContent {
|
||||
export function getProfileContent(): DeepReadonly<ProfileContent> {
|
||||
return profileContent
|
||||
}
|
||||
|
||||
@@ -14,14 +22,42 @@ export function getProfileSummaryText(): string {
|
||||
return profileContent.profile.patientSummaryNarrative
|
||||
}
|
||||
|
||||
export function getSidebarCopy(): SidebarCopy {
|
||||
export function getProfileSectionTitle(): string {
|
||||
return profileContent.profile.sectionTitle
|
||||
}
|
||||
|
||||
export function getLatestResultsCopy(): DeepReadonly<LatestResultsCopy> {
|
||||
return profileContent.profile.latestResults
|
||||
}
|
||||
|
||||
export function getSidebarCopy(): DeepReadonly<SidebarCopy> {
|
||||
return profileContent.profile.sidebar
|
||||
}
|
||||
|
||||
export function getExperienceEducationUICopy(): DeepReadonly<ExperienceEducationUICopy> {
|
||||
return profileContent.experienceEducation.ui
|
||||
}
|
||||
|
||||
export function getSkillsUICopy(): DeepReadonly<SkillsUICopy> {
|
||||
return profileContent.skillsNarrative.ui
|
||||
}
|
||||
|
||||
export function getSearchQuickActions(): ReadonlyArray<QuickActionCopyEntry> {
|
||||
return profileContent.searchChat.quickActions
|
||||
}
|
||||
|
||||
export function getLLMCopy(): LLMCopy {
|
||||
export function getAchievementEntries(): ReadonlyArray<AchievementCopyEntry> {
|
||||
return profileContent.resultsNarrative.achievements
|
||||
}
|
||||
|
||||
export function getEducationEntries(): ReadonlyArray<EducationCopyEntry> {
|
||||
return profileContent.experienceEducation.educationEntries
|
||||
}
|
||||
|
||||
export function getLLMCopy(): DeepReadonly<LLMCopy> {
|
||||
return profileContent.searchChat.llm
|
||||
}
|
||||
|
||||
export function getTimelineNarrativeEntry(entityId: TimelineNarrativeId): DeepReadonly<TimelineNarrativeEntry> {
|
||||
return profileContent.timelineNarrative[entityId]
|
||||
}
|
||||
|
||||
+31
-111
@@ -1,10 +1,15 @@
|
||||
import Fuse from 'fuse.js'
|
||||
|
||||
import { consultations } from '@/data/consultations'
|
||||
import { documents } from '@/data/documents'
|
||||
import { investigations } from '@/data/investigations'
|
||||
import { skills } from '@/data/skills'
|
||||
import { kpis } from '@/data/kpis'
|
||||
import { timelineConsultations } from '@/data/timeline'
|
||||
import {
|
||||
getAchievementEntries,
|
||||
getEducationEntries,
|
||||
getSearchQuickActions,
|
||||
} from '@/lib/profile-content'
|
||||
import type { DetailPanelContent } from '@/types/pmr'
|
||||
|
||||
export type PaletteSection = 'Experience' | 'Core Skills' | 'Significant Interventions' | 'Achievements' | 'Education' | 'Quick Actions'
|
||||
@@ -34,7 +39,7 @@ export function buildPaletteData(): PaletteItem[] {
|
||||
const items: PaletteItem[] = []
|
||||
|
||||
// Experience — all 4 roles from consultations.ts, open detail panel on select
|
||||
consultations.forEach((c) => {
|
||||
timelineConsultations.forEach((c) => {
|
||||
items.push({
|
||||
id: `exp-${c.id}`,
|
||||
title: c.role,
|
||||
@@ -76,39 +81,12 @@ export function buildPaletteData(): PaletteItem[] {
|
||||
})
|
||||
|
||||
// Achievements — open corresponding KPI detail panel
|
||||
const achievementEntries: Array<{ title: string; sub: string; keywords: string; kpiId: string }> = [
|
||||
{
|
||||
title: '\u00a314.6M Efficiency Savings Identified',
|
||||
sub: 'Data-driven prescribing interventions',
|
||||
keywords: '14.6m efficiency savings identified data-driven prescribing interventions money cost',
|
||||
kpiId: 'savings',
|
||||
},
|
||||
{
|
||||
title: '\u00a3220M Budget Oversight',
|
||||
sub: 'Full analytical accountability to ICB board',
|
||||
keywords: '220m budget oversight analytical accountability icb board',
|
||||
kpiId: 'budget',
|
||||
},
|
||||
{
|
||||
title: 'Power BI Dashboards for 200+ Users',
|
||||
sub: 'Clinicians & commissioners across ICB',
|
||||
keywords: 'power bi dashboards 200 users clinicians commissioners',
|
||||
kpiId: 'years',
|
||||
},
|
||||
{
|
||||
title: '1.2M Population Served',
|
||||
sub: 'Norfolk & Waveney Integrated Care System',
|
||||
keywords: '1.2m population served norfolk waveney ics integrated care system',
|
||||
kpiId: 'population',
|
||||
},
|
||||
]
|
||||
|
||||
achievementEntries.forEach((entry, i) => {
|
||||
getAchievementEntries().forEach((entry, i) => {
|
||||
const kpi = kpis.find(k => k.id === entry.kpiId)
|
||||
items.push({
|
||||
id: `ach-${i}`,
|
||||
title: entry.title,
|
||||
subtitle: entry.sub,
|
||||
subtitle: entry.subtitle,
|
||||
section: 'Achievements',
|
||||
iconVariant: 'amber',
|
||||
iconType: 'achievement',
|
||||
@@ -120,34 +98,11 @@ export function buildPaletteData(): PaletteItem[] {
|
||||
})
|
||||
|
||||
// Education — matching actual entries in EducationSubsection
|
||||
const educationEntries: Array<{ title: string; sub: string; keywords: string }> = [
|
||||
{
|
||||
title: 'NHS Leadership Academy \u2014 Mary Seacole Programme',
|
||||
sub: 'NHS Leadership Academy \u00b7 2018',
|
||||
keywords: 'nhs leadership academy mary seacole programme 2018 qualification management',
|
||||
},
|
||||
{
|
||||
title: 'MPharm (Hons) \u2014 2:1',
|
||||
sub: 'University of East Anglia \u00b7 2011\u20132015',
|
||||
keywords: 'mpharm hons 2:1 university east anglia uea 2011 2015 pharmacy degree',
|
||||
},
|
||||
{
|
||||
title: 'A-Levels',
|
||||
sub: 'Highworth Grammar School \u00b7 2009\u20132011',
|
||||
keywords: 'a-levels mathematics chemistry politics highworth grammar school 2009 2011',
|
||||
},
|
||||
{
|
||||
title: 'GPhC Registration',
|
||||
sub: 'General Pharmaceutical Council \u00b7 August 2016',
|
||||
keywords: 'gphc registration general pharmaceutical council 2016 registered pharmacist',
|
||||
},
|
||||
]
|
||||
|
||||
educationEntries.forEach((entry, i) => {
|
||||
getEducationEntries().forEach((entry, i) => {
|
||||
items.push({
|
||||
id: `edu-${i}`,
|
||||
title: entry.title,
|
||||
subtitle: entry.sub,
|
||||
subtitle: entry.subtitle,
|
||||
section: 'Education',
|
||||
iconVariant: 'purple',
|
||||
iconType: 'edu',
|
||||
@@ -157,43 +112,20 @@ export function buildPaletteData(): PaletteItem[] {
|
||||
})
|
||||
|
||||
// Quick Actions
|
||||
const quickActions: Array<{ title: string; sub: string; keywords: string; action: PaletteAction }> = [
|
||||
{
|
||||
title: 'Download CV',
|
||||
sub: 'Export as PDF',
|
||||
keywords: 'download cv export pdf resume',
|
||||
action: { type: 'download' },
|
||||
},
|
||||
{
|
||||
title: 'Send Email',
|
||||
sub: 'andy@charlwood.xyz',
|
||||
keywords: 'send email contact andy charlwood',
|
||||
action: { type: 'link', url: 'mailto:andy@charlwood.xyz' },
|
||||
},
|
||||
{
|
||||
title: 'View LinkedIn',
|
||||
sub: 'Professional profile',
|
||||
keywords: 'view linkedin professional profile social',
|
||||
action: { type: 'link', url: 'https://linkedin.com/in/andycharlwood' },
|
||||
},
|
||||
{
|
||||
title: 'View Projects',
|
||||
sub: 'GitHub & portfolio',
|
||||
keywords: 'view projects github portfolio code repositories',
|
||||
action: { type: 'link', url: 'https://github.com/andycharlwood' },
|
||||
},
|
||||
]
|
||||
getSearchQuickActions().forEach((entry, i) => {
|
||||
const action: PaletteAction = entry.type === 'download'
|
||||
? { type: 'download' }
|
||||
: { type: 'link', url: entry.url }
|
||||
|
||||
quickActions.forEach((entry, i) => {
|
||||
items.push({
|
||||
id: `action-${i}`,
|
||||
title: entry.title,
|
||||
subtitle: entry.sub,
|
||||
subtitle: entry.subtitle,
|
||||
section: 'Quick Actions',
|
||||
iconVariant: 'teal',
|
||||
iconType: 'action',
|
||||
keywords: entry.keywords,
|
||||
action: entry.action,
|
||||
action,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -248,7 +180,7 @@ export function buildEmbeddingTexts(): Array<{ id: string; text: string }> {
|
||||
const texts: Array<{ id: string; text: string }> = []
|
||||
|
||||
// Consultations (Experience) — enriched with plan outcomes, employer classification, clinical specialties
|
||||
consultations.forEach((c) => {
|
||||
timelineConsultations.forEach((c) => {
|
||||
const isNHS = c.organization.includes('NHS') || c.organization.includes('ICB')
|
||||
const employer = isNHS
|
||||
? `NHS employer: ${c.organization}`
|
||||
@@ -309,14 +241,8 @@ export function buildEmbeddingTexts(): Array<{ id: string; text: string }> {
|
||||
})
|
||||
|
||||
// KPI-backed Achievements — enriched with full story context and outcomes
|
||||
const achievementMap: Array<{ id: string; title: string; subtitle: string; kpiId: string }> = [
|
||||
{ id: 'ach-0', title: '£14.6M Efficiency Savings Identified', subtitle: 'Data-driven prescribing interventions', kpiId: 'savings' },
|
||||
{ id: 'ach-1', title: '£220M Budget Oversight', subtitle: 'Full analytical accountability to ICB board', kpiId: 'budget' },
|
||||
{ id: 'ach-2', title: 'Power BI Dashboards for 200+ Users', subtitle: 'Clinicians & commissioners across ICB', kpiId: 'years' },
|
||||
{ id: 'ach-3', title: '1.2M Population Served', subtitle: 'Norfolk & Waveney Integrated Care System', kpiId: 'population' },
|
||||
]
|
||||
|
||||
achievementMap.forEach((entry) => {
|
||||
getAchievementEntries().forEach((entry, index) => {
|
||||
const id = `ach-${index}`
|
||||
const kpi = kpis.find(k => k.id === entry.kpiId)
|
||||
const explanation = kpi?.explanation ?? ''
|
||||
const storyParts: string[] = []
|
||||
@@ -327,7 +253,7 @@ export function buildEmbeddingTexts(): Array<{ id: string; text: string }> {
|
||||
storyParts.push(`Outcomes: ${kpi.story.outcomes.join('. ')}.`)
|
||||
}
|
||||
texts.push({
|
||||
id: entry.id,
|
||||
id,
|
||||
text: `Achievement: ${entry.title}. ${entry.subtitle}. ${explanation} ${storyParts.join(' ')}`,
|
||||
})
|
||||
})
|
||||
@@ -352,14 +278,15 @@ export function buildEmbeddingTexts(): Array<{ id: string; text: string }> {
|
||||
})
|
||||
|
||||
// Education — enriched with research grades and specific subject details
|
||||
const educationItems: Array<{ id: string; docId: string; fallbackTitle: string; fallbackSub: string }> = [
|
||||
{ id: 'edu-0', docId: 'doc-mary-seacole', fallbackTitle: 'NHS Leadership Academy — Mary Seacole Programme', fallbackSub: 'NHS Leadership Academy · 2018' },
|
||||
{ id: 'edu-1', docId: 'doc-mpharm', fallbackTitle: 'MPharm (Hons) — 2:1', fallbackSub: 'University of East Anglia · 2011–2015' },
|
||||
{ id: 'edu-2', docId: 'doc-alevels', fallbackTitle: 'A-Levels', fallbackSub: 'Highworth Grammar School · 2009–2011' },
|
||||
{ id: 'edu-3', docId: 'doc-gphc', fallbackTitle: 'GPhC Registration', fallbackSub: 'General Pharmaceutical Council · August 2016' },
|
||||
const educationItems: Array<{ id: string; docId: string }> = [
|
||||
{ id: 'edu-0', docId: 'doc-mary-seacole' },
|
||||
{ id: 'edu-1', docId: 'doc-mpharm' },
|
||||
{ id: 'edu-2', docId: 'doc-alevels' },
|
||||
{ id: 'edu-3', docId: 'doc-gphc' },
|
||||
]
|
||||
|
||||
educationItems.forEach((entry) => {
|
||||
educationItems.forEach((entry, index) => {
|
||||
const fallback = getEducationEntries()[index]
|
||||
const doc = documents.find(d => d.id === entry.docId)
|
||||
if (doc) {
|
||||
const research = doc.researchDetail ? ` Research: ${doc.researchDetail}.` : ''
|
||||
@@ -372,22 +299,15 @@ export function buildEmbeddingTexts(): Array<{ id: string; text: string }> {
|
||||
} else {
|
||||
texts.push({
|
||||
id: entry.id,
|
||||
text: `Education: ${entry.fallbackTitle}. ${entry.fallbackSub}.`,
|
||||
text: `Education: ${fallback?.title ?? ''}. ${fallback?.subtitle ?? ''}.`,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Quick Actions
|
||||
const quickActionTexts: Array<{ id: string; title: string; subtitle: string }> = [
|
||||
{ id: 'action-0', title: 'Download CV', subtitle: 'Export as PDF' },
|
||||
{ id: 'action-1', title: 'Send Email', subtitle: 'andy@charlwood.xyz' },
|
||||
{ id: 'action-2', title: 'View LinkedIn', subtitle: 'Professional profile' },
|
||||
{ id: 'action-3', title: 'View Projects', subtitle: 'GitHub & portfolio' },
|
||||
]
|
||||
|
||||
quickActionTexts.forEach((entry) => {
|
||||
getSearchQuickActions().forEach((entry, index) => {
|
||||
texts.push({
|
||||
id: entry.id,
|
||||
id: `action-${index}`,
|
||||
text: `${entry.title}. ${entry.subtitle}.`,
|
||||
})
|
||||
})
|
||||
|
||||
+111
-47
@@ -1,68 +1,132 @@
|
||||
export type DeepReadonly<T> =
|
||||
T extends (...args: never[]) => unknown
|
||||
? T
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepReadonly<U>>
|
||||
: T extends object
|
||||
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
|
||||
: T
|
||||
|
||||
export interface AchievementCopyEntry {
|
||||
title: string
|
||||
subtitle: string
|
||||
keywords: string
|
||||
kpiId: string
|
||||
readonly title: string
|
||||
readonly subtitle: string
|
||||
readonly keywords: string
|
||||
readonly kpiId: string
|
||||
}
|
||||
|
||||
export interface EducationCopyEntry {
|
||||
title: string
|
||||
subtitle: string
|
||||
keywords: string
|
||||
readonly title: string
|
||||
readonly subtitle: string
|
||||
readonly keywords: string
|
||||
}
|
||||
|
||||
export interface QuickActionCopyEntry {
|
||||
title: string
|
||||
subtitle: string
|
||||
keywords: string
|
||||
type: 'download' | 'link'
|
||||
url?: string
|
||||
export type QuickActionCopyEntry =
|
||||
| {
|
||||
readonly title: string
|
||||
readonly subtitle: string
|
||||
readonly keywords: string
|
||||
readonly type: 'download'
|
||||
}
|
||||
| {
|
||||
readonly title: string
|
||||
readonly subtitle: string
|
||||
readonly keywords: string
|
||||
readonly type: 'link'
|
||||
readonly url: string
|
||||
}
|
||||
|
||||
export interface TimelineNarrativeCodeEntry {
|
||||
readonly code: string
|
||||
readonly description: string
|
||||
}
|
||||
|
||||
export interface TimelineNarrativeEntry {
|
||||
readonly description: string
|
||||
readonly details: ReadonlyArray<string>
|
||||
readonly outcomes: ReadonlyArray<string>
|
||||
readonly codedEntries: ReadonlyArray<TimelineNarrativeCodeEntry>
|
||||
}
|
||||
|
||||
export type TimelineNarrativeId =
|
||||
| 'interim-head-2025'
|
||||
| 'deputy-head-2024'
|
||||
| 'high-cost-drugs-2022'
|
||||
| 'pharmacy-manager-2017'
|
||||
| 'duty-pharmacy-manager-2016'
|
||||
| 'pre-reg-pharmacist-2015'
|
||||
| 'uea-mpharm-2011'
|
||||
| 'highworth-alevels-2009'
|
||||
|
||||
export interface SidebarCopy {
|
||||
sectionTitle: string
|
||||
roleTitle: string
|
||||
gphcLabel: string
|
||||
educationLabel: string
|
||||
locationLabel: string
|
||||
phoneLabel: string
|
||||
emailLabel: string
|
||||
registeredLabel: string
|
||||
navigationTitle: string
|
||||
tagsTitle: string
|
||||
alertsTitle: string
|
||||
searchLabel: string
|
||||
searchAriaLabel: string
|
||||
searchShortcut: string
|
||||
menuLabel: string
|
||||
readonly sectionTitle: string
|
||||
readonly roleTitle: string
|
||||
readonly gphcLabel: string
|
||||
readonly educationLabel: string
|
||||
readonly locationLabel: string
|
||||
readonly phoneLabel: string
|
||||
readonly emailLabel: string
|
||||
readonly registeredLabel: string
|
||||
readonly navigationTitle: string
|
||||
readonly tagsTitle: string
|
||||
readonly alertsTitle: string
|
||||
readonly searchLabel: string
|
||||
readonly searchAriaLabel: string
|
||||
readonly searchShortcut: string
|
||||
readonly menuLabel: string
|
||||
}
|
||||
|
||||
export interface LatestResultsCopy {
|
||||
readonly title: string
|
||||
readonly rightText: string
|
||||
readonly helperText: string
|
||||
readonly evidenceCta: string
|
||||
}
|
||||
|
||||
export interface ExperienceEducationUICopy {
|
||||
readonly educationLabel: string
|
||||
readonly employmentLabel: string
|
||||
readonly viewFullRecordLabel: string
|
||||
}
|
||||
|
||||
export interface SkillsCategoryCopyEntry {
|
||||
readonly id: 'Technical' | 'Domain' | 'Leadership'
|
||||
readonly label: string
|
||||
}
|
||||
|
||||
export interface SkillsUICopy {
|
||||
readonly sectionTitle: string
|
||||
readonly rightText: string
|
||||
readonly itemCountSuffix: string
|
||||
readonly yearsSuffix: string
|
||||
readonly viewAllLabel: string
|
||||
readonly categories: ReadonlyArray<SkillsCategoryCopyEntry>
|
||||
}
|
||||
|
||||
export interface LLMCopy {
|
||||
systemPrompt: string
|
||||
readonly systemPrompt: string
|
||||
}
|
||||
|
||||
export interface ProfileContent {
|
||||
profile: {
|
||||
patientSummaryNarrative: string
|
||||
latestResults: {
|
||||
title: string
|
||||
rightText: string
|
||||
helperText: string
|
||||
evidenceCta: string
|
||||
}
|
||||
sidebar: SidebarCopy
|
||||
readonly profile: {
|
||||
readonly sectionTitle: string
|
||||
readonly patientSummaryNarrative: string
|
||||
readonly latestResults: LatestResultsCopy
|
||||
readonly sidebar: SidebarCopy
|
||||
}
|
||||
experienceEducation: {
|
||||
educationEntries: ReadonlyArray<EducationCopyEntry>
|
||||
readonly experienceEducation: {
|
||||
readonly educationEntries: ReadonlyArray<EducationCopyEntry>
|
||||
readonly ui: ExperienceEducationUICopy
|
||||
}
|
||||
skillsNarrative: {
|
||||
summary: string
|
||||
readonly skillsNarrative: {
|
||||
readonly summary: string
|
||||
readonly ui: SkillsUICopy
|
||||
}
|
||||
resultsNarrative: {
|
||||
achievements: ReadonlyArray<AchievementCopyEntry>
|
||||
readonly resultsNarrative: {
|
||||
readonly achievements: ReadonlyArray<AchievementCopyEntry>
|
||||
}
|
||||
searchChat: {
|
||||
quickActions: ReadonlyArray<QuickActionCopyEntry>
|
||||
llm: LLMCopy
|
||||
readonly searchChat: {
|
||||
readonly quickActions: ReadonlyArray<QuickActionCopyEntry>
|
||||
readonly llm: LLMCopy
|
||||
}
|
||||
readonly timelineNarrative: Readonly<Record<TimelineNarrativeId, TimelineNarrativeEntry>>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user