Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / frontend/src/tools/screenmatch/queries.ts |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | frontend/src/tools/screenmatch/queries.ts |
| Original SHA-256 | 96aff4b9fdbaad3dacd1575b9267ad63f45d2f50ce40a32ff3350029f15521a0 |
| Git blob SHA | 5a808704101c360894aef71b032fb1555b3994bd |
| Reading-copy SHA-256 | 96aff4b9fdbaad3dacd1575b9267ad63f45d2f50ce40a32ff3350029f15521a0 |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / frontend/src/tools/screenmatch/queries.ts | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / frontend/src/tools/screenmatch/queries.ts | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓87 lines · 3.6 KB
// screenMATCH React Query hooks over the tool's namespace client. Keys are prefixed with the tool name
// so the three tools never collide in the shared query cache.
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { screenApi } from './api'
export function useScreenRequirements() {
return useQuery({ queryKey: ['screenmatch', 'requirements'], queryFn: screenApi.requirements })
}
export function useScreenRequirement(id: string | null) {
return useQuery({
queryKey: ['screenmatch', 'requirement', id],
queryFn: () => screenApi.requirement(id as string),
enabled: !!id,
})
}
export function useScreenCandidate(id: string | null) {
return useQuery({
queryKey: ['screenmatch', 'candidate', id],
queryFn: () => screenApi.candidate(id as string),
enabled: !!id,
})
}
export function useScreenRanked(requirementId: string | null) {
return useQuery({
queryKey: ['screenmatch', 'ranked', requirementId],
queryFn: () => screenApi.rankCandidates(requirementId as string),
enabled: !!requirementId,
})
}
export function useScreenOpportunities(candidateId: string | null) {
return useQuery({
queryKey: ['screenmatch', 'opportunities', candidateId],
queryFn: () => screenApi.opportunities(candidateId as string),
enabled: !!candidateId,
})
}
// An outcome is a scoring INPUT, not a passive log line: it feeds the AIOE weight profile and the
// counters the admin surface reports. Nothing was invalidated here, so the Outcomes recorded stat the
// operator just incremented kept showing the pre click number until a hard reload, which reads as the
// click having been swallowed. Deliberately narrow: the cached screen view is NOT invalidated, because
// refetching it would re POST the scoring endpoint that the same counter is fed from, so recording one
// decision would inflate the number it is meant to report honestly.
function useInvalidate() {
const qc = useQueryClient()
return () => {
void qc.invalidateQueries({ queryKey: ['aioe', 'status'] })
}
}
export function useRecordOutcome() {
const inv = useInvalidate()
return useMutation({
mutationFn: (o: import('../../lib/types').OutcomeInput) => screenApi.recordOutcome(o),
onSuccess: () => inv(),
})
}
export function useAliases() {
return useQuery({ queryKey: ['screenmatch', 'aliases'], queryFn: screenApi.aliases })
}
export function useAioeStatus() {
return useQuery({ queryKey: ['aioe', 'status'], queryFn: screenApi.aioeStatus, retry: false })
}
// The qualification of one candidate against one requirement. It is a POST only because the pair travels
// in a body; it reads a score and changes nothing the caller owns, so it is modelled as a QUERY.
//
// As a mutation it had to be fired from an effect on mount, and StrictMode runs effects twice in
// development, so every navigation issued POST /screen twice against the endpoint whose calls the
// Continuous Learning tile reports as outcomes recorded. A mutation also has no cache entry, so returning
// to a candidate already scored a second ago paid for the full evaluation again. Keying on the pair means
// the transition to another candidate reads a different cache slot, which is also what stops a stale
// score rendering under the new candidate's name (the reset() the old effect had to do by hand).
export function useScreenScreen(candidateId: string | null, requirementId: string | null) {
return useQuery({
queryKey: ['screenmatch', 'screen', candidateId, requirementId],
queryFn: () => screenApi.screen(candidateId as string, requirementId as string),
enabled: !!candidateId && !!requirementId,
})
}