Crawl listings từ nguồn ngoài (Muaban, Nhà Tốt, Batdongsan)
Mục tiêu
Thu thập tin đăng BĐS từ 3 nguồn bên thứ ba (Muaban.net, Nhà Tốt, Batdongsan.com.vn), chuẩn hóa về một format chung để tái dùng đúng các endpoint hiện có POST /properties và POST /listings nhằm tạo property + listing chính thức trong V-Nexus. Sau khi crawl, dữ liệu được chuẩn hóa thành 4 nhóm: thông tin property, thông tin listing, thông tin contact, thông tin nguồn crawl. Pipeline: chống trùng listing theo source + source_id (đã có thì bỏ qua, không tạo property/contact, không gọi POST /listings); tái dùng property nếu khớp address + area_m2 + property_type_id, nếu chưa có thì gọi POST /properties; resolve liên hệ theo số điện thoại (tra/tạo phone_registries rồi tra/tạo contacts); rồi map sang CreateListingRequest và gọi POST /listings. Tin crawl đi chung luồng với tin tạo từ app — không dùng chế độ ingest, không bỏ qua validate user-facing; Backend tính trust_score, route tin trust_score < 80 vào Data Marketplace (public) và tin trust_score ≥ 80 vào kho lưu trữ Admin, đồng thời push realtime qua WebSocket như mọi listing thường. Các trường nguồn (source, source_id, source_url) lưu trực tiếp trên bảng listings; thông tin liên hệ lưu ở bảng contacts mới (tham chiếu qua listings.contact_id), còn số điện thoại liên hệ lưu ở phone_registries — contacts trỏ tới qua khóa ngoại phone_registry_id. Bỏ hoàn toàn bảng staging data_sources, chế độ ingest, và logic resolve user/owner theo số điện thoại (không resolve users; phone_registries chỉ là nơi lưu số điện thoại, không suy ra owner).
Phạm vi
Trong phạm vi (In scope):
- Crawl tin đăng từ 3 nguồn: Muaban.net, Nhà Tốt, Batdongsan.com.vn; crawl chạy liên tục — xong lượt nào bắt đầu lượt kế tiếp ngay, không chờ interval cố định
- Mỗi lượt crawl lấy tin trong
time_windows= 2 phút lùi từ thời điểm hiện tại ([now − 2 phút, now]) - Chuẩn hóa dữ liệu crawl thành 4 nhóm: property, listing, contact, thông tin nguồn — khớp với request của
POST /propertiesvàPOST /listings - Chống trùng listing: trước khi xử lý, tra bảng
listingstheo cặpsource + source_id; nếu đã tồn tại → bỏ qua tin đó (không tạo property, không tạo contact, không gọiPOST /listings) - Loại tin thiếu số điện thoại: sau khi lấy chi tiết, nếu số điện thoại liên hệ null/rỗng/không hợp lệ → drop tin tại crawl, không tạo
phone_registries/contact/property/listing - Tái dùng property: tra property theo
address + area_m2 + property_type_id; khớp → dùngproperty_idhiện có; không khớp → gọiPOST /propertiesrồi lấyproperty_idvừa tạo - Resolve liên hệ: tra/tạo bản ghi
phone_registriestheo số điện thoại, rồi tra/tạocontactstrỏ tớiphone_registry_idđó; đã có → dùngcontact_idhiện có - Tạo bảng
contactslưu thông tin liên hệ (một-nhiều vớilistings); thêm khóa ngoạicontact_idvàolistings;contactscó khóa ngoạiphone_registry_id→phone_registries(nơi lưu số điện thoại) - Lưu các trường nguồn (
source,source_id,source_url) trực tiếp trênlistings - Map dữ liệu sang
CreateListingRequest(kèmproperty_id,contact_id,source,source_id,source_url) và gọiPOST /listings— đi chung luồng tin app, validate đầy đủ, không ingest - Backend tính
trust_score, routetrust_score < 80→ Data Marketplace (public),trust_score ≥ 80→ kho lưu trữ Admin; push event WebSocket khi listing trong Data Marketplace mới / cập nhật / đổitrust_score - Frontend nhận event và phản ánh thay đổi listing trên giao diện
Ngoài phạm vi (Out of scope):
- Crawl nguồn khác ngoài 3 website trên (phase sau)
- Thiết kế chi tiết màn hình listing trên Frontend (feature FE riêng nếu cần)
- Công thức/trọng số chính xác tính
trust_score(Dev quyết ở repo BE) - Thuật toán/threshold normalization để match property khi resolve (Dev quyết ở repo BE)
- Thiết kế schema DB chi tiết (kiểu cột, index), API contract kỹ thuật, lựa chọn tech stack crawler (thuộc repo source code)
- Logic xử lý nội bộ của
POST /propertiesvàPOST /listings(thuộc feature/endpoint tương ứng ở repo source) - Kiểm duyệt thủ công listing crawl trước khi publish
- Giao diện admin xem kho lưu trữ Admin (feature admin riêng)
- Resolve user/owner, tài khoản shadow, claim tài khoản — đã loại khỏi luồng crawl (số điện thoại lưu ở
phone_registriesnhưng không dùng để suy ra owner)
User Stories
- Là hệ thống, tôi muốn crawl tin đăng từ Muaban.net, Nhà Tốt, Batdongsan.com.vn để có nguồn dữ liệu listing bên ngoài.
- Là hệ thống, tôi muốn chuẩn hóa tin crawl thành property/listing/contact/nguồn để tái dùng đúng
POST /propertiesvàPOST /listingshiện có, không cần endpoint riêng. - Là hệ thống, tôi muốn trước khi xử lý kiểm tra
listingstheosource + source_id; nếu đã có thì bỏ qua để không tạo trùng property/contact/listing. - Là hệ thống, tôi muốn tái dùng property đã tồn tại (theo
address + area_m2 + property_type_id) hoặc tạo mới quaPOST /propertiesđể mỗi BĐS chỉ có một property. - Là hệ thống, tôi muốn lưu số điện thoại liên hệ ở
phone_registriesvà gắncontactstới đó quaphone_registry_id, gom các tin cùng số điện thoại về một contact, để quản lý liên hệ tập trung mà không định danh user. - Là Backend, tôi muốn nhận
CreateListingRequestkèmproperty_id,contact_id,source,source_id,source_urlvà xử lý như một request tạo listing bình thường (validate đầy đủ). - Là Backend, tôi muốn tính
trust_scorerồi route tintrust_score < 80vào Data Marketplace, tintrust_score ≥ 80vào kho lưu trữ Admin — như mọi listing khác. - Là user trên Frontend, tôi muốn thấy listing mới hoặc cập nhật trong Data Marketplace ngay khi hệ thống xử lý xong, không cần refresh trang.
- Là admin, tôi muốn tin có
trust_score ≥ 80tự động vào kho lưu trữ Admin để bảo vệ khỏi phân phối đại trà.
Luồng chức năng
sequenceDiagram
participant Source as Nguồn ngoài<br/>(Muaban / Nhà Tốt / Batdongsan)
participant Crawler as Crawler
participant Normalizer as Normalizer
participant BE as Backend
participant DM as Data Marketplace
participant AA as Kho lưu trữ Admin
participant WS as WebSocket
participant FE as Frontend
loop Crawl liên tục (window now lùi 2 phút)
Crawler->>Source: Liệt kê tin trong window
Source-->>Crawler: Danh sách tin ứng viên
Crawler->>Crawler: Tra listings theo source + source_id
alt source + source_id đã tồn tại
Crawler->>Crawler: Bỏ qua tin (không xử lý tiếp)
else chưa tồn tại
Crawler->>Source: Lấy chi tiết tin
Source-->>Crawler: Dữ liệu gốc
Crawler->>Normalizer: Payload thô theo nguồn
Normalizer->>Normalizer: Chuẩn hóa thành property, listing, contact, nguồn
alt số điện thoại trống hoặc không hợp lệ
Normalizer->>Normalizer: Bỏ tin (không gửi Backend)
else có số điện thoại hợp lệ
Normalizer->>BE: Tra property theo address + area_m2 + property_type_id
alt property đã tồn tại
BE-->>Normalizer: property_id hiện có
else chưa tồn tại
Normalizer->>BE: POST /properties
BE-->>Normalizer: property_id mới tạo
end
Normalizer->>BE: Tra phone_registries theo số điện thoại
alt số điện thoại đã có trong phone_registries
BE-->>Normalizer: phone_registry_id hiện có
else chưa có
Normalizer->>BE: Tạo phone_registries lưu số điện thoại
BE-->>Normalizer: phone_registry_id mới tạo
end
Normalizer->>BE: Tra contact theo phone_registry_id
alt contact đã tồn tại
BE-->>Normalizer: contact_id hiện có
else chưa tồn tại
Normalizer->>BE: Tạo contact gắn phone_registry_id
BE-->>Normalizer: contact_id mới tạo
end
Normalizer->>BE: POST /listings (property_id, contact_id, source, source_id, source_url)
end
end
end
Note over BE: POST /listings (auth tài khoản broker tạo sẵn) xử lý như tin thường
BE->>BE: Tạo listing gắn property_id + contact_id
BE->>BE: Tính trust_score + bổ sung field hệ thống
alt trust_score < 80
BE->>DM: Lưu vào Data Marketplace (public)
BE->>WS: LISTING_CREATED hoặc LISTING_UPDATED
WS->>FE: Push realtime
FE->>FE: Cập nhật listing trên UI
else trust_score ≥ 80
BE->>AA: Lưu vào kho lưu trữ Admin (admin-only)
BE->>WS: Event nội bộ admin (Dev quyết)
end
alt trust_score thay đổi
BE->>WS: LISTING_TRUST_SCORE_UPDATED
endPhân vai nghiệp vụ:
| Vai trò | Trách nhiệm |
|---|---|
| Crawler | Crawl liên tục từng nguồn; tra listings theo source + source_id trước khi xử lý, bỏ qua tin đã có; loại tin thiếu số điện thoại; xử lý lỗi kết nối/parse cơ bản |
| Normalizer | Chuẩn hóa dữ liệu thành 4 nhóm (property, listing, contact, nguồn); orchestrate: tra/tạo property qua POST /properties, tra/tạo phone_registries theo số điện thoại + tra/tạo contacts, map CreateListingRequest rồi gọi POST /listings |
| Backend | Cung cấp POST /properties, POST /listings, logic contact + phone_registries; validate đầy đủ như tin app; tính trust_score; route Data Marketplace / kho Admin; lưu DB + phát event |
| WebSocket | Đẩy event realtime tới Frontend (public Data Marketplace) hoặc admin channel (kho Admin) |
| Frontend | Subscribe event, cập nhật UI listing trong Data Marketplace |
Acceptance Criteria
- AC-1: Hệ thống crawl được tin đăng từ đủ 3 nguồn: Muaban.net, Nhà Tốt, Batdongsan.com.vn.
- AC-2: Giá trị
sourcechỉ nhận một trong:MUABAN,NHATOT,BATDONGSAN. - AC-3: Giá trị
listing_typeschỉ nhận: bán hoặc cho thuê. - AC-4: Sau crawl, dữ liệu được chuẩn hóa thành 4 nhóm — property, listing, contact, thông tin nguồn — khớp request của
POST /propertiesvàPOST /listings. - AC-5: Trước khi xử lý một tin, hệ thống tra
listingstheo cặpsource + source_id. Nếu đã tồn tại → bỏ qua: không tạo property, không tạo contact, không gọiPOST /listings. - AC-6: Nếu
source + source_idchưa tồn tại → tiếp tục xử lý property và contact. - AC-7: Tra property theo
address + area_m2 + property_type_id. Khớp → dùngproperty_idhiện có (không tạo mới, không ghi đè). Không khớp → gọiPOST /properties, lấyproperty_idvừa tạo. - AC-8:
property_id(tái dùng hoặc mới tạo) được gắn vàoCreateListingRequest. - AC-9: Tồn tại bảng
contactsvới tối thiểu các field:id,contact_name,phone_registry_id(FK →phone_registries.id),created_at,updated_at(có thể bổ sungstatus,source,note). Số điện thoại không lưu trêncontactsmà ởphone_registries. - AC-10:
contact_namevà số điện thoại không lưu trực tiếp trênlistings.contact_namelưu ởcontacts; số điện thoại lưu ởphone_registries(contacts trỏ tới quaphone_registry_id).listingstham chiếu liên hệ quacontact_id. - AC-11: Quan hệ
contacts↔listingslà một-nhiều: một contact có nhiều listings, một listing chỉ gắn một contact. Không tạo bảng trung gianlisting_contacts. - AC-12: Resolve liên hệ theo số điện thoại: tra/tạo
phone_registriestheo số điện thoại, rồi tra/tạocontactstrỏ tớiphone_registry_id. Đã có → dùngcontact_idhiện có; chưa có → tạo mới. Nhiều tin cùng số điện thoại → cùng mộtphone_registry→ cùng một contact. - AC-13: Tin thiếu số điện thoại hợp lệ bị loại tại crawl — không tạo
phone_registries, không tạo contact, không tạo property, không gọiPOST /listings. - AC-14:
CreateListingRequestnhận đượcproperty_id,contact_id,source,source_id,source_url. - AC-15: Tin crawl được tạo qua
POST /listings(đi chung luồng tin tạo từ app). Không dùng chế độ ingest; không bỏ qua validate user-facing — Backend xử lý như request tạo listing bình thường. - AC-16:
source,source_id,source_urllưu trực tiếp trênlistings, không qua bảng stagingdata_sources. - AC-17: Không đặt unique constraint
(source, source_id)ở DB. Chống trùng chỉ dựa vào kiểm tra tại crawl (tralistingstheosource + source_idtrước khi xử lý — xem AC-5). - AC-18: Không resolve
users/owner theo số điện thoại;phone_registrieschỉ là nơi lưu số điện thoại màcontactstham chiếu (quaphone_registry_id), không dùng để suy ra user sở hữu listing.contact_phonechỉ là số liên hệ, không phải căn cứ định danh user. - AC-19: Không còn bảng staging
data_sources; các trường cần thiết từ nguồn map trực tiếp vào requestPOST /properties/POST /listingsvà lưu trênlistings. - AC-20: Backend tính
trust_score,trust_score_breakdown,trust_score_calculated_at; phía crawl không gán các field này. - AC-21: Tin
trust_score < 80auto-publish vào Data Marketplace (public) ngay sau khi Backend xử lý; tintrust_score ≥ 80route vào kho lưu trữ Admin (admin-only), không publish public. - AC-22: Khi listing (
trust_score < 80) mới được tạo → eventLISTING_CREATEDqua WebSocket public; khi cập nhật →LISTING_UPDATED; khitrust_scorethay đổi →LISTING_TRUST_SCORE_UPDATED. - AC-23: Frontend nhận event WebSocket public và phản ánh thay đổi listing trên giao diện.
- AC-24: Hai tin khác
source + source_idnhưng resolve về cùngproperty_id→ giữ listing riêng cho từng tin, cùng trỏ tới một property (không merge). - AC-25: Lỗi crawl một nguồn không làm dừng pipeline các nguồn còn lại; lỗi chuẩn hóa một bản ghi không fail cả batch (log kèm
source,source_id).
Quy tắc nghiệp vụ
- Mỗi tin từ nguồn ngoài định danh duy nhất bởi cặp
source + source_id;sourcechỉ nhậnMUABAN/NHATOT/BATDONGSAN. - Crawl liên tục: xong lượt nào bắt đầu lượt kế tiếp ngay (không chờ interval cố định).
time_windows=[now − 2 phút, now]— chỉ lấy tin có thời điểm đăng/cập nhật tại nguồn trong khung này. - Chống trùng (tại crawl, lớp duy nhất): trước khi lấy chi tiết/xử lý, tra
listingstheosource + source_id; đã có → bỏ qua tin (không fetch tiếp, không tạo property/contact, không gọiPOST /listings). Không đặt unique constraint(source, source_id)ở DB làm chốt cuối — chống trùng chỉ ở lớp crawl này. - Loại tin thiếu liên hệ: số điện thoại null/rỗng/không hợp lệ → drop tại crawl (tin không liên hệ được coi là rác).
- Chuẩn hóa 4 nhóm: property, listing, contact, thông tin nguồn — map trực tiếp vào request
POST /propertiesvàPOST /listings; không qua staging. - Tái dùng property: tra theo
address + area_m2 + property_type_id. Khớp → dùngproperty_idhiện có, không tạo mới và không ghi đè. Không khớp →POST /properties→ lấyproperty_idmới. Thuật toán normalization địa chỉ/threshold match do Dev quyết ở repo BE. - Số điện thoại lưu ở
phone_registries: số điện thoại liên hệ không lưu trêncontactsmà ởphone_registries;contactscó khóa ngoạiphone_registry_id→phone_registries.id.phonenên là khóa tra duy nhất trongphone_registries. - Resolve liên hệ theo số điện thoại: tra/tạo
phone_registriestheo số điện thoại → tra/tạocontactstheophone_registry_id. Đã có → dùng lại; chưa có → tạo mới. Cùng số điện thoại ở nhiều tin → cùng mộtphone_registry→ cùng một contact. - Quan hệ contact–listing là một-nhiều: khóa ngoại
contact_idđặt trực tiếp trênlistings; không tạo bảng trung gianlisting_contacts. Một contact có nhiều listings, một listing gắn đúng một contact. - Contact chỉ để hiển thị/liên hệ: không dùng contact/số điện thoại để resolve
users/owners; không xác định user sở hữu listing qua contact. - Không resolve user/owner theo số điện thoại:
phone_registriesđược tái dùng làm nơi lưu số điện thoại (contacts trỏ tới quaphone_registry_id), không dùng để xác định user/owner của listing; không đi từphone_registries.user_idđể gán owner. - Tạo listing qua
POST /listings(luồng thường):CreateListingRequestnhậnproperty_id,contact_id,source,source_id,source_url. Validate đầy đủ như tin app; không ingest, không bỏ qua validate. Vì dùng chung validate user-facing, payload crawl phải đáp ứng ràng buộc của tin app (field bắt buộc,property_idhợp lệ, ảnh theo chuẩn hệ thống) — cách đáp ứng ràng buộc ảnh cho tin crawl (vd re-host) do Dev quyết. - Owner tin crawl = tài khoản broker tạo sẵn:
POST /listingsđược gọi bằng một tài khoản broker (seed) đã tạo trước; owner của listing crawl là tài khoản broker này (gắn theo JWT như tin app). Vẫn không resolve user/owner theo SĐT — owner đến từ tài khoản broker, không suy ra từphone_registries. - Trường nguồn trên
listings:source(tên nguồn crawl),source_id(id gốc tin tại nguồn),source_url(link gốc tin). - Bỏ bảng
data_sources: không lưu staging; thông tin nguồn →listings, thông tin liên hệ →contacts(listing tham chiếu qualistings.contact_id), số điện thoại →phone_registries. - Thứ tự pipeline:
source + source_id(bỏ nếu đã có) → kiểm tra số điện thoại (bỏ nếu thiếu) → property (tái dùng/tạo) →phone_registries(tra/tạo theo số điện thoại) → contact (tra/tạo theophone_registry_id) →POST /listings. - trust_score + routing (giữ — chạy trong luồng
POST /listingsthường): Backend tínhtrust_score;trust_score < 80→ Data Marketplace (public, auto-publish, không moderation thủ công);trust_score ≥ 80→ kho lưu trữ Admin (admin-only, không public). Phía crawl không gántrust_score. - 3 nguồn bắt buộc gồm Batdongsan (nguồn mới bổ sung) — backend phải chấp nhận
source = BATDONGSANđầy đủ như 2 nguồn còn lại; backend hiện mới nhậnnhatot/muabannên cần mở rộng (cách hiện thực do Dev quyết ở repo BE). - Đã có sự cho phép crawl từ 3 nguồn (Muaban.net, Nhà Tốt, Batdongsan.com.vn); vận hành phải tuân thủ điều khoản đã thỏa thuận.
- Listings trong kho lưu trữ Admin không phát event công khai; event nội bộ admin do Dev quyết.
- Thông tin liên hệ tuân thủ chính sách masking/permission hiện có của hệ thống (tham chiếu RBAC listing).
Dữ liệu & Trạng thái
Bảng contacts (mới) — lưu thông tin liên hệ, quan hệ một-nhiều với listings; số điện thoại nằm ở phone_registries:
| Field | Mô tả | Bắt buộc |
|---|---|---|
id | ID contact | ✓ |
contact_name | Tên người liên hệ | ✓ (tối thiểu) |
phone_registry_id | FK → phone_registries.id — nơi lưu số điện thoại liên hệ | ✓ |
status | Trạng thái contact | optional |
source | Nguồn của contact (vd CRAWL) | optional |
note | Ghi chú | optional |
created_at | Thời điểm tạo | ✓ |
updated_at | Thời điểm cập nhật | ✓ |
contact_name= tên người liên hệ; số điện thoại không lưu trêncontactsmà truy cập quaphone_registry_id→phone_registries.phone.- Contact chỉ phục vụ hiển thị/liên lạc; không dùng để resolve
users/owners.
Bảng phone_registries (tái dùng) — nơi lưu số điện thoại mà contacts tham chiếu:
| Field | Mô tả |
|---|---|
id | ID bản ghi |
phone | Số điện thoại liên hệ (khóa tra, nên unique) |
user_id | (cột hệ thống hiện có) không dùng để resolve owner trong luồng crawl |
is_blocked / block_reason | (cột hệ thống hiện có) tuỳ chính sách |
created_at / updated_at | Thời điểm tạo / cập nhật |
- Trong luồng crawl,
phone_registrieschỉ đóng vai kho lưu số điện thoại; không đi từphone_registries.user_idđể xác định user/owner của listing.
Bảng listings — field bổ sung/liên quan luồng crawl (các field khác giữ như tin tạo từ app):
| Field | Mô tả | Ai điền |
|---|---|---|
id | ID listing | Backend |
property_id | FK → properties (tái dùng nếu khớp) | Crawl resolve |
contact_id | FK → contacts.id (một-nhiều) — mới | Crawl resolve |
title, description, price | Nội dung tin | Crawl |
listing_types | bán / cho thuê | Crawl |
image_urls | Danh sách URL ảnh | Crawl |
status | Trạng thái listing | Backend |
source | Nguồn crawl: MUABAN / NHATOT / BATDONGSAN — mới (trên listings) | Crawl |
source_id | ID tin tại nguồn gốc — mới | Crawl |
source_url | Link tin gốc — mới | Crawl |
posted_at | Thời điểm đăng tại nguồn | Crawl |
scraped_at | Thời điểm crawl về | Backend/Crawl |
trust_score | Điểm uy tín (0–100) | Backend |
trust_score_breakdown | Chi tiết thành phần điểm | Backend |
trust_score_calculated_at | Thời điểm tính trust_score | Backend |
published_at | Thời điểm publish Data Marketplace (chỉ trust_score < 80) | Backend |
created_at / updated_at | Thời điểm tạo / cập nhật | Hệ thống |
- Không lưu
contact_name/ số điện thoại trênlistings; liên hệ truy cập quacontact_id→contacts→phone_registries. - Các field hệ thống khác của listing (counters, exclusive,
expired_at, …) giữ như tin tạo từ app.
Property — resolve qua endpoint hiện có:
- Match theo
address + area_m2 + property_type_id: khớp → tái dùngproperty_id; không khớp →POST /properties. - Schema/payload đầy đủ của property thuộc endpoint
POST /properties(feature properties) — requirement này chỉ dùngproperty_idtrả về. Thuật toán normalization/threshold match do Dev quyết.
Quan hệ dữ liệu:
contacts.id1 — Nlistings.contact_id(một contact, nhiều listings).contacts.phone_registry_id→phone_registries.id(số điện thoại lưu ởphone_registries;phonenên unique nên mỗi số ↔ mộtphone_registry↔ một contact).listings.property_id→properties.id(tái dùng nếu khớpaddress + area_m2 + property_type_id).listingslưusource,source_id,source_url.
Đã loại khỏi luồng crawl: resolve user/owner theo số điện thoại (không resolve users), bảng staging data_sources. (phone_registries được tái dùng làm nơi lưu số điện thoại, không dùng resolve owner.)
Trạng thái listing (status):
- Backend quản lý vòng đời listing (vd draft, published, archived, expired… — giá trị cụ thể do Dev quy ước ở repo source).
trust_score < 80→ public trong Data Marketplace (auto-publish, ghipublished_at).trust_score ≥ 80→ archived trong kho lưu trữ Admin, không ghipublished_atpublic.
Event WebSocket:
| Event | Khi nào phát | Channel |
|---|---|---|
LISTING_CREATED | Listing mới (trust_score < 80) trong Data Marketplace | Public |
LISTING_UPDATED | Listing (trust_score < 80) được cập nhật | Public |
LISTING_TRUST_SCORE_UPDATED | trust_score thay đổi sau xử lý Backend | Public (nếu listing đang trong Data Marketplace) |
| Admin event (Dev quyết) | Listing route vào kho lưu trữ Admin (trust_score ≥ 80) | Admin-only |
Trạng thái xử lý pipeline crawl:
normalized— đã chuẩn hóa 4 nhómskipped_duplicate—source + source_idđã có, bỏ quadropped_no_contact— thiếu số điện thoại, bỏ tinsubmitted— đã gọiPOST /listingspublished_marketplace—trust_score < 80, vào Data Marketplaceadmin_archived—trust_score ≥ 80, vào kho lưu trữ Adminfailed— lỗi crawl hoặc chuẩn hóa
Liên quan
- Phụ thuộc: Chưa có
- Ảnh hưởng: broker-daily-listing-distribution — Data Marketplace (tin
trust_score < 80) là pool cho Auto Distribution paid tier; routingtrust_score ≥ 80ảnh hưởng pool có sẵn cho broker. Lưu ý: số điện thoại tin crawl nay nằm ởphone_registries.phone, truy cập qualistings.contact_id→contacts.phone_registry_id→phone_registries(không quausers/owner) — feature đó cần điều chỉnh cách lấyphone_fullcho tin crawl theo đường này.