Files
jackwener__opencli/docs/adapters/browser/ctrip.md
jakevin 61c4637b4c enrich(ctrip): hotel-suggest + bug fixes (silent clamp, dropped columns, fake URL) (#1361)
* enrich(ctrip): hotel-suggest + bug fixes (silent clamp, dropped columns, fake URL)

Per WAWQAQ "丰富现有 adapter" pivot — Phase 2 site #1.

## New command
- `ctrip hotel-suggest` — surfaces hotel-context suggestions (cities,
  business areas, individual hotels) via the same backing endpoint with
  searchType=H. Distinct from `ctrip search` (searchType=D) which returns
  destinations / scenic spots / railway stations.

## Bug fixes for `ctrip search`
- **Silent clamp on `--limit` removed**: out-of-range values (≤0, ≥51,
  non-integer) now raise `ArgumentError` with explicit bounds rather than
  silently snapping to [1, 50].
- **Silent column drop fixed**: previously the adapter discarded `id`,
  `cityId`, `cityName`, `provinceName`, `countryName`, `lat`, `lon`, `eName`
  and `displayType` from upstream rows. Now all are surfaced as stable
  columns.
- **Fake URL fixed**: previously `url` was always `''`. Now constructs
  canonical Ctrip URLs by `type` (City / Markland / Hotel / Zone / RailwayStation)
  and returns `null` (no silent fabrication) for unknown types.
- **In-band error envelope typed**: `Result: false` payloads now surface
  as `COMMAND_EXEC` (was previously not handled — adapter returned empty
  rows).

## Doc fix
- `Mode: 🔐 Browser` → `🌐 Public` (search uses public API, no login)
- Add `hotel-suggest` to commands table in both `docs/adapters/index.md`
  and `docs/adapters/browser/ctrip.md`.

## Coords picker
Mainland China rows ship `gdLat`/`gdLon` (gaode); international rows ship
`gLat`/`gLon` (wgs84). Adapter picks the first non-zero pair (zero is the
upstream sentinel for "missing"); returns `null` if all variants are zero.

## Tests
25 contract assertions across `parseLimit` / `pickCoords` / `buildUrl` /
`mapSuggestRow` + registry-level checks for both commands (Strategy /
shape parity / typed errors / no silent clamp).

## Audits
- typed-error-lint: 196 = 196 (unchanged baseline)
- silent-column-drop: 103 = 103 (unchanged baseline)
- listing-id-pairing: advisory only (search has `id` round-trip column)

## Manifest
757 → 758 entries (+1 for `hotel-suggest`).

* fix(ctrip): wrap suggest fetch and json failures
2026-05-06 19:34:13 +08:00

2.0 KiB

Ctrip (携程)

Mode: 🌐 Public · Domain: ctrip.com

Public destination + hotel-context suggestion lookup against the m.ctrip.com/restapi/soa2/21881/json/gaHotelSearchEngine endpoint. No browser or login required.

Commands

Command Description
opencli ctrip search Suggest cities, scenic spots, railway stations and landmarks
opencli ctrip hotel-suggest Suggest cities, business areas and individual hotels

Usage Examples

# Destination suggest
opencli ctrip search 苏州 --limit 10

# Hotel-context suggest (cities / business areas / hotels)
opencli ctrip hotel-suggest 陆家嘴 --limit 5

# JSON output
opencli ctrip search 上海 -f json

Columns

Both commands share a uniform column shape:

Column Notes
rank 1-based position in the upstream list
id Upstream entity id (round-trips into URL)
type Raw type tag (City / Markland / Hotel / BusinessArea / RailwayStation)
displayType Localised label (城市 / 地标 / 酒店 / 商圈 / 火车站)
name Localised display name
eName English name (may be empty)
cityId, cityName, provinceName, countryName Geo context
lat, lon Best-available coords (gaode → google → flat → null)
score First non-zero of commentScore / cStar; null if both unrated
url Canonical Ctrip URL or null if the entity type has no public web page

--limit accepts integers in [1, 50]. Out-of-range values raise ArgumentError (no silent clamp).

Notes

  • Endpoint discriminator: searchType=D (search) vs searchType=H (hotel-suggest). Hotel and BusinessArea rows only appear in the H flavour.
  • Mainland China rows ship gdLat/gdLon (gaode). International rows ship gLat/gLon (wgs84). The adapter picks the first non-zero pair.
  • In-band Result: false envelopes are surfaced as COMMAND_EXEC typed errors; HTTP non-2xx becomes FETCH_ERROR.