Listings
Listing CRUD plus side effects (index, card cache, channel onboarding/offboarding) and property-association management.
📄️ List listings (paginated)
Returns a page of listings ordered by id. 1-based `page`; defaults to `page=1&size=20`. Values < 1 are clamped to the default. Response is a `PageResponse<Listing>` with `data`, `total`, `page`, `size`.
📄️ Create a listing
Creates the listing row, attaches the supplied properties + tags, indexes it for search, onboards it onto every channel that matches its tags, and warms the listing-card cache.
📄️ Get a listing by id (flat row, no property join)
Get a listing by id (flat row, no property join)
📄️ Partial update of a listing
Only the fields supplied on the body overwrite the stored row. `id` is taken from the path. After save the listing is re-indexed and its card cache is refreshed. Returns the persisted row.
📄️ Delete a listing
Offboards the listing from all channels (drops listing_channel_meal / vas / promotion / coupon / bank-offer rows), deletes the row, and removes it from the search index.
📄️ Get a listing with its property breakdown
Like GET /{listingId} but also fans out to listing_property + properties for the embedded `properties` array (bedrooms, bathrooms, per-property pricing, etc.).
📄️ Attach a property to a listing
Attach a property to a listing
📄️ Detach a property from a listing
Detach a property from a listing
📄️ Create listings in bulk
Create listings in bulk
📄️ Migrate live properties to listings
One-shot bootstrap: creates a single-property listing for every LIVE property that isn't already linked to a listing.
📄️ Rebuild the entire listing search index
Rebuild the entire listing search index
📄️ Search listings (filtered, paginated)
POST body accepts `rawParams` (same shape as CRS search). All filters AND together. Recognized filterNames: `id` / `listingId` (in), `status` (in), `city` / `state` / `country` / `locality` (in), `brand` (in, joins properties), `q` (title ILIKE substring). Unknown filter names are ignored.