One permit dashboard, three sources
The dashboard from the lesson: it asks one question, “is there a permit for this plate in this zone, and when does it end?”, through PermitLookup, and an adapter answers it for each source. The city adds its resident-permit registry as a third. Each level starts from the previous level’s finished code, so you can begin at any of them.
Drivers complain about “check again” screens, and the enforcement team has a new rule: ten minutes’ grace after a paid time ends, during which no ticket is issued. A teammate’s pull request puts both fixes in the partner adapter, the busiest source. You are reviewing it before it merges.
If it merges as written, partner permits show paid times nobody paid for, the meter’s and the registry’s drivers get no grace at all, and during an outage the dashboard shows permits the partner never confirmed, including for zones the plate never paid for.
Reproduce At 18:35 the partner reports KLM-204’s C7 permit paid through 18:30. The dashboard should say “KLM-204 in C7: in grace until 18:40 (paid through 18:30)”, and say the same for the meter and the registry. Today the partner’s line says “permit through 18:40”.
Acceptance criteria A permit whose end has passed by ten minutes or less shows “in grace until” its end plus ten minutes, with the time paid through, whichever source reported it; after that it shows “permit ended at”. The time a permit is paid through is the time its source reported. An outage shows as an outage, even for a plate the source answered before. Earlier rules still hold: invalid responses, absence, the registry’s translation. Notes Each case prints the dashboard’s line for each lookup, joined by “ | ”; the checker sets the time of day before each lookup. Times stay within one day. One case uses the checker’s own PermitLookup, so a rule that only some sources follow shows there. Keep the adapters’ names and constructors, and the checker plumbing; the checker builds one adapter per case and looks up through it once per step.