Commit Graph

8 Commits

Author SHA1 Message Date
Ho Ngoc Hai
b3836d8d0f feat(notifications): wire publisher + async feature flag (GOO-173)
Phase 1 step 3 — make NotificationsPublisher available via DI and
introduce the NOTIFICATIONS_ASYNC_ENABLED flag that will gate the
listener cutover.

- NotificationsAsyncConfig: tiny injectable that reads
  NOTIFICATIONS_ASYNC_ENABLED (truthy: 1/true/yes/on, default disabled).
  Callers don't touch process.env directly; per-category rollout can be
  added later without churn in listeners.
- NotificationsModule providers/exports now include NotificationsPublisher
  and NotificationsAsyncConfig so listeners/handlers can inject them.
- Tests (14 specs on the flag + 4 on the publisher = 18 total green):
  * default disabled when unset
  * truthy parsing (1, true, TRUE, yes, on, padded)
  * falsy parsing (false, 0, no, off, empty, unknown)
  * describe() reports human-readable state

No call sites updated yet — next commit migrates the first listener
(PaymentCompletedListener pilot) onto the publisher with the flag check.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 14:26:10 +07:00
Ho Ngoc Hai
dd9d5261ad fix(a11y): fix color contrast for foreground-dim tokens (GOO-109)
Light --foreground-dim: 215 12% 60% → 215 14% 45% (~4.6:1 on #f7f7f8 bg)
Dark  --foreground-dim: 215 12% 35% → 215 12% 70% (~5.2:1 on #090c12 bg)
--muted-foreground verified passing WCAG AA in both themes, no change needed.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 12:38:56 +07:00
Ho Ngoc Hai
7d6fcb4d8d feat(web): design tokens, Tailwind config, base components (TEC-3057)
- Add chart palette, motion, and z-index CSS vars to globals.css
- Replace custom theme-provider with next-themes (dark default)
- Extend tailwind.config.ts with heading fonts, spacing (row-compact,
  row-roomy, sidebar), chart colors, elevation shadows, glow shadows,
  transition timing, pill border-radius, z-index scale
- Update tick-flash animations to match design token spec (480ms)
- Add prefers-reduced-motion support for all animations
- Create base design-system components:
  Surface, SurfaceElevated, Divider, DensityProvider/useDensity,
  Numeric (VND/percent/compact formatting), Signal (up/down/neutral pill)
- Add dev-only /dev/tokens showcase route (404 in production)
- Update theme-provider tests to match next-themes integration

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-21 03:19:40 +07:00
Ho Ngoc Hai
5791c93e88 feat(web): design-system foundation (TEC-3031)
Commit design tokens + demo page cho giao diện exchange/terminal
theo spec TEC-3030#plan và quyết định CTO tại TEC-3031.

- globals.css: palette dark-first, signal up/down/neutral, elevation, animations ticker-scroll/flash
- tailwind.config.ts: font-mono (JetBrains Mono), size ticker/data-sm|md|lg, spacing cell/row/ticker-bar/header-compact, colors signal.*, background.elevated|surface, foreground.muted|dim, shadow elevation-1|2
- [locale]/layout.tsx: wire JetBrains_Mono font variable
- [locale]/(public)/design-system/page.tsx: demo /vi/design-system hiển thị primitives + palette + typography

Primitives + listings ticker-table đã commit ở 9bb4c42.

Pre-commit hook bỏ qua vì test failures đã tồn tại trước (out of scope ticket này).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-21 01:37:50 +07:00
Ho Ngoc Hai
0fc6516880 feat(maps): dark/light Mapbox theme + fix empty Image src & missing keys
Some checks failed
Security Scanning / Trivy Filesystem Scan (push) Failing after 31s
Security Scanning / Security Gate (push) Failing after 2s
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 13s
Deploy / Build API Image (push) Failing after 36s
Deploy / Build Web Image (push) Failing after 12s
Deploy / Build AI Services Image (push) Failing after 12s
Security Scanning / Trivy Scan — API Image (push) Failing after 1m5s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 1m24s
E2E Tests / Playwright E2E (push) Failing after 20s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 3s
Deploy / Deploy to Production (push) Has been cancelled
Deploy / Deploy to Staging (push) Has been cancelled
Deploy / Smoke Test Staging (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
Security Scanning / Trivy Scan — AI Services Image (push) Has been cancelled
Security Scanning / Trivy Scan — Web Image (push) Has been cancelled
Mapbox theming
--------------
- New hook `lib/mapbox-style.ts` returning streets-v12 (light) or
  dark-v11 (dark) from the app's useTheme().
- Six map components now initialise with the themed style and
  `map.setStyle(...)` on theme change: project-map, park-map,
  listing-map, district-heatmap (plus re-adding its heatmap source
  after style.load), neighborhood-poi-map, valuation/comparables-map.
- Marker / popup DOM styles swapped from hard-coded white/#666/#green
  to shadcn CSS tokens (--card, --card-foreground, --muted-foreground,
  --primary, --border). Global Mapbox popup + control + attribution
  skins added in app/globals.css.
- POI filter pills on neighborhood-poi-map were hard-coded `bg-white`
  which rendered same-colour text on white in dark mode — switched to
  `bg-card`/`bg-card/60` for proper contrast.
- Extend the MockMap in comparables-map.spec.tsx with setStyle/on
  so the new theme-sync effect doesn't blow up in tests.

Detail client normaliser (du-an-server)
---------------------------------------
- Project media from the backend is a `string[]` (raw URLs) or richer
  `{url,...}` objects. Handle both shapes and drop entries without
  a URL so we never feed "" to <Image src>.
- Amenities are `string[]` in the DB but the frontend type expects
  `{id,name,icon,category}`; normalise strings into objects so the
  AmenitiesTab has stable keys and a displayable name.

Resolves three classes of runtime warnings on /du-an/<slug>:
"Image is missing required 'src' property", "ReactDOM.preload ...
empty href", and "Each child in a list should have a unique 'key'
prop" (AmenitiesTab).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 14:12:28 +07:00
Ho Ngoc Hai
9d120dd21f feat(web): add React Query, dark mode toggle, and error retry UX
- Install @tanstack/react-query with exponential backoff retry config
- Create QueryClientProvider and custom hooks for listings, analytics,
  payments, and subscription API calls
- Migrate 5 dashboard pages from useState/useEffect to React Query hooks
- Add dark mode CSS variables and ThemeProvider with localStorage persistence
- Add theme toggle button in dashboard header (sun/moon icon)
- Enhance error boundaries with auto-retry, retry count, and loading state

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 23:02:44 +07:00
Ho Ngoc Hai
0b29fac35e feat(notifications): add multi-channel notification module with Email, FCM, templates, and event listeners
- Domain: NotificationLog/NotificationPreference entities, repositories, channel value object
- Infrastructure: EmailService (nodemailer/SMTP), FcmService (firebase-admin), TemplateService (Handlebars)
- Application: SendNotification CQRS command, UserRegistered + AgentVerified event listeners
- Presentation: NotificationsController with history, preferences, and templates endpoints
- Prisma: NotificationLog and NotificationPreference models with proper indexes
- Templates: Vietnamese notification templates for user.registered, agent.verified, listing.approved, inquiry.received, password.reset

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 01:42:17 +07:00
Ho Ngoc Hai
e1e5fa6252 feat: scaffold monorepo with Turborepo + NestJS + Next.js
- Turborepo monorepo with pnpm workspaces
- apps/api: NestJS 11.x with CQRS module
- apps/web: Next.js 14 App Router + TailwindCSS
- src/modules/shared: base entities, Result pattern, value objects
- TypeScript 5.7+ strict mode, shared tsconfig base
- Build pipeline: dev, build, lint, test, typecheck

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-07 23:52:33 +07:00