gendesign/.design-sync/NOTES.md
bot-backend e70f5da82b
All checks were successful
CI / changes (pull_request) Successful in 7s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
chore(design-sync): sync inputs for claude.ai/design trade-in DS
Imports tradein-mvp/frontend (38 components) to a claude.ai/design
design-system project. Synth-entry build (Next.js app, no dist):
- overrides/source-kit.mjs: process.env shim for browser IIFE
- preview-provider.tsx: seeded TanStack Query provider (mirrors the
  repo's offline ui-preview client) so fetch-coupled + auth-gated cards render
- previews/*.tsx: authored preview compositions (real fixture data)
- conventions.md: README header for the design agent
- config.json + NOTES.md: reproducible re-sync inputs
2026-06-27 14:40:50 +03:00

5 KiB

design-sync NOTES — tradein-mvp-frontend

Target: tradein-mvp/frontend (NOT the repo-root frontend/, which is the Site-Finder app). Project: gendesign-tradein.

Build gotchas

  • No dist / no Storybook → synth-entry mode. The package is a Next.js app, not a lib; package.json has no main/module/exports.
  • --entry must point at a NON-existent dist path (tradein-mvp/frontend/dist/index.js). Two jobs:
    1. PKG_DIR resolution walks up dirname(--entry) to the real named package.json → PKG_DIR=tradein-mvp/frontend (without --entry, PKG_DIR defaults to node_modules/<pkg> which doesn't self-install → ENOENT crash).
    2. The path being absent makes resolveDistEntry(soft) return null → synthEntry=truederiveComponentsFromSrc discovers components from src/. A path that EXISTS (e.g. package.json) suppresses synth mode → [ZERO_MATCH] tokens-only.
  • cfg.* path fields are PACKAGE-relative (relative to PKG_DIR), not repo-relative. srcDir=src, cssEntry=src/components/trade-in/trade-in.css, tokensGlob=src/app/globals.css.
  • --node-modules tradein-mvp/frontend/node_modules (react + @types/react live there).

Styling

  • Tokens in src/app/globals.css (:root{--bg-app,--accent,…}); component CSS in src/components/trade-in/trade-in.css (2277 lines). Manrope via remote Google Fonts @import (→ [FONT_REMOTE], no action).

Re-sync risks

  • Synth scan over-includes non-component PascalCase exports (51 found vs ~37 files) — prune with componentSrcMap: {Name: null} as identified.
  • Components are app-coupled (next/*, TanStack Query, data hooks); many need providers/mock props to render → expect floor cards / authored previews with composed props.

Authoring (38 components, all authored-good)

  • Import contract: preview imports {X} from 'tradein-mvp-frontend' (mapped to window.TradeInUI bundle) + data from ./_fixtures (re-exports the repo's offline app/ui-preview/estimate/fixture.ts). Type imports erased.
  • Provider = seeded PreviewProvider (.design-sync/preview-provider.tsx, wired via cfg.extraEntries + cfg.provider). Mirrors app/ui-preview/estimate/page.tsx's seeded QueryClient: pre-fills ["auth","me"] (fake admin user) + the estimate sub-queries (placement-history, house-analytics, sell-time-sensitivity, cian-price-changes=[], sales-vs-listings). This is what makes fetch-coupled cards (StreetDealsCard, HouseAnalyticsSection, PlacementHistoryCard) and auth-gated ones (RouteGuard, UserMenu) render offline.
    • CRITICAL: an extraEntries module must NOT import anything that reads process.env at module top-level (e.g. @/lib/useMe@/lib/api) — extraEntries evaluate BEFORE the synth-entry .pkg-shim.mjs, so process is undefined and the whole IIFE aborts (38/38 vanish from the global). The provider hardcodes ME_QUERY_KEY = ["auth","me"] instead of importing useMe.
    • extraEntries path is PACKAGE-relative: ../../.design-sync/preview-provider.tsx. Its @/ aliases don't resolve from outside the tsconfig root → use relative ../tradein-mvp/frontend/src/... for repo imports inside it.
  • Chart cards gate on analog count ≥8 (DistributionCard, ExposureCard): the shared fixture has 3 analogs → "not enough data" fallback. Those two previews extend analogs to 10 realistic ЕКБ lots INLINE in their own preview file (spread FIXTURE_ESTIMATE, override analogs+n_analogs) — never edit _fixtures.ts.
  • Admin/scraper panels (DataQualitySection, ProviderProxySection, RunsTable, PacingSection, SystemHealthSection) fetch their own data with no repo fixture → they render their real styled LOADING/header state. Graded good as honest states; richer data would need admin fixtures that don't exist in the repo.
  • MapCard / MapPicker: Leaflet from unpkg loads in the capture env; OSM raster tiles sometimes don't paint within the screenshot window (external tile fetch) — markers/popup/controls still render. Both graded good. MapPicker is a createPortal full-viewport overlay — rendered contained in capture; if a future capture viewport change makes it escape, add cfg.overrides.MapPicker.cardMode/viewport.

Re-sync risks

  • The process shim env defaults live in .design-sync/overrides/source-kit.mjs (synth entry). If the app reads NEW process.env.NEXT_PUBLIC_* vars, add them there or components throw.
  • PreviewProvider seed keys are pinned to the fixture's estimate_id and address/area/rooms — if fixture.ts changes those, update preview-provider.tsx to match (else fetch-coupled cards re-floor).
  • Synth scan re-includes Next route/layout/error files on every build → componentSrcMap nulls (13 entries) must persist. New app-router pages would need adding.
  • .d.ts props are weak ([key:string]:unknown) — synth mode has no built types. Real prop contracts live in each component's source interface Props. A real tsup/tsc lib build would fix this (recommend if the agent needs strong API contracts).
  • Grades clear on any cfg.provider/preview-affecting config change (expected) — re-grade from fresh sheets.