Skip to content

feat(apple): support all public search filters in spec and client - #231

Merged
amikai merged 5 commits into
mainfrom
claude/apple-openapi-integration-f8ce1f
Jul 19, 2026
Merged

feat(apple): support all public search filters in spec and client#231
amikai merged 5 commits into
mainfrom
claude/apple-openapi-integration-f8ce1f

Conversation

@amikai

@amikai amikai commented Jul 18, 2026

Copy link
Copy Markdown
Owner

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's SEARCH_SORT_TERMS.

Commit 1 — spec and client:

  • openapi.yaml: add the missing SearchFilters fields and SearchTeamFilter, drop the wrong maxItems: 1/3-letter-country constraint on locations, extend the sort enum, and note the refData ID sources.
  • client.go: expose the new filters on SearchRequest with bare-code inputs (HRDWR/CAM, IPHN, en_US) validated and prefixed internally; homeOffice is only sent when true, matching the site.
  • CLI: --home-office, --filter-keyword, --team TEAM/SUB, --product, --language (repeatable) and the extended --sort enum.
  • Fixtures: jobs_filtered_req.hurl now 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:

  • Team/product codes are opaque taxonomy an LLM can't guess, and teams drift with Apple's org chart, so they're exposed via a new apple_get_search_filters tool instead of hardcoded schema enums. Teams are fetched live from the anonymous refData/teamsofinterest endpoint (added to the spec as listTeams); products are a package snapshot because that refData endpoint rejects anonymous sessions.
  • apple_search_jobs accepts home_office, keywords, teams (TEAM/SUBTEAM), products, languages, and the full sort enum.
  • Debug CLI gains a matching filters subcommand; verified live (filters--team MLAI/CV returns 84 US matches, 0 in TWN, both correct).

🤖 Generated with Claude Code

amikai and others added 2 commits July 19, 2026 07:01
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 amikai left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread internal/provider/apple/products.go Outdated
Comment thread cmd/apple/main.go
amikai and others added 3 commits July 19, 2026 23:45
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>
@amikai
amikai merged commit 3654f74 into main Jul 19, 2026
9 checks passed
@amikai
amikai deleted the claude/apple-openapi-integration-f8ce1f branch July 28, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant