23-Oct-2026
08:46
CyprusVillasDirect — Market Intelligence
1. Background
We want to build a Market Intelligence feature for CyprusVillasDirect that collects pricing and availability information for holiday villas listed on Airbnb.
For example, we could collect data for villas in Pissouri and market this information to other villa owners in Pissouri, helping them understand whether they are overpricing or underpricing their properties relative to competitors.
The commercial objective is to develop a historical database that tells us:
- What each villa is charging for different arrival dates and lengths of stay.
- Which dates appear available or unavailable.
- What minimum-stay restrictions appear to apply.
- Whether discounts are being offered.
- How prices and availability change over time.
- How competitively each villa is priced relative to other villas.
Over time, this should allow us to estimate occupancy, identify pricing trends and compare the performance of competing properties.
Today's task is to build the collection and storage functionality, not the analytics or reporting.
2. Existing application
Villa entity
Already exists and contains:
PriceHistory entity
Already created with:
- Villa — ManyToOne relationship
- StartDate — proposed arrival date
- T1Price through T30Price — total prices for stays of 1–30 nights
- createdAt — timestamp recording when the information was collected
There is also an existing CRUD interface, including an index showing all 30 prices and a manual form.
Each collection should create a new record rather than overwrite an existing record, allowing us to track historical price changes.
No new entities or changes to existing entities are required.
3. Data collection methodology
For each villa, investigate every possible arrival date over the next six months (initially 180 days).
For each arrival date, obtain prices for stays of between 1 and 30 nights.
For example:
Villa: TheaVista
Arrival date: 1 July 2027
- 1 night: Checkout 2 July 2027 — Price £xxx
- 2 nights: Checkout 3 July 2027 — Price £xxx
- 3 nights: Checkout 4 July 2027 — Price £xxx
- And so on, up to:
- 30 nights: Checkout 31 July 2027 — Price £xxx
The checkout date is always calculated as: checkoutDate = startDate + numberOfNights
The proposed coverage per villa is: 180 arrival dates × 30 stay lengths = 5,400 quotes.
Some requests will not return a price because dates are unavailable, minimum-stay rules prevent booking, or another restriction applies.
Where no valid price is returned, store NULL, not zero.
A missing price does not necessarily mean the villa is occupied.
If we collect prices today and again tomorrow, both observations must be retained for historical comparison.
All prices should be collected in a consistent currency (GBP initially) and represent the total quoted price for the requested stay.
4. Implementation
Create a Symfony service named:
VillaMarketIntelligenceService
The service should accept:
The service will:
- Load the Villa entity.
- Check that airbnbUrl exists and an authorised pricing data source is available.
- For the specified arrival date, request prices for stays of 1–30 nights, or obtain equivalent information in bulk if the source supports it.
- Parse and validate the returned information.
- Create a new PriceHistory record with the Villa, StartDate and collection timestamp.
- Save the prices in T1Price through T30Price.
- Record errors in the application logs without aborting the complete collection.
Batch collection
Also provide a method that accepts:
- Villa ID
- Start date
- Number of arrival dates to investigate (default 180)
This should call the single-arrival-date method for each date.
For 180 arrival dates, the process should create 180 PriceHistory records per villa, each containing up to 30 prices.
Use a permitted data source, respect its rate limits and avoid unnecessary requests where equivalent bulk pricing information is available.
5. Testing
Initially, test the functionality on one villa and one arrival date.
Verify that:
- The correct Airbnb listing is identified.
- The 30 checkout dates are calculated correctly.
- Valid returned prices are saved against the correct T1Price–T30Price fields.
- Missing prices are saved as NULL.
- The existing collection timestamp is populated.
- Running the same collection twice creates two separate historical records.
- An individual quote failure does not stop the other quotes being collected.
Once this works, test collecting several arrival dates for the same villa.
6. Scope for today
Build:
- VillaMarketIntelligenceService.
- Pricing collection for 1–30 nights.
- Storage of collected prices in the existing PriceHistory entity.
- Historical snapshots without overwriting previous collections.
- Batch collection across multiple arrival dates.
- Basic error handling and testing.
Do not build today:
- Any new entities or entity changes.
- Competitor comparison reports.
- Occupancy calculations.
- Pricing recommendations.
- Charts or dashboards.
- Automatic scheduled collections.
The priority is to establish a reliable database of historical prices using the existing PriceHistory entity. We can develop the analytics once the underlying data collection is working.