Property search API serves MOCK_PROPERTIES: GET /api/properties and /api/properties/[id] return fabricated listings
Labels / Complexity: Frontend · High Complexity — High
Problem
The property search and detail endpoints return hardcoded listings from src/lib/mockData.ts. GET /api/properties (src/app/api/properties/route.ts) calls propertyService.searchProperties(...), which falls through to fetchAndCacheSearch in src/lib/propertyService.ts:
// Simulate API delay
await this.delay(300);
// Apply filters to all data (in a real DB, this would be WHERE clause)
let results = this.applyFilters([...MOCK_PROPERTIES], filters);
GET /api/properties/[id] (src/app/api/properties/[id]/route.ts) falls through to fetchAndCacheProperty, which does MOCK_PROPERTIES.find(p => p.id === id). Autocomplete (getAutocompleteSuggestions) searches the same constant. The responses are labeled source: 'network' (route.ts) even though no network call ever happens — every listing a user sees, filters, sorts, and pages through comes from the 412-line mockData.ts array of ~10 hand-written properties. There is no backend fetch, no pagination over real data, and no error path for a missing backend, because no backend is ever contacted. Consumers of the API (the search page, the property detail page, ISR revalidation, and any external integrator) receive fabricated data presented as production listings.
Root cause
src/lib/propertyService.ts fetchAndCacheSearch (line ~113) and fetchAndCacheProperty (line ~215): the "network fetch" is await this.delay(300) followed by filtering/finding in MOCK_PROPERTIES, with no HTTP call.
Why this is architecturally hard
- The service layer is built around the mock. Every strategy (
cache-first, network-first, stale-while-revalidate), the Redis/local cache write-through, and the API routes were shaped by a data source that never existed. Replacing it with a real backend means defining the request/response contract, error handling, and pagination semantics that the mock implicitly provided — a contract design task.
- Caching must not serve stale mock. The service writes fetched results into Redis and local caches; if a real fetch is added, cached mock entries already in Redis (seeded by the current code) must be invalidated or versioned, or users keep seeing fake listings after the fix.
- The API surface is public.
GET /api/properties is a real HTTP endpoint; the fix must decide whether the backend is the PropChain-BackEnd API (cross-repo contract) or an in-app data layer, and that decision has downstream impact on every consumer page.
Downstream impact
src/lib/propertyService.ts and the two route files are consumed by src/hooks/usePropertySearchQuery.ts, src/app/compare/page.tsx, src/lib/propertyServiceServer.ts (ISR), and src/components/SaveSearchButton.tsx. If the data source changes shape (pagination fields, listing fields), each consumer's types in src/types/property.ts must be reconciled.
Acceptance criteria
GET /api/properties and GET /api/properties/[id] return data from a real backend/data layer; no response originates from MOCK_PROPERTIES.
- Filtering, sorting, and pagination behave correctly against the real source (a test asserts a filter that matches nothing returns empty, and pagination returns the requested slice).
src/lib/mockData.ts is either deleted or moved behind an explicit NEXT_PUBLIC_USE_MOCK flag that defaults to off, documented as dev-only.
- Cached mock entries from previous deployments do not surface after the fix (version key or invalidation).
npm run lint and npm test pass.
Out of scope
Rebuilding the listing page UI; this issue is about the data source behind the existing API.
Getting started
Files: src/lib/propertyService.ts, src/app/api/properties/route.ts, src/app/api/properties/[id]/route.ts, src/lib/mockData.ts. Commands: npm run lint, npm test. Good first files to read: src/lib/propertyService.ts, src/app/api/properties/route.ts.
Property search API serves MOCK_PROPERTIES: GET /api/properties and /api/properties/[id] return fabricated listings
Labels / Complexity: Frontend · High Complexity — High
Problem
The property search and detail endpoints return hardcoded listings from
src/lib/mockData.ts.GET /api/properties(src/app/api/properties/route.ts) callspropertyService.searchProperties(...), which falls through tofetchAndCacheSearchinsrc/lib/propertyService.ts:GET /api/properties/[id](src/app/api/properties/[id]/route.ts) falls through tofetchAndCacheProperty, which doesMOCK_PROPERTIES.find(p => p.id === id). Autocomplete (getAutocompleteSuggestions) searches the same constant. The responses are labeledsource: 'network'(route.ts) even though no network call ever happens — every listing a user sees, filters, sorts, and pages through comes from the 412-linemockData.tsarray of ~10 hand-written properties. There is no backend fetch, no pagination over real data, and no error path for a missing backend, because no backend is ever contacted. Consumers of the API (the search page, the property detail page, ISR revalidation, and any external integrator) receive fabricated data presented as production listings.Root cause
src/lib/propertyService.tsfetchAndCacheSearch(line ~113) andfetchAndCacheProperty(line ~215): the "network fetch" isawait this.delay(300)followed by filtering/finding inMOCK_PROPERTIES, with no HTTP call.Why this is architecturally hard
cache-first,network-first,stale-while-revalidate), the Redis/local cache write-through, and the API routes were shaped by a data source that never existed. Replacing it with a real backend means defining the request/response contract, error handling, and pagination semantics that the mock implicitly provided — a contract design task.GET /api/propertiesis a real HTTP endpoint; the fix must decide whether the backend is the PropChain-BackEnd API (cross-repo contract) or an in-app data layer, and that decision has downstream impact on every consumer page.Downstream impact
src/lib/propertyService.tsand the two route files are consumed bysrc/hooks/usePropertySearchQuery.ts,src/app/compare/page.tsx,src/lib/propertyServiceServer.ts(ISR), andsrc/components/SaveSearchButton.tsx. If the data source changes shape (pagination fields, listing fields), each consumer's types insrc/types/property.tsmust be reconciled.Acceptance criteria
GET /api/propertiesandGET /api/properties/[id]return data from a real backend/data layer; no response originates fromMOCK_PROPERTIES.src/lib/mockData.tsis either deleted or moved behind an explicitNEXT_PUBLIC_USE_MOCKflag that defaults to off, documented as dev-only.npm run lintandnpm testpass.Out of scope
Rebuilding the listing page UI; this issue is about the data source behind the existing API.
Getting started
Files:
src/lib/propertyService.ts,src/app/api/properties/route.ts,src/app/api/properties/[id]/route.ts,src/lib/mockData.ts. Commands:npm run lint,npm test. Good first files to read:src/lib/propertyService.ts,src/app/api/properties/route.ts.