This repository was archived by the owner on Jun 9, 2026. It is now read-only.
chore(positions): add diagnostic logging to filing-fee lookup - #168
Open
dealvz wants to merge 1 commit into
Open
chore(positions): add diagnostic logging to filing-fee lookup#168dealvz wants to merge 1 commit into
dealvz wants to merge 1 commit into
Conversation
Surfaces which branch fired when the lookup returns a null fee: - `skipped` — position has no placeId or no name - `no_race_match` — placeId + name produced zero races; also logs up to 5 sample positionNames arrays for the same placeId so we can see what the data actually has and adjust the join - `matched` — race(s) found; logs which race we picked + what extractor said (so multi_value / no_match / pct_unresolvable show up too) Logging is `debug` level — visible in dev, off in prod unless explicitly enabled. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
Comment on lines
+307
to
+311
| const sampleNames = await this.client.race.findMany({ | ||
| where: { placeId: position.placeId }, | ||
| select: { positionNames: true }, | ||
| take: 5, | ||
| }) |
There was a problem hiding this comment.
The diagnostic sampleNames query executes unconditionally on every races.length === 0 path, including production traffic. The database round-trip happens regardless of whether the runtime log level will ever emit the debug message. NestJS Logger has no level-check guard you can call before building the payload, so the only correct fix is to remove the extra query and log only what you already have.
Suggested change
| const sampleNames = await this.client.race.findMany({ | |
| where: { placeId: position.placeId }, | |
| select: { positionNames: true }, | |
| take: 5, | |
| }) | |
| this.logger.debug({ | |
| event: 'FilingFeeLookup', | |
| outcome: 'no_race_match', | |
| positionId: position.id, | |
| positionName: position.name, | |
| placeId: position.placeId, | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Logging-only follow-up to #165. Surfaces which branch the filing-fee lookup took so we can debug null-fee responses in dev without DB access.
This commit was on the original branch but pushed after #165 merged, so it didn't make it in. Cherry-picking now to unblock active filing-fee debugging on dev.
What it logs
debuglevel (visible in dev, off in prod unless explicitly enabled). EverylookupFilingFeecall emits one of:outcome: 'skipped'withreason: 'no_place_id'or'no_name'— the Position row doesn't have the fields we need to look up a Race.outcome: 'no_race_match'—placeIdwas set, but no Race row matchedplaceId + positionNames. Also logssampleRacePositionNames(up to 5 races'position_namesarrays for the sameplaceId) so we can see what names actually exist and decide whether to loosen the join.outcome: 'matched'— race(s) found. Logs which race we picked, whether it hadfiling_requirements/salary, and whatextractFilingFeereturned (somulti_value/no_match/pct_of_salary_unresolvableshow up here too).Why now
Current state: PR #165 is merged but every filing-fee response in dev comes back
null— including for positions where we expected real data (e.g. positionc61611f1-7d9d-666f-c759-8fce3c3fc457, "Denver City Council - At Large"). The API response alone can't distinguish "Position has noplaceId" from "Race join produced zero rows" — both render as identical-looking nulls. This commit makes the distinction visible in logs.Risk / blast radius
this.logger.debug(...)calls.SELECT positionNames FROM Race WHERE placeId = ... LIMIT 5) on theno_race_matchbranch only. Doesn't fire on the success path.Test plan
GET /v1/positions/c61611f1-7d9d-666f-c759-8fce3c3fc457?includeDistrict=true&includeTurnout=true&electionDate=2027-04-06&includeFilingFee=trueagainsthttps://election-api-dev.goodparty.org.FilingFeeLookupline. Theoutcomefield tells us which branch fired.🤖 Generated with Claude Code
Note
Low Risk
Low risk: behavior is unchanged aside from additional
debuglogs and a small extra query only when no races match, with minimal performance impact.Overview
Adds structured
debug-level diagnostics toPositionsService.lookupFilingFeeto make null filing-fee responses explainable.The lookup now logs when it is skipped (missing
placeId/name), when there is no race match (including a small sample ofRace.positionNamesfor theplaceId), and when a race is matched (including chosen race attributes and theextractFilingFeeresult).Reviewed by Cursor Bugbot for commit cdfd665. Configure here.