fix(api,web): runtime fixes found during E2E + DB seed repair
Some checks failed
Security Scanning / Trivy Scan — API Image (push) Failing after 53s
Security Scanning / Trivy Scan — AI Services Image (push) Has been cancelled
Security Scanning / Trivy Filesystem Scan (push) Has been cancelled
Security Scanning / Security Gate (push) Has been cancelled
Security Scanning / Trivy Scan — Web Image (push) Has started running
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 10s
CI / AI Services (Python) — Smoke (push) Failing after 5s
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 58s
Deploy / Build API Image (push) Failing after 18s
Deploy / Build Web Image (push) Failing after 7s
CI / E2E Tests (push) Has been skipped
Deploy / Build AI Services Image (push) Failing after 7s
E2E Tests / Playwright E2E (push) Failing after 16s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 4s
Deploy / Smoke Test Staging (push) Has been cancelled
Deploy / Deploy to Staging (push) Has been cancelled
Deploy / Deploy to Production (push) Has been cancelled
Deploy / Rollback Staging (push) Has been cancelled
Deploy / Smoke Test Production (push) Has been cancelled
Deploy / Rollback Production (push) Has been cancelled

API bootstrap fixes (DI wiring):
- analytics.module: add forwardRef(() => AdminModule) to import
  AI_CONFIG_PROVIDER for GetListingAiAdviceHandler + GetProjectAiAdviceHandler
- listings.module: add PaymentsModule to imports so PAYMENT_INITIATOR is
  resolvable by FeatureListingHandler
- metrics.module: register 3 missing Prometheus providers that MetricsService
  injects (READ_MODEL_PROJECTOR_LAG_SECONDS / REFRESH_DURATION /
  RECONCILIATION_DRIFT_TOTAL) — caused boot failure previously
- get-listing-ai-advice.handler: switch LISTING_REPOSITORY import from barrel
  @modules/listings to direct internal path to break circular reference that
  made the symbol evaluate as undefined at decorator time
- shared.module: comment out broken EVENT_BUS / OutboxService / OutboxRelay
  providers (depend on @goodgo/contracts-events workspace pkg not yet wired)

CSRF middleware:
- Rewrite exclude logic as inline path-check inside the middleware itself.
  Nest 11 + path-to-regexp v8 changed how MiddlewareConsumer.exclude() matches
  against forRoutes('*') — the previous string patterns silently stopped
  matching, causing every POST to /auth/login to return 403 CSRF Forbidden.
  Inlined exempt list strips the /api/v1 prefix and checks against a Set.

Admin revenue stats:
- admin-stats.queries: use Prisma.sql template fragments for DATE_TRUNC unit
  ('day'|'month'). Passing the unit as a bind parameter caused Postgres error
  42803 (column must appear in GROUP BY) because the planner treats $1 as an
  opaque scalar and cannot prove SELECT and GROUP BY expressions are equal.

Admin audit-log page:
- SeverityPill: add ?? 'info' fallback — backend AuditLogEntry does not
  include a `severity` field, so SEVERITY_CONFIG[undefined] was undefined
  and .dir threw TypeError, crashing the whole audit-log page.

DB seed fixes:
- seed.ts: replace Vietnamese enum literals ('Sổ hồng', 'Sổ đỏ') with
  correct enum keys ('SO_HONG', 'SO_DO') for the LegalStatus column
- seed-industrial-parks.ts: gate the standalone main() behind
  require.main === module so importing the file from seed.ts doesn't
  immediately close the pg.Pool used by the orchestrator
- scripts/seed-industrial-listings.ts: restore from tmp/ stash; was missing
  from scripts/ causing seed.ts import to fail at startup
- migration 20260429010000_add_property_certificate_verified: Property table
  was missing the certificateVerified column required by seed + Prisma schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ho Ngoc Hai
2026-04-29 16:46:50 +07:00
parent 489d61a27b
commit f222611fcf
12 changed files with 645 additions and 20 deletions

View File

@@ -0,0 +1,6 @@
-- Add Property.certificateVerified flag — true when the listing's owner has
-- uploaded an ownership certificate (red book / pink book) that has passed
-- moderation. Defaults to false so existing rows keep current behaviour.
ALTER TABLE "Property"
ADD COLUMN "certificateVerified" BOOLEAN NOT NULL DEFAULT false;

View File

@@ -357,16 +357,16 @@ async function seedProperties() {
}
const properties: PropSeed[] = [
{ id: 'seed-prop-001', propertyType: PropertyType.APARTMENT, title: 'Căn hộ Vinhomes Central Park 3PN view sông Sài Gòn', description: 'Căn hộ 3 phòng ngủ tại Vinhomes Central Park, tầng cao view sông Sài Gòn tuyệt đẹp. Full nội thất cao cấp Châu Âu, tiện ích 5 sao.', address: '208 Nguyễn Hữu Cảnh', ward: 'Phường 22', district: 'Quận Bình Thạnh', city: 'Hồ Chí Minh', lat: 10.7942, lng: 106.7214, areaM2: 108, usableAreaM2: 95, bedrooms: 3, bathrooms: 2, floor: 25, totalFloors: 50, direction: Direction.SOUTHEAST, yearBuilt: 2018, legalStatus: 'Sổ hồng', projectName: 'Vinhomes Central Park', amenities: '["hồ bơi","gym","công viên","siêu thị"]' },
{ id: 'seed-prop-002', propertyType: PropertyType.APARTMENT, title: 'Căn hộ The Sun Avenue 2PN cho thuê gần Metro', description: 'Cho thuê căn hộ 2PN The Sun Avenue, nội thất đầy đủ, gần tuyến Metro số 1.', address: '28 Mai Chí Thọ', ward: 'An Phú', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.7696, lng: 106.7511, areaM2: 76, usableAreaM2: 68, bedrooms: 2, bathrooms: 2, floor: 15, totalFloors: 28, direction: Direction.NORTH, yearBuilt: 2020, legalStatus: 'Sổ hồng', projectName: 'The Sun Avenue', amenities: '["hồ bơi","gym","BBQ"]' },
{ id: 'seed-prop-003', propertyType: PropertyType.TOWNHOUSE, title: 'Nhà phố Thảo Điền 1 trệt 3 lầu compound an ninh', description: 'Nhà phố khu compound an ninh Thảo Điền, sân vườn rộng, gara 2 ô tô.', address: '12 Nguyễn Văn Hưởng', ward: 'Thảo Điền', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.8033, lng: 106.7391, areaM2: 200, usableAreaM2: 350, bedrooms: 4, bathrooms: 5, floors: 4, direction: Direction.SOUTH, yearBuilt: 2015, legalStatus: 'Sổ hồng', projectName: null, amenities: '["sân vườn","gara ô tô","bảo vệ 24/7"]' },
{ id: 'seed-prop-004', propertyType: PropertyType.LAND, title: 'Đất nền Quận 7 gần Phú Mỹ Hưng thổ cư 100%', description: 'Đất nền thổ cư 100%, sổ riêng từng nền, hẻm ô tô 8m.', address: '56 Huỳnh Tấn Phát', ward: 'Phú Thuận', district: 'Quận 7', city: 'Hồ Chí Minh', lat: 10.7312, lng: 106.7283, areaM2: 120, usableAreaM2: null, bedrooms: null, bathrooms: null, direction: Direction.EAST, yearBuilt: null, legalStatus: 'Sổ đỏ', projectName: null, amenities: null },
{ id: 'seed-prop-005', propertyType: PropertyType.OFFICE, title: 'Văn phòng cho thuê Quận 1 200m² trung tâm Nguyễn Huệ', description: 'Văn phòng hạng B+ trung tâm Quận 1, full nội thất, PCCC, thang máy.', address: '123 Nguyễn Huệ', ward: 'Bến Nghé', district: 'Quận 1', city: 'Hồ Chí Minh', lat: 10.7731, lng: 106.703, areaM2: 200, usableAreaM2: 180, bedrooms: null, bathrooms: 2, floor: 8, totalFloors: 15, direction: Direction.WEST, yearBuilt: 2010, legalStatus: 'Sổ hồng', projectName: null, amenities: '["thang máy","PCCC","bảo vệ 24/7"]' },
{ id: 'seed-prop-006', propertyType: PropertyType.VILLA, title: 'Biệt thự Sala Đại Quang Minh view công viên', description: 'Biệt thự song lập Sala, 230m² đất, 1 trệt 2 lầu 1 áp mái, bể bơi riêng.', address: '10 Mai Chí Thọ', ward: 'An Lợi Đông', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.7721, lng: 106.7432, areaM2: 230, usableAreaM2: 420, bedrooms: 5, bathrooms: 6, floors: 3, direction: Direction.NORTHEAST, yearBuilt: 2019, legalStatus: 'Sổ hồng', projectName: 'Sala Đại Quang Minh', amenities: '["bể bơi riêng","sân vườn","gara 3 ô tô"]' },
{ id: 'seed-prop-007', propertyType: PropertyType.SHOPHOUSE, title: 'Shophouse Vạn Phúc City mặt tiền kinh doanh', description: 'Shophouse mặt tiền 30m khu đô thị Vạn Phúc City, 1 trệt 4 lầu.', address: '15 Nguyễn Thị Nhung', ward: 'Hiệp Bình Phước', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.8345, lng: 106.7188, areaM2: 100, usableAreaM2: 400, bedrooms: 3, bathrooms: 4, floors: 5, direction: Direction.SOUTH, yearBuilt: 2022, legalStatus: 'Sổ hồng', projectName: 'Vạn Phúc City', amenities: '["mặt tiền kinh doanh","bãi đỗ xe"]' },
{ id: 'seed-prop-008', propertyType: PropertyType.APARTMENT, title: 'Căn hộ Masteri Thảo Điền 1PN full nội thất', description: 'Căn hộ 1PN Masteri Thảo Điền, nội thất cao cấp, view hồ bơi.', address: '159 Xa lộ Hà Nội', ward: 'Thảo Điền', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.8025, lng: 106.7415, areaM2: 50, usableAreaM2: 45, bedrooms: 1, bathrooms: 1, floor: 12, totalFloors: 40, direction: Direction.NORTHWEST, yearBuilt: 2017, legalStatus: 'Sổ hồng', projectName: 'Masteri Thảo Điền', amenities: '["hồ bơi","gym","sky lounge"]' },
{ id: 'seed-prop-009', propertyType: PropertyType.APARTMENT, title: 'Căn hộ Midtown Phú Mỹ Hưng 2PN giá tốt', description: 'Căn hộ 2PN Midtown The Peak, Phú Mỹ Hưng. Nội thất cơ bản, view đẹp.', address: '12 Nguyễn Lương Bằng', ward: 'Tân Phú', district: 'Quận 7', city: 'Hồ Chí Minh', lat: 10.7285, lng: 106.7195, areaM2: 85, usableAreaM2: 78, bedrooms: 2, bathrooms: 2, floor: 18, totalFloors: 30, direction: Direction.EAST, yearBuilt: 2021, legalStatus: 'Sổ hồng', projectName: 'Midtown Phú Mỹ Hưng', amenities: '["hồ bơi","gym","công viên"]' },
{ id: 'seed-prop-010', propertyType: PropertyType.TOWNHOUSE, title: 'Nhà phố Gò Vấp 1 trệt 2 lầu sổ hồng riêng', description: 'Nhà phố mới xây tại Gò Vấp, 1 trệt 2 lầu, sân thượng, hẻm xe hơi 6m.', address: '88 Nguyễn Oanh', ward: 'Phường 17', district: 'Quận Gò Vấp', city: 'Hồ Chí Minh', lat: 10.8352, lng: 106.6648, areaM2: 65, usableAreaM2: 150, bedrooms: 3, bathrooms: 3, floors: 3, direction: Direction.WEST, yearBuilt: 2024, legalStatus: 'Sổ hồng', projectName: null, amenities: '["sân thượng","ban công"]' },
{ id: 'seed-prop-001', propertyType: PropertyType.APARTMENT, title: 'Căn hộ Vinhomes Central Park 3PN view sông Sài Gòn', description: 'Căn hộ 3 phòng ngủ tại Vinhomes Central Park, tầng cao view sông Sài Gòn tuyệt đẹp. Full nội thất cao cấp Châu Âu, tiện ích 5 sao.', address: '208 Nguyễn Hữu Cảnh', ward: 'Phường 22', district: 'Quận Bình Thạnh', city: 'Hồ Chí Minh', lat: 10.7942, lng: 106.7214, areaM2: 108, usableAreaM2: 95, bedrooms: 3, bathrooms: 2, floor: 25, totalFloors: 50, direction: Direction.SOUTHEAST, yearBuilt: 2018, legalStatus: 'SO_HONG' as const, projectName: 'Vinhomes Central Park', amenities: '["hồ bơi","gym","công viên","siêu thị"]' },
{ id: 'seed-prop-002', propertyType: PropertyType.APARTMENT, title: 'Căn hộ The Sun Avenue 2PN cho thuê gần Metro', description: 'Cho thuê căn hộ 2PN The Sun Avenue, nội thất đầy đủ, gần tuyến Metro số 1.', address: '28 Mai Chí Thọ', ward: 'An Phú', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.7696, lng: 106.7511, areaM2: 76, usableAreaM2: 68, bedrooms: 2, bathrooms: 2, floor: 15, totalFloors: 28, direction: Direction.NORTH, yearBuilt: 2020, legalStatus: 'SO_HONG' as const, projectName: 'The Sun Avenue', amenities: '["hồ bơi","gym","BBQ"]' },
{ id: 'seed-prop-003', propertyType: PropertyType.TOWNHOUSE, title: 'Nhà phố Thảo Điền 1 trệt 3 lầu compound an ninh', description: 'Nhà phố khu compound an ninh Thảo Điền, sân vườn rộng, gara 2 ô tô.', address: '12 Nguyễn Văn Hưởng', ward: 'Thảo Điền', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.8033, lng: 106.7391, areaM2: 200, usableAreaM2: 350, bedrooms: 4, bathrooms: 5, floors: 4, direction: Direction.SOUTH, yearBuilt: 2015, legalStatus: 'SO_HONG' as const, projectName: null, amenities: '["sân vườn","gara ô tô","bảo vệ 24/7"]' },
{ id: 'seed-prop-004', propertyType: PropertyType.LAND, title: 'Đất nền Quận 7 gần Phú Mỹ Hưng thổ cư 100%', description: 'Đất nền thổ cư 100%, sổ riêng từng nền, hẻm ô tô 8m.', address: '56 Huỳnh Tấn Phát', ward: 'Phú Thuận', district: 'Quận 7', city: 'Hồ Chí Minh', lat: 10.7312, lng: 106.7283, areaM2: 120, usableAreaM2: null, bedrooms: null, bathrooms: null, direction: Direction.EAST, yearBuilt: null, legalStatus: 'SO_DO' as const, projectName: null, amenities: null },
{ id: 'seed-prop-005', propertyType: PropertyType.OFFICE, title: 'Văn phòng cho thuê Quận 1 200m² trung tâm Nguyễn Huệ', description: 'Văn phòng hạng B+ trung tâm Quận 1, full nội thất, PCCC, thang máy.', address: '123 Nguyễn Huệ', ward: 'Bến Nghé', district: 'Quận 1', city: 'Hồ Chí Minh', lat: 10.7731, lng: 106.703, areaM2: 200, usableAreaM2: 180, bedrooms: null, bathrooms: 2, floor: 8, totalFloors: 15, direction: Direction.WEST, yearBuilt: 2010, legalStatus: 'SO_HONG' as const, projectName: null, amenities: '["thang máy","PCCC","bảo vệ 24/7"]' },
{ id: 'seed-prop-006', propertyType: PropertyType.VILLA, title: 'Biệt thự Sala Đại Quang Minh view công viên', description: 'Biệt thự song lập Sala, 230m² đất, 1 trệt 2 lầu 1 áp mái, bể bơi riêng.', address: '10 Mai Chí Thọ', ward: 'An Lợi Đông', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.7721, lng: 106.7432, areaM2: 230, usableAreaM2: 420, bedrooms: 5, bathrooms: 6, floors: 3, direction: Direction.NORTHEAST, yearBuilt: 2019, legalStatus: 'SO_HONG' as const, projectName: 'Sala Đại Quang Minh', amenities: '["bể bơi riêng","sân vườn","gara 3 ô tô"]' },
{ id: 'seed-prop-007', propertyType: PropertyType.SHOPHOUSE, title: 'Shophouse Vạn Phúc City mặt tiền kinh doanh', description: 'Shophouse mặt tiền 30m khu đô thị Vạn Phúc City, 1 trệt 4 lầu.', address: '15 Nguyễn Thị Nhung', ward: 'Hiệp Bình Phước', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.8345, lng: 106.7188, areaM2: 100, usableAreaM2: 400, bedrooms: 3, bathrooms: 4, floors: 5, direction: Direction.SOUTH, yearBuilt: 2022, legalStatus: 'SO_HONG' as const, projectName: 'Vạn Phúc City', amenities: '["mặt tiền kinh doanh","bãi đỗ xe"]' },
{ id: 'seed-prop-008', propertyType: PropertyType.APARTMENT, title: 'Căn hộ Masteri Thảo Điền 1PN full nội thất', description: 'Căn hộ 1PN Masteri Thảo Điền, nội thất cao cấp, view hồ bơi.', address: '159 Xa lộ Hà Nội', ward: 'Thảo Điền', district: 'Thủ Đức', city: 'Hồ Chí Minh', lat: 10.8025, lng: 106.7415, areaM2: 50, usableAreaM2: 45, bedrooms: 1, bathrooms: 1, floor: 12, totalFloors: 40, direction: Direction.NORTHWEST, yearBuilt: 2017, legalStatus: 'SO_HONG' as const, projectName: 'Masteri Thảo Điền', amenities: '["hồ bơi","gym","sky lounge"]' },
{ id: 'seed-prop-009', propertyType: PropertyType.APARTMENT, title: 'Căn hộ Midtown Phú Mỹ Hưng 2PN giá tốt', description: 'Căn hộ 2PN Midtown The Peak, Phú Mỹ Hưng. Nội thất cơ bản, view đẹp.', address: '12 Nguyễn Lương Bằng', ward: 'Tân Phú', district: 'Quận 7', city: 'Hồ Chí Minh', lat: 10.7285, lng: 106.7195, areaM2: 85, usableAreaM2: 78, bedrooms: 2, bathrooms: 2, floor: 18, totalFloors: 30, direction: Direction.EAST, yearBuilt: 2021, legalStatus: 'SO_HONG' as const, projectName: 'Midtown Phú Mỹ Hưng', amenities: '["hồ bơi","gym","công viên"]' },
{ id: 'seed-prop-010', propertyType: PropertyType.TOWNHOUSE, title: 'Nhà phố Gò Vấp 1 trệt 2 lầu sổ hồng riêng', description: 'Nhà phố mới xây tại Gò Vấp, 1 trệt 2 lầu, sân thượng, hẻm xe hơi 6m.', address: '88 Nguyễn Oanh', ward: 'Phường 17', district: 'Quận Gò Vấp', city: 'Hồ Chí Minh', lat: 10.8352, lng: 106.6648, areaM2: 65, usableAreaM2: 150, bedrooms: 3, bathrooms: 3, floors: 3, direction: Direction.WEST, yearBuilt: 2024, legalStatus: 'SO_HONG' as const, projectName: null, amenities: '["sân thượng","ban công"]' },
];
for (const p of properties) {