decodeVinOrCandidates returns { type: "notFound" } or { type: "error" }
instead of null, so data !== null was incorrectly marking these as
success. Now explicitly checks emex result type.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
testService() was swallowing errors — services like parts-catalogs catch
internally and return null, so the outer try/catch never fired. Now each
service call has its own try/catch, and null responses get an explicit
error message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The api client unwraps response.data automatically, which conflicts
with our testService response having its own 'data' field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Admin-only page at /dashboard/service-test with dropdown to test
each VIN decode service (Corgi, PartsCatalogs, PL24, EMEX, VIN API)
individually or the full cascade. Results shown as JSON on page,
no DB writes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Backend: add `model` query param to wizard-vehicles endpoint
- Backend: 3-tier matching: exact name → name prefix → model fuzzy
- Frontend: simplified wizard UI, show determined params as tags
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace static DB-based dropdown chain with live wizard from emexdwc.ae.
The wizard API (GetWizard2) works without auth and shows all models/options
for each catalog (e.g. AU1587 now shows 103 Audi models vs 11 before).
Backend: proxy GetWizard2 + search DB for matching vehicles after wizard completes.
Frontend: step-by-step wizard with breadcrumb navigation, search, and reset.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Detect available filter fields from actual data per catalog
- Skip fields whose values are substrings of optionsRaw (e.g. driveType
redundant when optionsRaw="LEFT (GSX)")
- Skip fields that duplicate already-added filters (e.g. engine=LHD same
as driveType=LHD in Land Rover)
- Use optionsRaw as primary variant text in vehicle rows
- Works for all 54 catalogs: Renault (structured), Fiat, BMW, Volvo, etc.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dropdowns now auto-detect which fields have data (engine, body type,
transmission, drive type, fuel type, variant) and show only relevant
filters. Each dropdown cascades — selecting a value narrows options
for subsequent filters. Handles both structured options_raw (Renault)
and standard DB fields (Fiat, BMW, Volvo, etc).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Model → Engine → Gearbox dropdown chain narrows 4000+ vehicles down
to a manageable selection. Parses options_raw key:value pairs for
catalogs that have structured data (Renault). Falls back to engine/
transmission fields for others (BMW, Volvo, etc).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parse emexdwc.ae QuickGroups hierarchy and create a static gid→path mapping
(384 groups). Groups page now shows collapsible tree (Body > Vehicle Front >
Bumper/Parts) instead of flat list. Unmapped groups fall back to flat display.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace stacked images + plain table with interactive SchemaViewer (same as PL24).
Backend transforms response to SchemaViewer-compatible format (Part/SchemaPic types).
Add prev/next pagination for groups with multiple schema images.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Redesign emex_* tables from vehicle-centric to catalog-centric structure with
junction tables (emex_vehicle_group_links, emex_vehicle_part_links). Migrate
92M+ rows from emex DB via postgres_fdw. Add EmexCatalogService for browse
and VIN pre-scraped matching, with Redis caching. Frontend catalog page now
has PL24/Emex tabs with full drill-down routes (brand → vehicle → group → parts).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Helmet's default CSP blocked images from storage.sase.tr (different
origin). Add it to img-src and connect-src directives.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move SPA fallback from main.ts catch-all (didn't work - NestJS 404
handler runs first) to HttpExceptionFilter. Now non-API GET 404s
serve index.html so client-side routing works for /dashboard/* etc.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
NestJS was returning 404 JSON for SPA routes like /dashboard/search
because ServeStaticModule couldn't find a matching file and the request
fell through to NestJS router. Add explicit catch-all GET handler after
app.init() to serve index.html for non-API routes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add multi-stage Dockerfile (node:22-alpine, pnpm, Chromium for Playwright)
- Add docker-compose.coolify.yml with api, worker, redis services
- Add @nestjs/serve-static for serving Vite frontend from NestJS
- Add .dockerignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Playwright browser with pure HTTP for EMEX VIN decode:
- Vehicles.aspx, QuickGroups.aspx, QuickDetails.aspx all work
without authentication — no session/browser needed
- VIN decode drops from ~10-20s (Playwright) to ~1-5s (HTTP)
- Playwright browser kept as fallback if HTTP fails
Add multi-candidate selection for EMEX (mirrors PartsCatalogs flow):
- EmexCandidate interface matches PcatCar shape so VehicleSelectModal
renders without changes
- decodeVinOrCandidates(): single HTTP fetch returns vehicle OR
candidates (avoids double Vehicles.aspx request)
- decodeVinByIndex(): resolves user-selected candidate by index
- vehicles.service: emexCandidates in VinResolveResult, emexCarIndex
param in decodeVin/resolveVin, resolveEmexCarByIndex() method
- vehicles.controller: @Body("emexCarIndex") accepted
- search.tsx: candidateSource state, handleCandidateSelect sends
emexCarIndex or pcatCarId based on source
Test VIN NM417800006410193 (Fiat SIENA) now shows 2-option modal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remotion Player + compositions (SchemaDemo, DashboardDemo, EcommerceDemo)
replaced with React.lazy wrappers in routes/index.tsx — now split into
separate chunks loaded only when the landing page sections are visible
- posthog-js static import replaced with a dynamic load() wrapper in
lib/posthog.ts; all exported functions remain fire-and-forget with the
same API signature
- subscription/index.tsx updated to use new setPeopleProperties() helper
instead of the raw posthog instance
Initial chunk: 1,082 KB → 727 KB (-33%), gzip 324 KB → 212 KB
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Integrate external parts catalogs API with auth service, add BullMQ-based
catalog prefetch worker for background data caching, expand vehicles service
with shared vehicle support, and add vehicle select modal to frontend.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add unavailable/remark/modelCodes/presel fields to categories and parts DB schema
- Pass PL24 unavailable flag through pipeline instead of filtering out records
- Show unavailable categories/parts at reduced opacity in grid, tree, and parts panel
- Display part remark and model codes as secondary info in parts table
- Move Google sign-in button above email form on login/register pages with branded icon
- Add public email existence check endpoint for better login error messages
- Update INDEX.md documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Landing hero VIN search now decodes directly for logged-in users
- Unauthenticated users redirected to register with VIN preserved in search params
- Added loading states for decode button
- Tightened section spacing across landing page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add oem_code_copies table and analytics module for tracking part code copies
- Integrate PostHog for frontend product analytics (VIN decode, OEM copy events)
- Switch email service from stub to Postal API with proper error handling
- Add copy button to parts panel with clipboard + server-side logging
- Add admin copy-logs page with filtering and top-copied-codes view
- Add VIN report endpoint for users to flag unrecognized chassis numbers
- Add Postal email env vars to config schema
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add OpenTelemetry SDK with tracing, metrics, and OTLP export for API and worker
- Integrate Grafana Faro for frontend real-user monitoring
- Instrument health checks, database, Bull queues, and HTTP exception filter
- Add Grafana dashboard JSON for service overview
- Remove deprecated apps/web-nj (Next.js) — fully replaced by Vite+React frontend
- Update nginx config with OTEL collector proxy
- Minor UI fixes in schema viewer, category components, and subscription flow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move trial creation from auth hook to dedicated /subscriptions/trial endpoint
with eligibility checks (3-day Full Paket trial)
- Add animated onboarding progress (Remotion) with confetti on completion
- Register redirects to subscription page with welcome flow
- Add Google social login/signup support with config injection
- Improve hotspot overlay visibility in dark mode
- Show "Panele Git" on landing page when authenticated
- Turkish translations for API error messages
- Add toast utility wrapper, UUID generation for auth IDs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Browser autofill forces a light background on inputs, making white text
invisible in dark mode. Added -webkit-autofill overrides in globals.css
and switched Input from bg-transparent to bg-background with explicit
text-foreground.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split-panel auth layout with dark promo panel, sectioned dashboard nav with theme toggle,
testimonials/social proof on landing page, e-commerce Remotion demo, and static pages
(about, blog, contact, terms, privacy, KVKK).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace static mockups with Remotion Player animations:
- SchemaDemo: 3x3 grid with spring animations, highlight, part info card
- DashboardDemo: 5-scene product flow (VIN input, vehicle info, categories, schema, OEM codes)
- Both support dark/light theme via isDark prop, autoplay + loop
Expand pricing section from single teaser to all 4 plans with horizontal scroll on mobile.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rewrite landing page copy with Jobs-to-be-Done and loss framing
- Add VIN live preview via backend pl24+emex decode chain
- Add comparison table (mobile-responsive), stats, pricing teaser, referral banner
- Replace testimonials with aggregate social proof stats
- Create demo page with 3-step VIN decode flow for unregistered users
- Add public /vehicles/preview/:vin endpoint (no auth required)
- Auto-create 7-day trial subscription on user registration
- Highlight multi-catalog cross-querying advantage in OEM feature and comparison
- Update register page with trial messaging and VIN param support
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add PL24 Ford legacy service for fordt_parts architecture
- Refactor EMEX to use persistent browser pool instead of per-call instances
- Make vehicle decode resilient: fallback to PL24 when Corgi doesn't recognize VIN
- Add collapsible sidebar with persistent user preference
- Improve brand access guard and categories service
- Add debug/test scripts for VIN e2e testing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enrich category children with batch-fetched schema images and leaf detection
on the API side. Display thumbnails in grid cards with shimmer loading
placeholders and background prefetching. Add TanStack Query caching for
category children. Fix insert race condition with onConflictDoNothing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace browser-based Puppeteer scraper with standalone scraper wrapper.
Add EMEX as fallback source for categories when PL24 is unavailable.
Update vehicle decoding to use new synchronous EMEX API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add WV1/WV2/WV3 WMI codes for Volkswagen commercial vehicles (Ticari)
mapped to vn_parts service. Skip BOM links in category traversal since
they are leaf categories returning parts, not subgroups.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add POST /admin/users endpoint with password hashing and role support
- Add user creation dialog to admin users page
- Migrate web from Next.js to Vite + TanStack Router
- Fix Dialog component positioning for Tailwind CSS v4
- Add @source directive for @sase/ui package scanning
- Add pl24 integration parsers and vehicle decode flow
- Backup old Next.js app to apps/web-nj
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add force-static + SEO metadata to home and pricing pages
- Lazy load SchemaViewer (ssr:false) — heaviest component with zoom/pan/pinch
- Lazy load BrandSelector in subscription page (conditional render)
- Extract DailyChart from admin dashboard, lazy load (ssr:false)
- Extract SettingsContent and PaymentContent into separate components
with dynamic imports and loading skeletons
- Add comprehensive project documentation (docs/INDEX.md)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add admin referrals management page with search and pagination
- Fix EFT payment endpoint URL and receipt upload path
- Add admin nav items to mobile-nav with role-based visibility
- Add referrals link and "Yonetim" section header to sidebar
- Update next-env.d.ts for Next.js 16 dev types path
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 11 new test files covering roles guard, brand-access guard, users,
brands, plans, payments, vehicles, categories, parts, referrals, and
admin services. Total test count increases from ~52 to 164, all passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>