Commit Graph

320 Commits

Author SHA1 Message Date
Ho Ngoc Hai
caa0a58afd feat(notifications): R8.1 Stringee SMS adapter + rate limiting (TEC-2764)
- Add NotificationChannelPort domain port for SMS/transactional channels.
- Refactor StringeeSmsService to implement the port; routes OTP template
  keys through the tighter otp bucket and transactional keys through the
  wider bucket.
- Add SmsRateLimiterService using a Redis sorted-set sliding window with
  per-minute + per-hour limits per phone; fails open on Redis errors.
- Rate-limit violations throw DomainException(TOO_MANY_REQUESTS, 429)
  with retryAfterSeconds in the details payload.
- Cover adapter + rate limiter with unit tests (22 specs); all 148
  notifications tests still green.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:37:45 +07:00
Ho Ngoc Hai
8c6e3b92d0 feat(notifications): R2.8 residential WS events (TEC-2759)
- Add emitResidentialEvent helper on NotificationsGateway that fans
  residential:price-drop, residential:new-listing-in-project, and
  residential:inquiry-reply to the user's /notifications room.
- Wire three CQRS @EventsHandler listeners on ListingPriceChangedEvent
  (only when newPrice < oldPrice, match saved searches),
  ListingApprovedEvent (match saved searches with filters.projectId
  against property.projectDevelopmentId), and InquiryReadEvent
  (notify inquiry author).
- Redis pub/sub fan-out already handled by RedisIoAdapter from
  TEC-2766, so these broadcasts work across API instances.
- Unit tests for all three listeners and the new gateway helper.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:28:40 +07:00
Ho Ngoc Hai
729afe2db6 feat(ai-services): dedicated GET /avm/v2/feature-importance endpoint (TEC-2760)
Exposes ensemble feature importance as a standalone endpoint per R5.1 spec.
Aggregates XGBoost (0.4) + LightGBM (0.35) + CatBoost (0.25) gain when trained
boosters are loaded; falls back to the curated heuristic ranking otherwise, so
callers can depend on the endpoint during scaffold/heuristic-only runs.

- Factored heuristic drivers into a shared constant (_HEURISTIC_DRIVERS)
- Added AVMv2FeatureImportanceResponse model (model_version + source + drivers)
- Added service.get_feature_importance() public method
- Added tests/test_avm_v2.py::test_feature_importance_heuristic (24 total pass)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:27:30 +07:00
Ho Ngoc Hai
5731577fa9 feat(listings): R2.3 featured listings entitlement + admin promote + search filter (TEC-2754)
- Add Plan.featuredListingsQuota (Int?) with per-tier seed (FREE=0, AGENT_PRO=5, INVESTOR=10, ENTERPRISE unlimited) and migration 20260418000000_add_featured_listings_quota
- Wire featured_listings_promoted metric into CheckQuotaHandler METRIC_TO_PLAN_FIELD so QuotaGuard honors the new quota
- Add PromoteFeaturedListingCommand + handler (entitlement-based, no payment): verifies ownership/agent, checks quota, extends featuredUntil, meters usage
- Add POST /listings/:id/promote endpoint gated by @RequireQuota('featured_listings_promoted') + QuotaGuard
- Add AdminFeatureListingCommand + handler with LISTING_FEATURED / LISTING_UNFEATURED audit log entries (new AdminAction enum values) and transactional write
- Add POST /admin/moderation/listings/:id/feature endpoint (ADMIN-only) with reason + duration
- Expose featured?: boolean filter on SearchPropertiesDto -> isFeatured:=1|0 Typesense filter in SearchPropertiesHandler
- Unit tests: 8 for PromoteFeaturedListingHandler, 6 for AdminFeatureListingHandler, 3 for search featured filter

Keeps existing pay-per-feature FeatureListingHandler intact for backward compatibility.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:18:04 +07:00
Ho Ngoc Hai
580eb2a261 feat(web): residential_projects feature flag for /du-an routes (TEC-2757)
- Add useResidentialProjectsFlag hook with NEXT_PUBLIC_FEATURE_RESIDENTIAL_PROJECTS env + URL/localStorage override (mirrors AVM v2 pattern)
- Gate /du-an index (client) and /du-an/[slug] detail (server) routes via notFound() when flag disabled
- Add component tests for index page including disabled-flag notFound branch

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:13:06 +07:00
Ho Ngoc Hai
2c1e3771e9 feat(analytics): add Python NeighborhoodScore service + NestJS HTTP proxy (TEC-2756)
- libs/ai-services: new POST /neighborhood/score router computing weighted
  6-axis livability score from per-category POI counts; algorithm versioned
  for future iteration (sigmoid curves, percentile thresholds).
- apps/api: HttpNeighborhoodScoreService proxies to Python first, falls back
  to PrismaNeighborhoodScoreService when AI service unavailable. Mirrors the
  HttpAVMService pattern. Existing GET /analytics/neighborhoods/:district/score
  endpoint and CQRS handler now flow through the proxy.
- AnalyticsModule binds Http variant by default, retains Prisma variant as
  injectable fallback.
- Tests: 5 pytest cases for Python heuristic, 4 vitest cases for HTTP proxy
  fallback behaviour.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:07:02 +07:00
Ho Ngoc Hai
329a821b4a feat(notifications): production-ready WebSocket gateway (TEC-2766)
- Add RedisIoAdapter (shared/infra) for multi-instance Socket.IO fan-out
  with graceful fallback to the in-memory IoAdapter when Redis is
  unreachable.
- Pin Socket.IO heartbeat (pingInterval/pingTimeout/connectTimeout)
  via env-tunable gateway options for reconnect stability.
- Expose Prometheus metrics on /notifications: goodgo_ws_connected_clients
  (Gauge) and goodgo_ws_messages_total (Counter) with namespace/event/
  direction labels. Wired through MetricsService and tracked across
  connect/disconnect + emits.
- Unit tests: RedisIoAdapter connect/fallback/close, new MetricsService
  WS helpers, and gateway metric increments/decrements on auth paths.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:06:25 +07:00
Ho Ngoc Hai
5d4ecdeb2f feat(web): AVM v2 upgraded valuation dashboard (TEC-2763)
R5.4 ships the upgraded AVM UI behind the `avm_v2` A/B flag. When the
flag is on, the dashboard exposes:

- Tab switch between single valuation and multi-property compare
- Waterfall drivers chart (ValueDriversChart) alongside the existing
  horizontal bar breakdown
- Mapbox comparables map with similarity-coloured markers and an
  optional highlighted subject pin
- Confidence interval + range bar and PDF export remain available
- Valuation history chart surface unchanged (still lazy-loaded)

Flag plumbing (useAvmV2Flag):
- NEXT_PUBLIC_FEATURE_AVM_V2=1 enables by default
- `?avm_v2=1|0` URL param forces + persists to localStorage
- safe localStorage handling (no throw when storage is blocked)

Tests: comparables-map, value-drivers-chart, use-avm-v2-flag specs
added. Pre-existing "Yếu tố chính" assertion in valuation-results.spec
updated to match the current copy ("Yếu tố ảnh hưởng giá") so the
valuation suite is green (7 files, 52 tests).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:05:46 +07:00
Ho Ngoc Hai
e18390ead9 feat(auth): add phoneNumber to profile update with SMS OTP re-verify
TEC-2722 — PATCH /api/v1/auth/profile now accepts phoneNumber alongside
fullName, avatarUrl, and email. Phone changes are deferred until the user
confirms the SMS OTP via POST /api/v1/auth/profile/verify-phone, mirroring
the existing email-change OTP flow.

- Add PhoneChangeRequestedEvent + user.phone_change_otp SMS template
- Add VerifyPhoneChangeHandler with Redis-backed 10-minute OTP
- Re-check phone uniqueness at verify time to catch races
- Extend unit tests for UpdateProfileHandler + add VerifyPhoneChangeHandler spec

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 00:17:12 +07:00
Ho Ngoc Hai
78e46a024b feat(web): enhance KYC upload with validation, previews, test ids
- Add file type (JPG/PNG/WEBP/PDF) and 5MB size validation
- Show image previews with cleanup of object URLs
- Add data-testid attributes on inputs, buttons, previews, alerts for E2E
- Improve error messaging for expired/failed presigned uploads (403 vs other)
- Guard step 2->3 advance when front image missing

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 00:06:13 +07:00
Ho Ngoc Hai
b21f197c09 feat(notifications): add Zalo OA webhook controller + WebSocket gateway tests
- Add ZaloOaWebhookController: GET verification endpoint, POST event handler
  for follow/unfollow/user_send_text events with user linking via OAuthAccount
- Register webhook controller in NotificationsModule
- Add 13 unit tests for webhook (challenge verify, follow/unfollow/message
  handling, linked/unlinked users, error resilience)
- Add 18 unit tests for NotificationsGateway (JWT auth, multi-device tracking,
  disconnect cleanup, notification.sent event, Redis cache, unread count)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 18:31:02 +07:00
Ho Ngoc Hai
8e9d021465 feat: add unit tests for featured listings, neighborhood scores + price history chart
- Add unit tests for FeatureListingHandler (6 tests) and ActivateFeaturedListingHandler (6 tests)
- Add unit tests for NeighborhoodScoreServiceImpl (5 tests) and GetNeighborhoodScoreHandler (2 tests)
- Add PriceHistoryChart component with recharts LineChart for listing detail page
- Wire up price history API client and integrate chart into listing detail view

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 18:21:44 +07:00
Ho Ngoc Hai
0dda2bffdb feat(api): add POST /avm/industrial endpoint for industrial rent estimation
Wire NestJS controller to Python AI service's industrial AVM. Adds CQRS
query/handler, Swagger-annotated DTOs, AI client method, and 7 unit tests
covering parameter mapping, response camelCase conversion, and error handling.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 18:01:23 +07:00
Ho Ngoc Hai
9eaec46a37 feat(ai-services): AVM v2 residential — expanded features, training pipeline, model versioning
Add neighborhood_score, developer_reputation, floor_level, direction premiums
to the multi-model ensemble. Implement real Optuna-based training pipeline
for XGBoost/LightGBM/CatBoost with grouped train/val/test splits. Add
file-based model registry with rollback and list-versions endpoints.
23 Python tests covering all new features.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:55:03 +07:00
Ho Ngoc Hai
6cf2c23170 feat(listings): add source field to PriceHistory + unit tests
- Add `source` column to PriceHistory Prisma model (manual_update, admin_override, market_adjustment)
- Add migration for the new column with default 'manual_update'
- Update ListingPriceChangedEvent domain event with optional source parameter
- Update RecordPriceHistoryHandler to persist source
- Update GetPriceHistoryHandler to return source in query results
- Add unit tests for RecordPriceHistoryHandler (5 cases)
- Add unit tests for GetPriceHistoryHandler (3 cases)
- Add ListingPriceChangedEvent tests to domain events spec (4 cases)
- Add getPriceHistory controller tests (2 cases)

All 1805 tests pass, typecheck clean.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:43:48 +07:00
Ho Ngoc Hai
f3a2a012c4 feat(web): add price range filter and list view to /du-an page
Add minPrice/maxPrice inputs to ProjectFilterBar and introduce a
list view mode alongside the existing grid/map toggle for project
browsing.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:40:30 +07:00
Ho Ngoc Hai
a6e53e3d06 feat(ai-services): add AVM v2 A/B comparison endpoint and tests
Add POST /avm/v2/compare-v1 endpoint that runs both v1 (single-model)
and v2 (ensemble) AVM predictions on the same property and returns a
side-by-side comparison with price diff, confidence delta, and a
recommendation on which model to prefer.

- ABComparisonRequest/Response schemas in avm_v2 models
- compare_v1() method in AVMv2EnsembleService
- 4 new integration tests for the comparison endpoint
- All 47 Python tests pass

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:35:30 +07:00
Ho Ngoc Hai
74804757c5 test(analytics): add unit tests for AVM batch, history, comparison endpoints
Add comprehensive test coverage for the three AVM API upgrade endpoints:
- BatchValuationHandler: batch results, partial failures, error handling
- ValuationHistoryHandler: history retrieval, limit, empty state, errors
- ValuationComparisonHandler: multi-property compare, summary, edge cases
- AnalyticsController: route-level tests for all new endpoints

Fix async error handling in handlers by adding await to cache.getOrSet
calls so try/catch blocks properly catch rejections.

Fix pre-existing web test failures: add missing FLOOD_RISK_OPTIONS and
QUALITY_LABELS to valuation-form mock, update valuation-results assertions
to match current component rendering.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:28:38 +07:00
Ho Ngoc Hai
ac4191cdf0 test(reports): add E2E pipeline integration tests for report generation
26 tests covering: full pipeline flow for 3 report types + generic fallback,
status polling (GENERATING → READY/FAILED transitions), quota enforcement and
user scoping, error handling (PDF failure, AI failure, auth checks), delete
cleanup flow, and temp file lifecycle.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:24:52 +07:00
Ho Ngoc Hai
8f2d325d60 feat(industrial): add IndustrialListing CRUD endpoints + Typesense indexing
Wire full DDD stack for IndustrialListing: domain entity, repository interface,
CQRS commands/queries with handlers, Prisma repository, Typesense sync on
create/update/delete, controller with 5 REST endpoints, and validated DTOs.
Register all providers in IndustrialModule.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:08:08 +07:00
Ho Ngoc Hai
13bd76ac5d feat(ai-services): add building_coverage, loading_docks, zoning to industrial AVM
Completes the industrial-specific feature set required for AVM industrial
valuation. Adds heuristic adjustments for all three new features and
4 new tests covering zoning premiums, loading docks, and coverage ratio.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:06:27 +07:00
Ho Ngoc Hai
8592fb436c feat(web): integrate neighborhood radar chart into listing detail page
Add NeighborhoodRadarChart to listing detail view, fetching scores
from the analytics API based on the listing's district and city.
Displays a 6-axis radar chart (education, healthcare, transport,
shopping, environment, safety) with overall score and color-coded
badges.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:05:26 +07:00
Ho Ngoc Hai
24a2fd1369 fix(web,prisma): fix TypeScript errors in transfer wizard and schema
- Fix Zod v4 enum API: replace deprecated `required_error` with `error`
- Create missing TransferWizardClient component (4-step wizard: category, items, AI estimate, submit)
- Add CANCELLED status to TransferListingStatus enum for soft-delete support

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 17:02:20 +07:00
Ho Ngoc Hai
a7bcc807ad feat(transfer): add DELETE endpoint, domain events, and event-driven Typesense sync
- DeleteTransferListingCommand/Handler with seller authorization and soft delete (→ CANCELLED)
- Domain events: TransferListingCreated/Updated/DeletedEvent with EventEmitter2
- Event handler: TransferListingTypesenseHandler syncs Typesense on all CUD operations
- Create/Update handlers now emit domain events after persistence
- DELETE /transfer/listings/:id controller endpoint with JWT auth

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 15:27:57 +07:00
Ho Ngoc Hai
ca41f7e604 feat(transfer): add Claude Vision condition assessment for transfer pricing
Add POST /transfer/estimate-from-photos endpoint that uses Claude Vision API
to assess furniture/appliance condition from photos, integrating with the
existing rule-based pricing engine. Includes rate limiting (5/min), image hash
caching, graceful fallback, and 17 unit tests covering all paths.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 14:41:32 +07:00
Ho Ngoc Hai
b22543d59e feat(seed): add MacroeconomicData and InfrastructureProject seed data
Add seed-macro-infra.ts with 144 macroeconomic data points (HCMC + Hanoi,
6 indicators, quarterly 2023-2025) and 15 infrastructure projects with
PostGIS coordinates (Metro Line 1, Thu Duc Innovation District, Ring Road 3,
Long Thanh Airport, Can Gio Bridge, etc.). Integrated into main seed pipeline.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 14:18:41 +07:00
Ho Ngoc Hai
57db3fe388 test(auth): add unit tests for KYC presigned upload and submit handlers
Cover GenerateKycUploadUrlsHandler (10 tests) and SubmitKycHandler (10 tests):
presigned URL flow, legacy file upload, status validation, error handling.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 13:19:44 +07:00
Ho Ngoc Hai
5810f0be56 feat(web): add industrial compare page, listing search, and Mapbox park map
- Add interactive Mapbox map to /khu-cong-nghiep landing page with park markers and popups
- Build compare page at /khu-cong-nghiep/so-sanh with recharts RadarChart and detailed comparison table
- Build listing search page at /khu-cong-nghiep/cho-thue with filters for property type, lease type, area, and price
- Add IndustrialListing types, API client functions, and React Query hooks

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 12:40:35 +07:00
Ho Ngoc Hai
28cdd92846 test(listings): add updateListing controller tests for PATCH /api/v1/listings/:id
Cover the updateListing controller method: basic command dispatch and
full-field update with re-moderation flag.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 11:41:29 +07:00
Ho Ngoc Hai
44533a88f4 fix(web): wire up inquiry modal toast notification on listing detail page
The "Nhắn tin" button's inquiry modal now shows a success toast via
sonner after submission instead of an in-dialog success state, and
closes the modal automatically. Added sonner as a dependency and
mounted <Toaster> in the root locale layout.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 10:56:56 +07:00
Ho Ngoc Hai
25f415f3bc test(reports): add unit tests for report handlers and domain entity
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 21s
CI / E2E Tests (push) Has been skipped
Deploy / Build API Image (push) Failing after 3m40s
Deploy / Build Web Image (push) Failing after 15s
Deploy / Build AI Services Image (push) Failing after 16s
E2E Tests / Playwright E2E (push) Failing after 2m3s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 23m49s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 16s
Security Scanning / Trivy Scan — API Image (push) Failing after 1m24s
Security Scanning / Trivy Scan — Web Image (push) Failing after 34s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 22s
Security Scanning / Trivy Filesystem Scan (push) Failing after 18s
Security Scanning / Security Gate (push) Failing after 1s
Add tests for GenerateReport, GetReport, DeleteReport command/query
handlers and Report entity domain logic.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 09:18:32 +07:00
Ho Ngoc Hai
3a9325719a refactor(reports): consolidate duplicate PDF services into single implementations
Remove duplicate minio-pdf-storage and puppeteer-pdf services, keeping
the consolidated versions in pdf-generator.service.ts and pdf-storage.service.ts.
Update reports module imports to use the correct classes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 09:18:19 +07:00
Ho Ngoc Hai
430c67f244 feat(listings): add featured boost to search and expose isFeatured in API responses
Featured listings now sort first in search results via featuredUntil desc ordering.
All listing read DTOs (detail, search, seller) include isFeatured boolean and featuredUntil timestamp.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 09:16:44 +07:00
Ho Ngoc Hai
deb04989de feat(api): add industrial, transfer, and reports backend modules
Add three new NestJS modules following DDD/CQRS architecture:
- Industrial: KCN (industrial park) management with PostGIS geo queries, Typesense search, and market statistics
- Transfer: Furniture/premises transfer listings with AI-powered price estimation and depreciation modeling
- Reports: Async AI report generation via BullMQ with Claude narrative service, PDF generation, and macro data integration

Includes Prisma schema models, migrations, seed scripts, and app.module wiring with BullMQ Redis config.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 09:11:16 +07:00
Ho Ngoc Hai
7ce651fce5 feat(web): add khu-cong-nghiep, chuyen-nhuong, and reports pages
Add three new frontend page sections:
- Industrial parks (khu-cong-nghiep): listing, detail, filter bar
- Transfer listings (chuyen-nhuong): search, category tabs, detail
- AI reports dashboard: list, create, viewer with TOC

Includes components, API clients, hooks, server helpers, i18n keys,
navigation links in public and dashboard layouts, and lint fixes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 09:07:45 +07:00
Ho Ngoc Hai
62a8842193 feat(listings): complete PATCH /api/v1/listings/:id endpoint
- Add mediaOrder field to UpdateListingDto, Command, and Handler for
  reordering media items
- Add updateMediaOrder method to IPropertyRepository and Prisma impl
- Fix PrismaPropertyRepository.update() to persist amenities, nearbyPOIs,
  floors, floor, totalFloors, and metroDistanceM columns
- Add unit tests for media order updates in handler spec
- Add DTO validation tests for mediaOrder with nested validation
- Add e2e integration tests covering content updates, auth, ownership
  guard, and forbidden field rejection

Existing guards enforced:
- Only seller or assigned agent can update (403 for others)
- ACTIVE listings transition to PENDING_REVIEW on edit
- propertyType, address, location blocked via DTO whitelist

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 06:10:27 +07:00
Ho Ngoc Hai
a48abf23b5 fix(web): add Vietnamese diacritics to inquiry modal text
The InquiryModal had all Vietnamese text written without diacritics
(e.g., "Vui long" instead of "Vui lòng"), which looks unprofessional
on a Vietnamese real estate platform. Fixed all 12 text strings.

The onClick handler, modal form, API integration (POST /api/v1/inquiries),
phone pre-fill, and success state were already correctly implemented.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 06:06:16 +07:00
Ho Ngoc Hai
a3f0c731fe fix(docs): update remaining Next.js 14 references to Next.js 15
The .md files (CLAUDE.md, architecture docs) already referenced Next.js 15
correctly. Fixed the two remaining .txt audit files that still said Next.js 14.
libs/ai-services and libs/mcp-servers were already documented in CLAUDE.md
and both had comprehensive READMEs.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 06:05:47 +07:00
Ho Ngoc Hai
3b5da2dcf9 feat(messaging): add in-app messaging module with Conversation + Message models
Implements buyer-agent in-app messaging (Task 8.4):
- Prisma models: Conversation, ConversationParticipant, Message
- Full DDD module: domain entities, repository interfaces, CQRS commands/queries
- REST API: POST/GET conversations, POST/GET messages, PATCH read, DELETE messages
- WebSocket gateway (/messaging namespace): real-time message delivery, typing indicators, room-based routing
- 46 unit tests covering handlers, repositories, controller, and gateway

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:36:04 +07:00
Ho Ngoc Hai
30d3039b94 feat(analytics): add NeighborhoodScoreService with POI-based scoring and API endpoint
- Create INeighborhoodScoreService interface and implementation
- Score districts 0-100 across 6 categories: education, healthcare, transport, shopping, greenery, safety
- Calculate scores from POI data with configurable weights and max counts
- Add GetNeighborhoodScoreQuery handler with lazy calculation
- Add GET /analytics/neighborhoods/:district/score endpoint
- Wire service and handler into AnalyticsModule

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:21:28 +07:00
Ho Ngoc Hai
5db3dfbda6 fix(lint): final import-type fixes in listings barrel and search result mapper
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:17:54 +07:00
Ho Ngoc Hai
e78d706b42 chore: update infrastructure configs, audit docs, and env template
- Update Docker Compose configs for Redis, Typesense, and MinIO services
- Update GitHub Actions deploy workflow with improved caching and steps
- Extend .env.example with Stringee, Zalo OA, and FCM config keys
- Update audit documentation with latest findings and recommendations
- Update CHANGELOG and README with recent feature additions

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:17:38 +07:00
Ho Ngoc Hai
53c33a1c50 feat(mcp): add industrial parks and reports MCP tool servers
Add IndustrialParkServer for KCN/KCX search and analytics, and
ReportsServer for market report generation. Include unit tests
for industrial parks server.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:16:11 +07:00
Ho Ngoc Hai
2a69736728 feat(web): add social share component and wire price history into listing detail
- Add SocialShare component with copy-link, Facebook, Zalo, and QR code sharing
- Integrate price history chart and social sharing into listing detail page
- Register new price history and feature-listing handlers in ListingsModule

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:15:43 +07:00
Ho Ngoc Hai
d4e100a00c feat(api): add price history, Stringee SMS, Zalo OA, WebSocket notifications, and feature-listing command
- Add PriceHistory model + migration, price-changed domain event, and event handler
- Add GetPriceHistory query handler and controller endpoint
- Implement StringeeSmsService and ZaloOaService with unit tests
- Add Zalo ZNS templates for Vietnamese notification messages
- Add WebSocket notification gateway for real-time push
- Add FeatureListingCommand for promoted listings
- Apply remaining consistent-type-imports lint fixes across API modules

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:15:04 +07:00
Ho Ngoc Hai
c920934fb6 fix(lint): enforce consistent-type-imports and fix import ordering across codebase
Auto-fix 862 lint errors: convert value imports used only as types to
`import type`, fix import group ordering in seed.ts and du-an-api.ts,
remove unused imports in auth controller, and clean up stale eslint-disable
comments referencing non-existent rules.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:13:56 +07:00
Ho Ngoc Hai
86adcf7295 feat(listings): add update endpoint, QR code generation, and presigned upload helpers
Wire up PATCH /listings/:id with UpdateListingCommand/Handler, add QR code
image endpoint, extend IMediaStorageService with generatePresignedUpload and
getPublicUrl, and include UpdateListingDto unit tests.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:12:25 +07:00
Ho Ngoc Hai
e21e096e54 feat(web): complete du-an project pages, neighborhood components, and public notification bell
- Add grid/map view toggle on /du-an listing page with Mapbox project markers
- Enhance du-an detail with master plan viewer, neighborhood radar chart, POI map, and price history chart
- Create neighborhood component suite: radar chart (Recharts), POI map (Mapbox), score badges
- Add du-an API client, server-side fetching, and React Query hooks
- Wire NotificationBell into public layout header for authenticated users
- Fix missing PROJECT_STATUS_COLORS import in du-an detail client

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:11:21 +07:00
Ho Ngoc Hai
8da488711b feat(analytics): AVM v2 batch valuation, comparison, history + frontend upgrade
Add batch valuation (POST /analytics/valuation/batch, max 50 properties),
valuation comparison (POST /analytics/valuation/compare, 2-5 properties),
and history endpoint (GET /analytics/valuation/history/:propertyId) with
confidence explanation helper. Frontend: enhanced valuation form with project
autocomplete and deep analysis toggle, results with confidence badges and
price range visualization, comparables table, history chart, market context
card, and PDF export.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 05:08:05 +07:00
Ho Ngoc Hai
93a390efb9 fix(payments): add missing barrel exports for ConfirmBankTransfer command and DTO
The ConfirmBankTransfer command, handler, result type, and DTO were implemented
but not exported from their respective index files, making them inaccessible
to consumers importing from the barrel.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-16 04:30:46 +07:00