Several fixes discovered while smoke-testing the homepage under the new
port layout (web 3200 / api 3201) to avoid clashing with a sibling project:
- analytics-api: add `unwrap<T>()` helper for the `{ data, cacheMeta }`
envelope the backend CacheMetaInterceptor appends to every
`/analytics/*` response. Apply to all 9 analytics methods. Without this
`data.activeCount` (etc.) were `undefined`, crashing KpiStrip with
`TypeError: Cannot read properties of undefined (reading 'toLocaleString')`.
- public page: hard-coded `city = 'Ho Chi Minh'` returned 0 rows because
the DB stores `'Hồ Chí Minh'` and the SQL filter is case-insensitive but
not diacritic-insensitive. Use the accented spelling.
- use-analytics hooks: add `useAuthedAnalytics()` gate so unauthenticated
visitors on public routes no longer fire 401s from analytics queries.
- next.config.js CSP: add localhost:3200/3201 (http + ws) to connect-src so
the web origin can reach the relocated API. Without this fetches hit
`TypeError: Failed to fetch` on login.
- .claude/launch.json + package.json: web → 3200, api → 3201 (was 3000/3001,
conflicting with the sibling psyforge project also using 3000).
- Minor follow-ups from parallel QA work on this branch (analytics modules,
notifications gateway, auth test fixtures, trending-areas handler + DTO
+ tests, a few E2E smoke specs).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
57 lines
1.5 KiB
JSON
57 lines
1.5 KiB
JSON
{
|
|
"name": "@goodgo/web",
|
|
"version": "0.0.1",
|
|
"private": true,
|
|
"scripts": {
|
|
"dev": "next dev --port 3200",
|
|
"build": "next build",
|
|
"start": "next start",
|
|
"lint": "eslint src/ app/ components/ lib/ hooks/ i18n/ --no-error-on-unmatched-pattern",
|
|
"test": "vitest run",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"@hookform/resolvers": "^5.2.2",
|
|
"@sentry/nextjs": "^10.47.0",
|
|
"@tanstack/react-query": "^5.96.2",
|
|
"@tanstack/react-table": "^8.21.3",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"html2canvas": "^1.4.1",
|
|
"jspdf": "^4.2.1",
|
|
"lucide-react": "^1.7.0",
|
|
"mapbox-gl": "^3.21.0",
|
|
"next": "^15.5.14",
|
|
"next-intl": "^4.9.0",
|
|
"next-themes": "^0.4.6",
|
|
"react": "^18.3.0",
|
|
"react-dom": "^18.3.0",
|
|
"react-hook-form": "^7.72.1",
|
|
"recharts": "^3.8.1",
|
|
"socket.io-client": "^4.8.3",
|
|
"sonner": "^2.0.7",
|
|
"tailwind-merge": "^3.5.0",
|
|
"web-vitals": "^5.2.0",
|
|
"zod": "^4.3.6",
|
|
"zustand": "^5.0.12"
|
|
},
|
|
"devDependencies": {
|
|
"@testing-library/jest-dom": "^6.9.1",
|
|
"@testing-library/react": "^16.3.2",
|
|
"@testing-library/user-event": "^14.6.1",
|
|
"@types/mapbox-gl": "^3.5.0",
|
|
"@types/node": "^25.5.2",
|
|
"@types/react": "^18.3.0",
|
|
"@types/react-dom": "^18.3.0",
|
|
"@vitejs/plugin-react": "^4.7.0",
|
|
"autoprefixer": "^10.4.0",
|
|
"jsdom": "^29.0.2",
|
|
"msw": "^2.13.2",
|
|
"postcss": "^8.4.0",
|
|
"tailwindcss": "^3.4.0",
|
|
"tailwindcss-animate": "^1.0.7",
|
|
"typescript": "^6.0.2",
|
|
"vitest": "^4.1.3"
|
|
}
|
|
}
|