...
TraineeProfile: add
linkedProgrammeMembership[]: {uuid, when, how, metrics}
to placement subdocument. The actual details of the PM are already held in theprogrammeMembership[]
subdocuments.tis-trainee-sync: add
placementProgrammeMembership
collection to be synced from TIS, and triggering re-enrichment of related placements. For the first phase, the only sync will be the Placement-ProgrammeMembership-Link table from TIS. When an INSERT/UPDATE/DELETE record arrives in tis-trainee-sync for that table we would need to update the sync collection, re-enrich the related placement and update the trainee profile accordingly.
In addition, send this new trainee profile content to the NDW.
In phase 1, the newlinkedProgrammeMembership
data should not affect TSS credentials, forms, notifications or actions,
...
Notes:
Post linkage (not reliable):
Sometimes placements ‘borrow’ post from another programme because otherwise post management becomes laborious, e.g. Emergency Medicine Higher → EM run-through; GP using Obstetrics etc. in hospital placement.
...
When the notifications pilot was run, we had a slightly different rule to identify placements that belonged to pilot programme memberships. This rule had a similar rate of ambiguous / missing matches (and in the context we didn't mind, since it was intended purely to identify if there was at least one programme membership that the placement might belong to that was in the pilot, rather than identify that PM unambiguously).
New rule:
- placement start date between PM start and end dates OR
- placement start date no more than 13 days before the PM start date AND placement end date no later than PM end dateThe rule we used for the pilot logic:
- placement start date not before 1st of month of PM start date AND placement start date on no later than PM end date
Comparison:
SQL new rule (example for no matches, 2023):SELECT
count(*)
-- pl.id, pl.dateFrom, pl.dateTo, matches, minpmuuid, pmmin.programmeStartDate, pmmin.programmeEndDate, maxpmuuid, pmmax.programmeStartDate, pmmax.programmeEndDate
FROM tcs.Placement pl JOIN
(
SELECT id, sum(ismatch) as matches, min(uuid) as minpmuuid, max(uuid) as maxpmuuid FROM
(
SELECT pl.id, pm.uuid, if((pl.dateFrom >= pm.programmeStartDate AND pl.dateFrom <= pm.programmeEndDate)
OR (date_add(pl.dateFrom, interval 13 day) >= pm.programmeStartDate AND pl.dateTo <= pm.programmeEndDate), 1, 0) AS isMatch FROM
tcs.Placement pl
JOIN tcs.ProgrammeMembership pm ON pm.personId = pl.traineeId
WHERE (pl.dateFrom >= "2022-01-01" AND pl.dateFrom < "2023-01-01")
) plpm_match
GROUP BY id
) plsummary ON pl.id = plsummary.id
JOIN tcs.ProgrammeMembership pmmin ON pmmin.uuid = plsummary.minpmuuid
JOIN tcs.ProgrammeMembership pmmax ON pmmax.uuid = plsummary.maxpmuuid
WHERE matches = 0
Pilot rule (example for no matches, 2023):SELECT
count(*)
-- pl.id, pl.dateFrom, pl.dateTo, matches, minpmuuid, pmmin.programmeStartDate, pmmin.programmeEndDate, maxpmuuid, pmmax.programmeStartDate, pmmax.programmeEndDate
FROM tcs.Placement pl JOIN
(
SELECT id, sum(ismatch) as matches, min(uuid) as minpmuuid, max(uuid) as maxpmuuid FROM
(
SELECT pl.id, pm.uuid, if((pl.dateFrom >= CAST(DATE_FORMAT(pm.programmeStartDate ,'%Y-%m-01') as DATE) AND pl.dateFrom <= pm.programmeEndDate), 1, 0) AS isMatch FROM
tcs.Placement pl
JOIN tcs.ProgrammeMembership pm ON pm.personId = pl.traineeId
WHERE (pl.dateFrom >= "2022-01-01" AND pl.dateFrom < "2023-01-01")
) plpm_match
GROUP BY id
) plsummary ON pl.id = plsummary.id
JOIN tcs.ProgrammeMembership pmmin ON pmmin.uuid = plsummary.minpmuuid
JOIN tcs.ProgrammeMembership pmmax ON pmmax.uuid = plsummary.maxpmuuid
WHERE matches = 0
placement matches to [x] PMs | pilot rule | ||||||||
placement start year | 0 | 1 | 2+ | problem | 0 | 1 | 2+ | problem | |
2024 | 231 | 152741 | 681 | 0.59% | 229 | 152747 | 678 | 0.59% | |
2023 | 128 | 148610 | 662 | 0.53% | 124 | 148604 | 672 | 0.53% | |
2022 | 110 | 140250 | 673 | 0.56% | 114 | 140244 | 675 | 0.56% | |
2021 | 149 | 135458 | 753 | 0.66% | 160 | 135459 | 741 | 0.66% | |
2020 | 222 | 113549 | 647 | 0.76% | 230 | 113539 | 649 | 0.77% | |
2019 | 219 | 120681 | 694 | 0.75% | 231 | 120673 | 690 | 0.76% | |
2018 | 377 | 116156 | 641 | 0.87% | 384 | 116151 | 639 | 0.87% | |
2017 | 552 | 114230 | 740 | 1.12% | 549 | 114234 | 739 | 1.11% | |
2016 | 819 | 114335 | 971 | 1.54% | 819 | 114333 | 973 | 1.54% | |
2015 | 933 | 109715 | 932 | 1.67% | 936 | 109706 | 938 | 1.68% | |
2014 | 1119 | 107813 | 915 | 1.85% | 1116 | 107809 | 922 | 1.86% | |
2013 | 1382 | 105883 | 934 | 2.14% | 1381 | 105873 | 945 | 2.15% | |
2012 | 1775 | 100458 | 1104 | 2.79% | 1769 | 100454 | 1114 | 2.79% | |
2011 | 1564 | 93948 | 1303 | 2.96% | 1550 | 93953 | 1312 | 2.96% | |
2010 | 1967 | 89070 | 2398 | 4.67% | 1936 | 89079 | 2420 | 4.66% |
Note that the table above excludes placements for the 2-3% of trainees who have no programme memberships set up. Revised estimates for recent years including different linking methods are summarised below:
linked method: | ||||||||||
placement year start | total placements | unlinked | unlinkable trainee | unique PM | PM end date matches | f1f2_foundation specialty | %linked | %unlinkable | %to link | |
2024 | 158149 | 808 | 4153 | 153111 | 63 | 14 | 96.9% | 2.6% | 0.51% | |
2023 | 153490 | 716 | 4104 | 148618 | 52 | 0 | 96.9% | 2.7% | 0.47% | |
2022 | 144648 | 729 | 3612 | 140250 | 54 | 3 | 97.0% | 2.5% | 0.50% | |
2021 | 139423 | 821 | 3061 | 135460 | 72 | 9 | 97.2% | 2.2% | 0.59% | |
2020 | 117308 | 780 | 2896 | 113551 | 50 | 31 | 96.9% | 2.5% | 0.66% | |
2019 | 124209 | 791 | 2615 | 120681 | 70 | 52 | 97.3% | 2.1% | 0.64% | |
2018 | 119838 | 961 | 2664 | 116156 | 51 | 6 | 97.0% | 2.2% | 0.80% |