feat(apple): support all public search filters in spec and client - #231
Conversation
Clicking through the jobs.apple.com filter panel showed the search API accepts far more than the single country location the spec modeled: keyword chips, team/sub-team pairs, products, languages, a home-office flag, multiple locations at any granularity (state, metro, city), and four extra sort orders. Capture that contract in openapi.yaml, expose the new filters through SearchRequest and the debug CLI, and re-record the filtered fixture live so it exercises every dimension at once. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Team and product codes are opaque Apple taxonomy, so an LLM caller had no way to use the new search filters. Expose them through a discovery tool instead of hardcoded enums: teams are fetched live from the anonymous refData endpoint (now in the spec as listTeams), while products are a package-level snapshot because that refData endpoint rejects anonymous sessions. apple_search_jobs now accepts home_office, keyword chips, TEAM/SUBTEAM pairs, products, languages, and the full sort enum; the debug CLI gains a matching filters subcommand. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
amikai
left a comment
There was a problem hiding this comment.
I found one functional coverage gap and two smaller CLI contract issues. Details are inline.
| // CountryCode are required and every other filter narrows the result set. | ||
| type SearchRequest struct { | ||
| Keyword string | ||
| CountryCode string |
There was a problem hiding this comment.
[P2] Expose the multi-location filters through JobsClient. The OpenAPI schema now accepts multiple location IDs at country/state/metro/city granularity, but the session-aware wrapper still exposes only one required CountryCode. The CLI and MCP inputs inherit that restriction, so callers cannot use the multi-location behavior advertised by this PR. Please add a location input (with CountryCode as a compatibility fallback if desired), surface it through the CLI/MCP tool, and cover a request containing more than one location.
There was a problem hiding this comment.
Fixed in e2fda16: SearchRequest now has a Locations []string field (bare codes at any granularity, e.g. TPEI/NTC9) that combines with CountryCode via OR; CountryCode is now optional as long as one of the two is set. Surfaced via --location (repeatable) on the CLI and locations on the MCP tool. Covered by a mock-server round trip with two locations and no country (TestSearchJobsMultipleLocationsWithoutCountry, TestAppleSearchJobsLocationsWithoutCountryE2E) plus live verification.
There was a problem hiding this comment.
[P2] Follow-up: mixed-case location codes are still broken. locationFilterIDs routes locations through filterCode, which uppercases them. Apple’s live location typeahead returns case-sensitive values such as state953; a direct search with postLocation-state953 returned 2,992 matches, while postLocation-STATE953 returned zero. Please preserve location-code case with a dedicated validator, change the OpenAPI location pattern to allow lowercase ([A-Za-z0-9]+), and add a regression test using a mixed-case code such as state953. This thread should remain open until that path is fixed.
There was a problem hiding this comment.
Fixed in ea247f0: added a dedicated locationFilterCode validator that preserves case (unlike filterCode, used by team/product codes, which correctly uppercases those since they're uppercase-only). Widened the OpenAPI location pattern to postLocation-[A-Za-z0-9]+, regenerated, and added TestLocationFilterCodePreservesCase plus a mixed-case entry in TestSearchAPIRequestMultipleLocations. Live-verified: --location state953 returns 2,992 matches, --location STATE953 returns 0 — confirms the fix and that it's no longer silently coerced.
Matches the terse one-liner style already applied to the meta provider's tools: filter field descriptions point at apple_get_search_filters instead of listing stale example values. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… usage - Expose the multi-location filters through JobsClient: SearchRequest gains Locations (bare codes at any granularity, OR'd with CountryCode), surfaced via --location (CLI) and locations (MCP), with CountryCode kept as a compatibility fallback rather than required. Covers a live mock-server round trip through more than one location. - Add json:"code"/json:"name" tags to Product so `apple filters --format json` matches the lowercase-key contract used by teams and the MCP output. - List `filters` in the root usage synopsis and the no-subcommand error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
locationFilterIDs routed location codes through filterCode, which uppercases team/product codes. Apple's location IDs are case-sensitive (confirmed live: postLocation-state953 returns 2,992 matches, postLocation-STATE953 returns 0), so that silently broke any mixed-case location. Add a dedicated locationFilterCode validator that preserves case, widen the OpenAPI location pattern to allow lowercase, and regenerate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Apple spec modeled only a single-country location filter, but clicking through the jobs.apple.com filter panel (and capturing the live search payloads) showed the API also accepts keyword chips, team/sub-team pairs, products, languages, a home-office flag, multi-location arrays at any granularity (state/metro/city codes such as
TPEI/TAIP/NTC9), and four extra sort orders from the site bundle'sSEARCH_SORT_TERMS.Commit 1 — spec and client:
openapi.yaml: add the missingSearchFiltersfields andSearchTeamFilter, drop the wrongmaxItems: 1/3-letter-country constraint onlocations, extend thesortenum, and note the refData ID sources.client.go: expose the new filters onSearchRequestwith bare-code inputs (HRDWR/CAM,IPHN,en_US) validated and prefixed internally;homeOfficeis only sent when true, matching the site.--home-office,--filter-keyword,--team TEAM/SUB,--product,--language(repeatable) and the extended--sortenum.jobs_filtered_req.hurlnow exercises every filter dimension in one request and its response was re-recorded live (63 matches; verified identical through the CLI).Commit 2 — MCP discovery tool:
apple_get_search_filterstool instead of hardcoded schema enums. Teams are fetched live from the anonymousrefData/teamsofinterestendpoint (added to the spec aslistTeams); products are a package snapshot because that refData endpoint rejects anonymous sessions.apple_search_jobsacceptshome_office,keywords,teams(TEAM/SUBTEAM),products,languages, and the full sort enum.filterssubcommand; verified live (filters→--team MLAI/CVreturns 84 US matches, 0 in TWN, both correct).🤖 Generated with Claude Code