docs: update INDEX.md + add catalog module, Ford/PSA legacy catalog, shared vehicles
- CatalogModule: VIN-less PL24 catalog browser (brands, models, categories, parts) - Supports P5 Modern (REST) and P4 Legacy (Ford, PSA) catalog architectures - Ford variant selector (model-year/engine/gearbox), PSA variant selector (body/engine/gearbox) - New API endpoints: ford-config, psa-bodies, psa-engines, psa-gearboxes, brands/:name/catalogs - Shared vehicles: vehicles table decoupled from users via userVehicles junction table - PL24 Ford Legacy service: comprehensive HTML-scraping for Ford/PSA/Hyundai/Kia/Nissan/Opel/Volvo - PL24 types and service updated for P4 Legacy brand support - Categories/parts service updated for dual FK (vehicleId + catalogVehicleId) pattern - Catalog browser frontend routes and components - docs/INDEX.md: updated with all new endpoints, components, hooks, routes (2026-03-02) - docs/pl24-catalog/: per-brand catalog exploration docs - scripts/migration-shared-vehicles.sql, pl24-catalog-explorer.js, posthog-dashboards.sh Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@@ -1,223 +0,0 @@
|
|||||||
/**
|
|
||||||
* EMEX VIN Scraper - Playwright Benchmark
|
|
||||||
* Same flow as puppeteer-based emex-vin-scraper.js but using Playwright
|
|
||||||
*/
|
|
||||||
const { chromium } = require('playwright');
|
|
||||||
|
|
||||||
const VIN = process.argv[2] || 'NM0GXXTTPGAG07617';
|
|
||||||
|
|
||||||
const CONFIG = {
|
|
||||||
baseUrl: 'https://emexdwc.ae',
|
|
||||||
timeout: 60000,
|
|
||||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
||||||
catalogMap: {
|
|
||||||
'WBA': 'BMW202501', 'WBS': 'BMW202501', 'WBY': 'BMW202501',
|
|
||||||
'WDB': 'MB201810', 'WDD': 'MB201810', 'WDC': 'MB201810', 'WDF': 'MB201810',
|
|
||||||
'WAU': 'AU1587', 'WVW': 'VW1587', 'WVG': 'VW1587',
|
|
||||||
'VF1': 'RENAULT201910', 'VF7': 'CPSA01', 'VF3': 'CPSA01',
|
|
||||||
'ZFA': 'CFIAT84', 'ZAR': 'RFIAT84',
|
|
||||||
'WF0': 'FORD202201', 'NM0': 'FORD202201',
|
|
||||||
'JTD': 'TOYOTA00', 'JTE': 'TOYOTA00',
|
|
||||||
'WP0': 'PO799', 'WP1': 'PO799',
|
|
||||||
},
|
|
||||||
brandMap: {
|
|
||||||
'BMW202501': 'BMW', 'MB201810': 'Mercedes-Benz', 'AU1587': 'Audi',
|
|
||||||
'VW1587': 'Volkswagen', 'RENAULT201910': 'Renault', 'CPSA01': 'Peugeot',
|
|
||||||
'CFIAT84': 'Fiat', 'RFIAT84': 'Alfa Romeo', 'FORD202201': 'Ford',
|
|
||||||
'TOYOTA00': 'Toyota', 'PO799': 'Porsche',
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function getCatalogCode(vin) {
|
|
||||||
return CONFIG.catalogMap[vin.substring(0, 3)] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBrand(code) {
|
|
||||||
return CONFIG.brandMap[code] || code;
|
|
||||||
}
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
const totalStart = performance.now();
|
|
||||||
const timings = {};
|
|
||||||
|
|
||||||
console.log('=' .repeat(70));
|
|
||||||
console.log('EMEX VIN SCRAPER - PLAYWRIGHT BENCHMARK');
|
|
||||||
console.log('=' .repeat(70));
|
|
||||||
console.log(`VIN: ${VIN}`);
|
|
||||||
const catalogCode = getCatalogCode(VIN);
|
|
||||||
console.log(`Catalog: ${catalogCode}`);
|
|
||||||
console.log('=' .repeat(70));
|
|
||||||
|
|
||||||
// ── Launch browser ──
|
|
||||||
let t = performance.now();
|
|
||||||
const browser = await chromium.launch({
|
|
||||||
headless: true,
|
|
||||||
args: [
|
|
||||||
'--no-sandbox',
|
|
||||||
'--disable-setuid-sandbox',
|
|
||||||
'--disable-dev-shm-usage',
|
|
||||||
'--disable-gpu',
|
|
||||||
]
|
|
||||||
});
|
|
||||||
const context = await browser.newContext({
|
|
||||||
userAgent: CONFIG.userAgent,
|
|
||||||
viewport: { width: 1920, height: 1080 },
|
|
||||||
});
|
|
||||||
const page = await context.newPage();
|
|
||||||
timings.browserLaunch = performance.now() - t;
|
|
||||||
console.log(`[${timings.browserLaunch.toFixed(0)}ms] Browser launched`);
|
|
||||||
|
|
||||||
// ── Step 1: Establish session ──
|
|
||||||
t = performance.now();
|
|
||||||
await page.goto(CONFIG.baseUrl, { waitUntil: 'networkidle', timeout: CONFIG.timeout });
|
|
||||||
timings.session = performance.now() - t;
|
|
||||||
const cookies = await context.cookies();
|
|
||||||
const sessionCookie = cookies.find(c => c.name === 'ASP.NET_SessionId')?.value || '';
|
|
||||||
console.log(`[${timings.session.toFixed(0)}ms] Session: ${sessionCookie ? 'established' : 'none'}`);
|
|
||||||
|
|
||||||
// ── Step 2: VIN URL search ──
|
|
||||||
t = performance.now();
|
|
||||||
const vinUrl = `${CONFIG.baseUrl}/Vehicles.aspx?ft=findByVIN&c=&ssd=&vin=${VIN}`;
|
|
||||||
console.log(`\nNavigating to: ${vinUrl}`);
|
|
||||||
await page.goto(vinUrl, { waitUntil: 'networkidle', timeout: CONFIG.timeout });
|
|
||||||
await page.waitForTimeout(1500); // wait for dynamic content
|
|
||||||
timings.vinSearch = performance.now() - t;
|
|
||||||
|
|
||||||
// Extract vehicle links
|
|
||||||
const vehicleLinks = await page.evaluate(() => {
|
|
||||||
const results = [];
|
|
||||||
const links = document.querySelectorAll('a[href*="Vehicle.aspx"], a[href*="QuickGroups.aspx"]');
|
|
||||||
links.forEach(link => {
|
|
||||||
const href = link.href;
|
|
||||||
const name = link.textContent.trim();
|
|
||||||
if (name && !results.some(r => r.name === name)) {
|
|
||||||
const cMatch = href.match(/[?&]c=([^&]+)/);
|
|
||||||
const ssdMatch = href.match(/[?&]ssd=([^&]+)/);
|
|
||||||
results.push({
|
|
||||||
name,
|
|
||||||
href,
|
|
||||||
catalogCode: cMatch ? cMatch[1] : '',
|
|
||||||
ssd: ssdMatch ? decodeURIComponent(ssdMatch[1]) : '',
|
|
||||||
isQuickGroups: href.includes('QuickGroups.aspx'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return results;
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`[${timings.vinSearch.toFixed(0)}ms] VIN search → ${vehicleLinks.length} vehicle(s) found`);
|
|
||||||
|
|
||||||
if (vehicleLinks.length > 0) {
|
|
||||||
const v = vehicleLinks[0];
|
|
||||||
console.log(` Vehicle: ${v.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Step 3: Fetch category tree ──
|
|
||||||
const qgLink = vehicleLinks.find(l => l.isQuickGroups);
|
|
||||||
let quickGroupsUrl = qgLink?.href || null;
|
|
||||||
|
|
||||||
if (!quickGroupsUrl && vehicleLinks.length > 0) {
|
|
||||||
const first = vehicleLinks[0];
|
|
||||||
if (first.ssd) {
|
|
||||||
const vidMatch = first.href.match(/[?&]vid=([^&]+)/);
|
|
||||||
const vid = vidMatch ? vidMatch[1] : '0';
|
|
||||||
quickGroupsUrl = `${CONFIG.baseUrl}/QuickGroups.aspx?c=${first.catalogCode || catalogCode}&vid=${vid}&ssd=${encodeURIComponent(first.ssd)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let categories = [];
|
|
||||||
if (quickGroupsUrl) {
|
|
||||||
t = performance.now();
|
|
||||||
await page.goto(quickGroupsUrl, { waitUntil: 'networkidle', timeout: CONFIG.timeout });
|
|
||||||
await page.waitForTimeout(1500);
|
|
||||||
|
|
||||||
categories = await page.evaluate(() => {
|
|
||||||
const cats = [];
|
|
||||||
const links = document.querySelectorAll('a[href*="QuickDetails"], a[href*="gid="]');
|
|
||||||
links.forEach(link => {
|
|
||||||
const gidMatch = link.href.match(/gid=(\d+)/);
|
|
||||||
if (gidMatch) {
|
|
||||||
cats.push({ gid: gidMatch[1], name: link.textContent.trim(), url: link.href });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return cats;
|
|
||||||
});
|
|
||||||
timings.categories = performance.now() - t;
|
|
||||||
console.log(`[${timings.categories.toFixed(0)}ms] Categories → ${categories.length} found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Step 4: Fetch first category parts ──
|
|
||||||
let parts = [];
|
|
||||||
let schemaImageUrl = null;
|
|
||||||
if (categories.length > 0) {
|
|
||||||
const firstCatUrl = categories[0].url;
|
|
||||||
t = performance.now();
|
|
||||||
console.log(`\nFetching parts from: ${categories[0].name}`);
|
|
||||||
await page.goto(firstCatUrl, { waitUntil: 'networkidle', timeout: CONFIG.timeout });
|
|
||||||
await page.waitForTimeout(1500);
|
|
||||||
|
|
||||||
// Check if we landed on Unit.aspx (redirect for BOM leaf nodes)
|
|
||||||
const currentUrl = page.url();
|
|
||||||
if (currentUrl.includes('QuickDetails.aspx')) {
|
|
||||||
// Look for Unit.aspx links
|
|
||||||
const unitLink = await page.evaluate(() => {
|
|
||||||
const link = document.querySelector('a[href*="Unit.aspx"]');
|
|
||||||
return link ? link.href : null;
|
|
||||||
});
|
|
||||||
if (unitLink) {
|
|
||||||
console.log(' Following Unit.aspx link...');
|
|
||||||
await page.goto(unitLink, { waitUntil: 'networkidle', timeout: CONFIG.timeout });
|
|
||||||
await page.waitForTimeout(1500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract parts from the page
|
|
||||||
const partsData = await page.evaluate(() => {
|
|
||||||
const result = { parts: [], schemaImageUrl: null };
|
|
||||||
|
|
||||||
// Schema image
|
|
||||||
const img = document.querySelector('img[src*="GetImage"], img[src*="schema"], img.partImage, #imgSchema');
|
|
||||||
if (img) result.schemaImageUrl = img.src;
|
|
||||||
|
|
||||||
// Parts table
|
|
||||||
const rows = document.querySelectorAll('table tr, .partRow, [class*="part"]');
|
|
||||||
rows.forEach(row => {
|
|
||||||
const cells = row.querySelectorAll('td');
|
|
||||||
if (cells.length >= 2) {
|
|
||||||
const name = cells[0]?.textContent?.trim() || '';
|
|
||||||
const partNumber = cells[1]?.textContent?.trim() || '';
|
|
||||||
if (name && partNumber) {
|
|
||||||
result.parts.push({ name, partNumber });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
parts = partsData.parts;
|
|
||||||
schemaImageUrl = partsData.schemaImageUrl;
|
|
||||||
timings.parts = performance.now() - t;
|
|
||||||
console.log(`[${timings.parts.toFixed(0)}ms] Parts → ${parts.length} found, schema: ${schemaImageUrl ? 'yes' : 'no'}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Cleanup ──
|
|
||||||
await browser.close();
|
|
||||||
|
|
||||||
// ── Summary ──
|
|
||||||
const totalTime = performance.now() - totalStart;
|
|
||||||
console.log('\n' + '=' .repeat(70));
|
|
||||||
console.log('PLAYWRIGHT BENCHMARK RESULTS');
|
|
||||||
console.log('=' .repeat(70));
|
|
||||||
console.log(`Browser launch: ${timings.browserLaunch?.toFixed(0) || '-'}ms`);
|
|
||||||
console.log(`Session establish: ${timings.session?.toFixed(0) || '-'}ms`);
|
|
||||||
console.log(`VIN search: ${timings.vinSearch?.toFixed(0) || '-'}ms`);
|
|
||||||
console.log(`Categories: ${timings.categories?.toFixed(0) || '-'}ms`);
|
|
||||||
console.log(`Parts (1st cat): ${timings.parts?.toFixed(0) || '-'}ms`);
|
|
||||||
console.log('-'.repeat(70));
|
|
||||||
console.log(`TOTAL: ${totalTime.toFixed(0)}ms (${(totalTime / 1000).toFixed(1)}s)`);
|
|
||||||
console.log('=' .repeat(70));
|
|
||||||
console.log(`Vehicle: ${getBrand(catalogCode)} - ${vehicleLinks[0]?.name || 'N/A'}`);
|
|
||||||
console.log(`Categories: ${categories.length}`);
|
|
||||||
console.log(`Parts (sample): ${parts.length}`);
|
|
||||||
})();
|
|
||||||
253
CLAUDE.md
@@ -16,7 +16,10 @@
|
|||||||
| **Styling** | Tailwind CSS 4, shadcn/ui (Radix primitives) |
|
| **Styling** | Tailwind CSS 4, shadcn/ui (Radix primitives) |
|
||||||
| **State** | Zustand 5 |
|
| **State** | Zustand 5 |
|
||||||
| **Payments** | Iyzico (card) + EFT (bank transfer) |
|
| **Payments** | Iyzico (card) + EFT (bank transfer) |
|
||||||
|
| **Email** | Postal (transactional) |
|
||||||
| **Storage** | MinIO (S3-compatible) |
|
| **Storage** | MinIO (S3-compatible) |
|
||||||
|
| **Analytics** | PostHog (product analytics) |
|
||||||
|
| **Observability** | OpenTelemetry (API) + Grafana Faro (frontend) |
|
||||||
| **Testing** | Vitest 3, Playwright 1.50 |
|
| **Testing** | Vitest 3, Playwright 1.50 |
|
||||||
| **Linting** | Biome (2-space indent, double quotes, semicolons, trailing commas) |
|
| **Linting** | Biome (2-space indent, double quotes, semicolons, trailing commas) |
|
||||||
| **CI/CD** | GitHub Actions → SSH deploy → PM2 |
|
| **CI/CD** | GitHub Actions → SSH deploy → PM2 |
|
||||||
@@ -31,27 +34,28 @@ ss/
|
|||||||
│ │ ├── main.ts # Bootstrap (Helmet, CORS, rate limiting)
|
│ │ ├── main.ts # Bootstrap (Helmet, CORS, rate limiting)
|
||||||
│ │ ├── app.module.ts # Root module (global guards/interceptors/filters)
|
│ │ ├── app.module.ts # Root module (global guards/interceptors/filters)
|
||||||
│ │ ├── worker.ts # BullMQ worker process
|
│ │ ├── worker.ts # BullMQ worker process
|
||||||
│ │ ├── database/schema/ # Drizzle ORM schemas (core.ts, emex.ts, pl24.ts, relations.ts)
|
│ │ ├── database/schema/ # Drizzle ORM schemas (core.ts, emex.ts, pl24.ts, parts-catalogs.ts, relations.ts)
|
||||||
│ │ ├── common/ # Guards, interceptors, filters, decorators, pipes, DTOs
|
│ │ ├── common/ # Guards, interceptors, filters, decorators, pipes, DTOs
|
||||||
│ │ ├── integrations/ # corgi/, pl24/, emex/, vin-api/
|
│ │ ├── integrations/ # corgi/, pl24/, emex/, parts-catalogs/, vin-api/
|
||||||
│ │ └── [modules]/ # auth, users, brands, plans, subscriptions, payments,
|
│ │ └── [modules]/ # auth, users, brands, plans, subscriptions, payments,
|
||||||
│ │ # referrals, vehicles, categories, parts, translations,
|
│ │ # referrals, vehicles, categories, parts, catalog,
|
||||||
│ │ # admin, jobs, email, storage, redis
|
│ │ # translations, analytics, admin, jobs, email, storage, redis,
|
||||||
|
│ │ # telemetry
|
||||||
│ └── web/ # Vite + React frontend (port 3000)
|
│ └── web/ # Vite + React frontend (port 3000)
|
||||||
│ └── src/
|
│ └── src/
|
||||||
│ ├── main.tsx # Entry (RouterProvider, QueryClientProvider)
|
│ ├── main.tsx # Entry (RouterProvider, QueryClientProvider, Faro, PostHog)
|
||||||
│ ├── routes/ # TanStack Router file-based routes
|
│ ├── routes/ # TanStack Router file-based routes
|
||||||
│ ├── components/ # admin/, schema/, vehicles/, categories/, payment/, settings/, subscription/
|
│ ├── components/ # admin/, schema/, vehicles/, categories/, payment/, settings/, subscription/
|
||||||
│ ├── hooks/ # useAuth, useParts, useSchemaInteraction
|
│ ├── hooks/ # useAuth, useParts, useSchemaInteraction
|
||||||
│ ├── stores/ # Zustand: auth.store.ts, schema.store.ts
|
│ ├── stores/ # Zustand: auth.store.ts, schema.store.ts
|
||||||
│ ├── lib/ # api-client, auth-client, i18n, toast, user-settings
|
│ ├── lib/ # api-client, auth-client, i18n, posthog, faro, toast, user-settings, category-icons
|
||||||
│ └── messages/ # tr.json, en.json (i18n)
|
│ └── messages/ # tr.json, en.json (i18n)
|
||||||
├── packages/
|
├── packages/
|
||||||
│ ├── shared/ # @sase/shared — types, Zod schemas, constants, utils
|
│ ├── shared/ # @sase/shared — types, Zod schemas, constants, utils
|
||||||
│ ├── config/ # @sase/config — Zod env validation schema
|
│ ├── config/ # @sase/config — Zod env validation schema
|
||||||
│ └── ui/ # @sase/ui — shadcn-based React components
|
│ └── ui/ # @sase/ui — shadcn-based React components
|
||||||
├── docker/ # docker-compose.yml (PostgreSQL, Redis, MinIO)
|
├── docker/ # docker-compose.yml (PostgreSQL, Redis, MinIO) + nginx configs
|
||||||
├── scripts/ # deploy.sh, test scripts
|
├── scripts/ # deploy.sh, test/debug scripts
|
||||||
├── docs/ # INDEX.md + detailed docs (00-13)
|
├── docs/ # INDEX.md + detailed docs (00-13)
|
||||||
└── ecosystem.config.js # PM2 config (api, web, worker)
|
└── ecosystem.config.js # PM2 config (api, web, worker)
|
||||||
```
|
```
|
||||||
@@ -93,17 +97,147 @@ pnpm --filter web exec tsr generate
|
|||||||
- **Route files:** TanStack Router auto-generates `routeTree.gen.ts` — never edit manually
|
- **Route files:** TanStack Router auto-generates `routeTree.gen.ts` — never edit manually
|
||||||
- **i18n:** Turkish default (`tr.json`), English available (`en.json`). Use `useTranslation()` hook → `t("key")`
|
- **i18n:** Turkish default (`tr.json`), English available (`en.json`). Use `useTranslation()` hook → `t("key")`
|
||||||
|
|
||||||
|
## Backend Modules
|
||||||
|
|
||||||
|
| Module | Purpose |
|
||||||
|
|--------|---------|
|
||||||
|
| **AuthModule** | Better Auth (email/password + Google OAuth) |
|
||||||
|
| **UsersModule** | Profile CRUD, password change, OAuth connections, account deletion |
|
||||||
|
| **BrandsModule** | Brand CRUD (cached, admin-managed) |
|
||||||
|
| **PlansModule** | Pricing plan CRUD (cached, admin-managed) |
|
||||||
|
| **SubscriptionsModule** | Create, activate, cancel, resume, extend subscriptions |
|
||||||
|
| **PaymentsModule** | Iyzico card + EFT with receipt upload + admin approval |
|
||||||
|
| **ReferralsModule** | Referral code generation, tier-based rewards |
|
||||||
|
| **VehiclesModule** | VIN decode (multi-source fallback), vehicle history, brand access check |
|
||||||
|
| **CategoriesModule** | Hierarchical category tree, schema pictures |
|
||||||
|
| **PartsModule** | Parts by category, OEM code search |
|
||||||
|
| **CatalogModule** | VIN-less catalog browser — PL24 brands, models, category trees, parts |
|
||||||
|
| **TranslationsModule** | Automotive term translation (Redis → DB → Dictionary fallback) |
|
||||||
|
| **AnalyticsModule** | OEM code copy tracking, usage analytics |
|
||||||
|
| **AdminModule** | Dashboard stats, user management, payment approval |
|
||||||
|
| **EmailModule** | Postal transactional emails (welcome, payment confirmation, password reset) |
|
||||||
|
| **StorageModule** | S3/MinIO file upload/download |
|
||||||
|
| **RedisModule** | Key-value cache operations |
|
||||||
|
| **JobsModule** | BullMQ queues + processors + prefetch worker |
|
||||||
|
| **TelemetryModule** | OpenTelemetry SDK (tracing, metrics) |
|
||||||
|
|
||||||
## Architecture Patterns
|
## Architecture Patterns
|
||||||
|
|
||||||
- **Global guards order:** ThrottlerGuard → AuthGuard → RolesGuard
|
- **Global guards order:** ThrottlerGuard → AuthGuard → RolesGuard
|
||||||
- **Global interceptors:** TransformInterceptor → LoggingInterceptor → TimeoutInterceptor (30s)
|
- **Global interceptors:** TransformInterceptor → LoggingInterceptor → TimeoutInterceptor (30s)
|
||||||
- **Global filters:** HttpExceptionFilter, DrizzleExceptionFilter (unique constraint → 409)
|
- **Global filters:** HttpExceptionFilter, DrizzleExceptionFilter (unique constraint → 409)
|
||||||
- **VIN decode chain:** Corgi (offline WMI) → PL24 API → PartsCatalogs API → EMEX scraper → NHTSA VIN API
|
|
||||||
- **Category fetch chain:** DB cache → PL24 → PartsCatalogs → EMEX (lazy, source-based in `getCategoryTree`)
|
|
||||||
- **Caching:** Redis for sessions (5min), brands/plans (30min HTTP cache), translations, category trees
|
|
||||||
- **Job queues (BullMQ):** EMEX_SCRAPE (on-demand), CATALOG_PREFETCH (on-demand, post-VIN-decode, depth-limited), SUBSCRIPTION_EXPIRY (daily 3AM), QUERY_CLEANUP (weekly Sun 4AM)
|
|
||||||
- **Vite proxy:** `/api` requests → `http://localhost:4000` in dev
|
- **Vite proxy:** `/api` requests → `http://localhost:4000` in dev
|
||||||
|
|
||||||
|
### VIN Decode Fallback Chain
|
||||||
|
Corgi (offline WMI) → **PartsCatalogs API** → PL24 API → EMEX scraper → NHTSA VIN API
|
||||||
|
|
||||||
|
> Note: PartsCatalogs was added between Corgi and PL24 as it has broader VIN coverage. If multiple car matches return, the frontend prompts the user to select.
|
||||||
|
|
||||||
|
### Category Fetch Chain (VIN-based)
|
||||||
|
DB cache → PL24 → PartsCatalogs → EMEX (lazy, source-based in `getCategoryTree`)
|
||||||
|
|
||||||
|
### Catalog Browse Flow (VIN-less)
|
||||||
|
1. `GET /catalog/brands` → check user subscription access per brand
|
||||||
|
2. `GET /catalog/brands/:name/models` → PL24 `fetchVehicleList()` → stored in `catalogVehicles` table
|
||||||
|
3. `GET /catalog/vehicles/:id/categories` → PL24 `fetchMainGroups()` → stored in `categories` with `catalogVehicleId`
|
||||||
|
4. `GET /catalog/vehicles/:id/categories/:categoryId` → PL24 `fetchSubGroupsByPath()` / `fetchPartsByPath()` → stored lazily
|
||||||
|
|
||||||
|
### PL24 Catalog Architectures
|
||||||
|
- **P5_MODERN** (REST JSON API): VW Group, BMW, Mini, Mercedes, Porsche, Renault, Dacia, Alpine, Jaguar, Land Rover, Toyota, Lexus, MAN, Mitsubishi, Suzuki, etc.
|
||||||
|
- **LEGACY_PSA** (HTML scraping): Citroën, Peugeot
|
||||||
|
- **LEGACY_FORD** (HTML scraping): Ford passenger (wf0_parts) + commercial (fordt_parts)
|
||||||
|
- **LEGACY_HYUNDAI_KIA** (HTML scraping): Hyundai, Kia
|
||||||
|
- **LEGACY_NISSAN** (HTML scraping): Nissan, Infiniti
|
||||||
|
- **LEGACY_OPEL** (HTML scraping): Opel, Vauxhall
|
||||||
|
- **LEGACY_VOLVO** (HTML scraping): Volvo, Polestar
|
||||||
|
|
||||||
|
Our PL24 account (tr-903645) supports **VAG group only** for VIN-less catalog. Other brands may return errors on model listing. All P4 Legacy VIN decodes route through `PL24FordLegacyService.decodeVinForService(vin, serviceName)`.
|
||||||
|
|
||||||
|
### Caching Strategy
|
||||||
|
- Redis: VIN decode results (24h), category trees (2h for catalog browser), parts fetches (1h), translations
|
||||||
|
- HTTP Cache: brands, plans (30min `Cache-Control`)
|
||||||
|
- Sessions: Better Auth (5min Redis)
|
||||||
|
|
||||||
|
### Job Queues (BullMQ)
|
||||||
|
| Queue | Trigger | Schedule |
|
||||||
|
|-------|---------|----------|
|
||||||
|
| `EMEX_SCRAPE` | On-demand (VIN decode) | — |
|
||||||
|
| `CATALOG_PREFETCH` | After VIN decode | — (depth-limited, rate-limited, cooldown-guarded) |
|
||||||
|
| `SUBSCRIPTION_EXPIRY` | Cron | Daily 3:00 AM |
|
||||||
|
| `QUERY_CLEANUP` | Cron | Weekly Sunday 4:00 AM |
|
||||||
|
|
||||||
|
### Subscription & Access Control
|
||||||
|
- Plans have `brandCount` field: `0` = unlimited access, `N` = limited to N brands
|
||||||
|
- Brand access tracked in `userBrands` junction table (userId + subscriptionId + brandId)
|
||||||
|
- Full plan (brandCount=0) auto-adds all active brands on activation
|
||||||
|
- `BrandAccessGuard` (per-route) verifies user's subscription includes the requested brand
|
||||||
|
|
||||||
|
## Database Schema Summary
|
||||||
|
|
||||||
|
**Schema files:** `apps/api/src/database/schema/`
|
||||||
|
- `core.ts` — Main application tables
|
||||||
|
- `emex.ts` — EMEX scraper cache tables
|
||||||
|
- `pl24.ts` — PL24 catalog cache tables
|
||||||
|
- `parts-catalogs.ts` — PartsCatalogs API cache tables
|
||||||
|
- `relations.ts` — Drizzle ORM relationships
|
||||||
|
|
||||||
|
**Key tables in `core.ts`:**
|
||||||
|
- `users`, `sessions`, `accounts`, `verifications` — Better Auth managed
|
||||||
|
- `brands`, `plans` — Catalog of available brands/plans (admin-managed)
|
||||||
|
- `userSubscriptions` — status: pending/active/trial/cancelled/expired
|
||||||
|
- `userBrands` — junction table controlling brand access per subscription
|
||||||
|
- `payments` — Iyzico or EFT, status tracking
|
||||||
|
- `vehicles` — one per unique VIN, shared across users via `userVehicles`
|
||||||
|
- `userVehicles` — junction (userId + vehicleId unique), tracks lastAccessedAt
|
||||||
|
- `categories` — parent-child hierarchy; has both `vehicleId` (VIN-based) and `catalogVehicleId` (VIN-less) FKs (nullable for the other mode)
|
||||||
|
- `parts` — OEM code, quantity, hotspot index; same dual FK pattern as categories
|
||||||
|
- `schemaPics` — exploded view images + hotspots JSONB, linked to categories
|
||||||
|
- `catalogVehicles` — VIN-less catalog: one record per PL24 service vehicle (unique on source + serviceVehicleId)
|
||||||
|
- `queryLogs` — VIN decode audit trail
|
||||||
|
- `oemCodeCopies` — OEM code copy events (analytics)
|
||||||
|
- `referrals`, `passwordResetTokens`, `emexCategoryTranslations`
|
||||||
|
|
||||||
|
## Integrations
|
||||||
|
|
||||||
|
| Integration | Type | Path | Notes |
|
||||||
|
|-------------|------|------|-------|
|
||||||
|
| **Corgi** | Offline DB | `integrations/corgi/` | WMI database for brand ID |
|
||||||
|
| **PL24** | REST API + HTML scraper | `integrations/pl24/` | Multi-brand catalog; P5 (REST) + P4 Legacy (HTML). Services: `pl24.service.ts`, `pl24-ford-legacy.service.ts` |
|
||||||
|
| **PartsCatalogs** | REST API + Playwright JWT | `integrations/parts-catalogs/` | Broad VIN coverage; JWT captured via Playwright from partner sites; IP-bound via DataImpulse proxy |
|
||||||
|
| **EMEX** | Browser scraper | `integrations/emex/` | Playwright-based (emexdwc.ae), async via BullMQ |
|
||||||
|
| **VIN-API** | REST API | `integrations/vin-api/` | NHTSA VIN decoder (last-resort fallback) |
|
||||||
|
|
||||||
|
## Frontend Routes
|
||||||
|
|
||||||
|
**Public:** `/`, `/pricing`, `/about`, `/contact`, `/blog`, `/demo`, `/privacy`, `/terms`, `/kvkk`
|
||||||
|
|
||||||
|
**Auth (layout `_auth.tsx`):** `/login`, `/register`, `/forgot-password`, `/reset-password`
|
||||||
|
|
||||||
|
**Dashboard (protected, layout `dashboard.tsx`):**
|
||||||
|
- `/dashboard` — Home
|
||||||
|
- `/dashboard/search` — VIN decode input
|
||||||
|
- `/dashboard/history` — Past VIN searches
|
||||||
|
- `/dashboard/subscription` — Plan/brand selection
|
||||||
|
- `/dashboard/subscription/pay` — Payment (Iyzico or EFT)
|
||||||
|
- `/dashboard/billing` — Payment history
|
||||||
|
- `/dashboard/settings` — Profile, Security, Connections, Referral tabs
|
||||||
|
- `/dashboard/vehicles/$id` — Vehicle details
|
||||||
|
- `/dashboard/vehicles/$id/categories/$categoryId` — Interactive schema + parts
|
||||||
|
|
||||||
|
**Catalog Browser (VIN-less, protected):**
|
||||||
|
- `/dashboard/catalog` — Brand grid with access flags
|
||||||
|
- `/dashboard/catalog/$brandName` — Model list (from PL24)
|
||||||
|
- `/dashboard/catalog/$brandName/$modelId` — Category tree/grid view
|
||||||
|
- `/dashboard/catalog/$brandName/$modelId/categories/$categoryId` — Sub-categories or schema+parts
|
||||||
|
|
||||||
|
**Admin (role-based):**
|
||||||
|
- `/dashboard/admin` — Stats + charts
|
||||||
|
- `/dashboard/admin/users` — User management
|
||||||
|
- `/dashboard/admin/payments` — EFT approval workflow
|
||||||
|
- `/dashboard/admin/referrals` — Referral tracking
|
||||||
|
- `/dashboard/admin/analytics` — Daily query stats
|
||||||
|
- `/dashboard/admin/copy-logs` — OEM code copy tracking
|
||||||
|
|
||||||
## Auth & Test Credentials
|
## Auth & Test Credentials
|
||||||
|
|
||||||
- **Admin:** `admin@sase.tr` / `Sase2026`
|
- **Admin:** `admin@sase.tr` / `Sase2026`
|
||||||
@@ -115,12 +249,105 @@ pnpm --filter web exec tsr generate
|
|||||||
|
|
||||||
**Required:** `DATABASE_URL`, `REDIS_PASSWORD`, `BETTER_AUTH_SECRET` (min 32 chars), `BETTER_AUTH_URL`, `MINIO_ENDPOINT`, `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`, `MINIO_PUBLIC_URL`, `CORS_ORIGIN`
|
**Required:** `DATABASE_URL`, `REDIS_PASSWORD`, `BETTER_AUTH_SECRET` (min 32 chars), `BETTER_AUTH_URL`, `MINIO_ENDPOINT`, `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`, `MINIO_PUBLIC_URL`, `CORS_ORIGIN`
|
||||||
|
|
||||||
**Optional:** `PORT` (4000), `REDIS_HOST` (127.0.0.1), `REDIS_PORT` (6379), `GOOGLE_CLIENT_ID/SECRET`, `IYZICO_API_KEY/SECRET_KEY/BASE_URL`, `PL24_BASE_URL/COMPANY_CODE/USERNAME/PASSWORD`, `EMEX_USERNAME/PASSWORD`, `ML_PREDICTION_ENABLED`
|
**Optional (grouped):**
|
||||||
|
- `PORT` (4000), `REDIS_HOST` (127.0.0.1), `REDIS_PORT` (6379), `MINIO_BUCKET_NAME` (sase-schemas), `MINIO_USE_SSL` (false)
|
||||||
|
- `GOOGLE_CLIENT_ID/SECRET` — Google OAuth
|
||||||
|
- `IYZICO_API_KEY/SECRET_KEY/BASE_URL` — Payment processing
|
||||||
|
- `PL24_BASE_URL/COMPANY_CODE/USERNAME/PASSWORD` — PL24 catalog API
|
||||||
|
- `EMEX_USERNAME/PASSWORD` — EMEX scraper
|
||||||
|
- `PCAT_USE_PROXY` (true), `PCAT_PROXY_HOST` (gw.dataimpulse.com), `PCAT_PROXY_USER/PASS` — PartsCatalogs proxy
|
||||||
|
- `POSTAL_API_URL/API_KEY`, `POSTAL_FROM_ADDRESS` (noreply@sase.tr), `POSTAL_FROM_NAME` (Sase.tr) — Email
|
||||||
|
- `OTEL_ENABLED` (false), `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_SERVICE_NAME` (sase-api), `OTEL_TRACE_SAMPLE_RATE` (1.0) — OpenTelemetry
|
||||||
|
- `ML_PREDICTION_ENABLED` (false)
|
||||||
|
|
||||||
Full schema: `packages/config/src/index.ts`
|
Full schema: `packages/config/src/index.ts`
|
||||||
|
|
||||||
|
## Common Gotchas
|
||||||
|
|
||||||
|
- **Frontend is Vite + TanStack Router** — NOT Next.js
|
||||||
|
- **Categories & Parts tables have dual FKs:** `vehicleId` (VIN-based, nullable) and `catalogVehicleId` (VIN-less, nullable) — always check which context you're in
|
||||||
|
- **PartsCatalogs JWT is IP-bound** via DataImpulse proxy; the auth service manages a warm pool of JWTs using Playwright
|
||||||
|
- **P4 Legacy brands have no REST API** — Ford, PSA, Hyundai/Kia, Nissan, Opel, Volvo all use HTML scraping through `PL24FordLegacyService`
|
||||||
|
- **`catalogVehicles` unique key** is `(source, serviceVehicleId)` — not by VIN (these vehicles may not have VINs)
|
||||||
|
- **`routeTree.gen.ts`** is auto-generated by TanStack Router — never edit manually
|
||||||
|
- **DrizzleExceptionFilter** catches unique constraint violations → 409 Conflict
|
||||||
|
- **File uploads:** PNG/JPG/PDF only, max 5MB (middleware in `main.ts`)
|
||||||
|
- **Env validation** uses Zod from `@sase/config` — app won't start if env vars invalid
|
||||||
|
- **Playwright (EMEX/PartsCatalogs):** `waitUntil: 'networkidle'` (not `networkidle2`); `page.context().cookies()` (not `page.cookies()`)
|
||||||
|
- **VIN decode may return candidates** if PartsCatalogs finds multiple matches — frontend shows selection modal
|
||||||
|
|
||||||
|
## ast-grep — Structural Code Search & Refactoring
|
||||||
|
|
||||||
|
ast-grep (`sg`) does AST-aware pattern matching — finds code by structure, not text. Unlike `grep`, it understands syntax so `foo( bar )` and `foo(bar)` both match the pattern `foo($X)`.
|
||||||
|
|
||||||
|
**Install:** `npm i -g @ast-grep/cli` (already installed globally)
|
||||||
|
|
||||||
|
### Pattern syntax
|
||||||
|
|
||||||
|
| Syntax | Meaning |
|
||||||
|
|--------|---------|
|
||||||
|
| `$VAR` | Matches any **single** AST node (expression, identifier, etc.) |
|
||||||
|
| `$$$ARGS` | Matches **zero or more** nodes (variadic — use for argument lists, statements) |
|
||||||
|
| Literal code | Matches exact syntax structure |
|
||||||
|
|
||||||
|
### Common commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Search by pattern in TypeScript files
|
||||||
|
ast-grep -p 'console.log($$$)' -l ts apps/
|
||||||
|
|
||||||
|
# Search and preview rewrite (no changes yet)
|
||||||
|
ast-grep -p '$A && $A()' --rewrite '$A?.()' -l ts apps/
|
||||||
|
|
||||||
|
# Interactive rewrite — confirm each change
|
||||||
|
ast-grep -p '$A && $A()' --rewrite '$A?.()' --interactive -l ts apps/
|
||||||
|
|
||||||
|
# Apply all rewrites without confirmation
|
||||||
|
ast-grep -p '$A && $A()' --rewrite '$A?.()' --update-all -l ts apps/
|
||||||
|
|
||||||
|
# Output matches as JSON (useful for scripting)
|
||||||
|
ast-grep -p 'useQuery($$$)' -l tsx --json apps/web/src/
|
||||||
|
|
||||||
|
# Show surrounding context lines
|
||||||
|
ast-grep -p 'db.select()' -l ts -C 3 apps/api/src/
|
||||||
|
|
||||||
|
# Limit to specific file globs
|
||||||
|
ast-grep -p '@Public()' -l ts --globs 'apps/api/src/**/*.controller.ts' .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Language flags for this project
|
||||||
|
|
||||||
|
| Flag | Use for |
|
||||||
|
|------|---------|
|
||||||
|
| `-l ts` | API services, guards, modules, DTOs |
|
||||||
|
| `-l tsx` | React components, route files |
|
||||||
|
| `-l json` | i18n message files |
|
||||||
|
|
||||||
|
### Useful patterns for this codebase
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Find all @Public() decorated endpoints
|
||||||
|
ast-grep -p '@Public()' -l ts apps/api/src/
|
||||||
|
|
||||||
|
# Find all useQuery calls (TanStack Query)
|
||||||
|
ast-grep -p 'useQuery({$$$})' -l tsx apps/web/src/
|
||||||
|
|
||||||
|
# Find Drizzle inserts
|
||||||
|
ast-grep -p 'db.insert($TABLE).values($$$)' -l ts apps/api/src/
|
||||||
|
|
||||||
|
# Find all Redis cache sets
|
||||||
|
ast-grep -p 'this.redis.set($$$)' -l ts apps/api/src/
|
||||||
|
|
||||||
|
# Find t() translation calls missing a key
|
||||||
|
ast-grep -p 't($KEY)' -l tsx apps/web/src/
|
||||||
|
|
||||||
|
# Find all BullMQ queue.add() calls
|
||||||
|
ast-grep -p '$QUEUE.add($$$)' -l ts apps/api/src/jobs/
|
||||||
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- **Project index:** `docs/INDEX.md` (comprehensive — routes, API endpoints, DB schema, components)
|
- **Project index:** `docs/INDEX.md` (comprehensive — routes, API endpoints, DB schema, components)
|
||||||
- **Marketing context:** `.claude/product-marketing-context.md`
|
- **Marketing context:** `.claude/product-marketing-context.md`
|
||||||
- **Detailed docs:** `docs/00-overview.md` through `docs/13-analytics-posthog.md`
|
- **Detailed docs:** `docs/00-overview.md` through `docs/13-analytics-posthog.md`
|
||||||
|
- **Memory:** `.claude/projects/-home-s-ss/memory/MEMORY.md`
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { EmexModule } from "./integrations/emex/emex.module";
|
|||||||
import { TranslationsModule } from "./translations/translations.module";
|
import { TranslationsModule } from "./translations/translations.module";
|
||||||
import { AdminModule } from "./admin/admin.module";
|
import { AdminModule } from "./admin/admin.module";
|
||||||
import { AnalyticsModule } from "./analytics/analytics.module";
|
import { AnalyticsModule } from "./analytics/analytics.module";
|
||||||
|
import { CatalogModule } from "./catalog/catalog.module";
|
||||||
import { HealthController } from "./health.controller";
|
import { HealthController } from "./health.controller";
|
||||||
import { AuthGuard } from "./common/guards/auth.guard";
|
import { AuthGuard } from "./common/guards/auth.guard";
|
||||||
import { RolesGuard } from "./common/guards/roles.guard";
|
import { RolesGuard } from "./common/guards/roles.guard";
|
||||||
@@ -70,6 +71,7 @@ import { HttpExceptionFilter } from "./common/filters/http-exception.filter";
|
|||||||
TranslationsModule,
|
TranslationsModule,
|
||||||
AdminModule,
|
AdminModule,
|
||||||
AnalyticsModule,
|
AnalyticsModule,
|
||||||
|
CatalogModule,
|
||||||
],
|
],
|
||||||
controllers: [HealthController],
|
controllers: [HealthController],
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
92
apps/api/src/catalog/catalog.controller.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import { Controller, Get, Param, Post, Query } from "@nestjs/common";
|
||||||
|
import { CurrentUser } from "../common/decorators/current-user.decorator";
|
||||||
|
import { Roles } from "../common/decorators/roles.decorator";
|
||||||
|
import { CatalogService } from "./catalog.service";
|
||||||
|
|
||||||
|
@Controller("catalog")
|
||||||
|
export class CatalogController {
|
||||||
|
constructor(private catalogService: CatalogService) {}
|
||||||
|
|
||||||
|
@Get("brands")
|
||||||
|
getBrands(@CurrentUser() user: { id: string }) {
|
||||||
|
return this.catalogService.getBrands(user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("brands/:brandName/catalogs")
|
||||||
|
getCatalogs(@Param("brandName") brandName: string, @CurrentUser() user: { id: string }) {
|
||||||
|
return this.catalogService.getCatalogs(brandName, user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("brands/:brandName/models")
|
||||||
|
getModels(
|
||||||
|
@Param("brandName") brandName: string,
|
||||||
|
@Query("service") service: string | undefined,
|
||||||
|
@CurrentUser() user: { id: string },
|
||||||
|
) {
|
||||||
|
return this.catalogService.getModels(brandName, user.id, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("vehicles/:id")
|
||||||
|
getVehicle(@Param("id") id: string, @CurrentUser() user: { id: string }) {
|
||||||
|
return this.catalogService.getVehicle(id, user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("vehicles/:id/ford-config")
|
||||||
|
getFordModelConfig(@Param("id") id: string, @CurrentUser() user: { id: string }) {
|
||||||
|
return this.catalogService.getFordModelConfig(id, user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("vehicles/:id/psa-bodies")
|
||||||
|
getPsaBodies(@Param("id") id: string, @CurrentUser() user: { id: string }) {
|
||||||
|
return this.catalogService.getPsaBodies(id, user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("vehicles/:id/psa-engines")
|
||||||
|
getPsaEngines(
|
||||||
|
@Param("id") id: string,
|
||||||
|
@Query("body") body: string,
|
||||||
|
@CurrentUser() user: { id: string },
|
||||||
|
) {
|
||||||
|
return this.catalogService.getPsaEngines(id, body, user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("vehicles/:id/psa-gearboxes")
|
||||||
|
getPsaGearboxes(
|
||||||
|
@Param("id") id: string,
|
||||||
|
@Query("body") body: string,
|
||||||
|
@Query("engine") engine: string,
|
||||||
|
@CurrentUser() user: { id: string },
|
||||||
|
) {
|
||||||
|
return this.catalogService.getPsaGearboxes(id, body, engine, user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("vehicles/:id/categories")
|
||||||
|
getCategoryTree(
|
||||||
|
@Param("id") id: string,
|
||||||
|
@Query("body") body: string | undefined,
|
||||||
|
@Query("engine") engine: string | undefined,
|
||||||
|
@Query("gearbox") gearbox: string | undefined,
|
||||||
|
@CurrentUser() user: { id: string },
|
||||||
|
) {
|
||||||
|
return this.catalogService.getCategoryTree(id, user.id, body, engine, gearbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("vehicles/:id/categories/:categoryId")
|
||||||
|
getCategoryWithParts(
|
||||||
|
@Param("id") id: string,
|
||||||
|
@Param("categoryId") categoryId: string,
|
||||||
|
@Query("body") body: string | undefined,
|
||||||
|
@Query("engine") engine: string | undefined,
|
||||||
|
@Query("gearbox") gearbox: string | undefined,
|
||||||
|
@CurrentUser() user: { id: string },
|
||||||
|
) {
|
||||||
|
return this.catalogService.getCategoryWithParts(id, categoryId, user.id, body, engine, gearbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Admin: explore a PL24 service catalog structure for discovery */
|
||||||
|
@Post("explore/:serviceName")
|
||||||
|
@Roles("admin")
|
||||||
|
exploreService(@Param("serviceName") serviceName: string) {
|
||||||
|
return this.catalogService.exploreService(serviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
apps/api/src/catalog/catalog.module.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
import { CatalogController } from "./catalog.controller";
|
||||||
|
import { CatalogService } from "./catalog.service";
|
||||||
|
import { PL24Module } from "../integrations/pl24/pl24.module";
|
||||||
|
import { SubscriptionsModule } from "../subscriptions/subscriptions.module";
|
||||||
|
import { StorageModule } from "../storage/storage.module";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [PL24Module, SubscriptionsModule, StorageModule],
|
||||||
|
controllers: [CatalogController],
|
||||||
|
providers: [CatalogService],
|
||||||
|
exports: [CatalogService],
|
||||||
|
})
|
||||||
|
export class CatalogModule {}
|
||||||
1270
apps/api/src/catalog/catalog.service.ts
Normal file
3
apps/api/src/catalog/dto/catalog-query.dto.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export class ExploreServiceDto {
|
||||||
|
serviceName!: string;
|
||||||
|
}
|
||||||
@@ -22,7 +22,10 @@ function createService(db: any) {
|
|||||||
fetchGroups: vi.fn().mockResolvedValue([]),
|
fetchGroups: vi.fn().mockResolvedValue([]),
|
||||||
fetchParts: vi.fn().mockResolvedValue(null),
|
fetchParts: vi.fn().mockResolvedValue(null),
|
||||||
};
|
};
|
||||||
const service = new CategoriesService(db as any, redis as any, pl24Service as any, emexService as any, partsCatalogsService as any, storage as any);
|
const pl24FordLegacyService = {
|
||||||
|
fetchCategoriesForPsaVin: vi.fn().mockResolvedValue([]),
|
||||||
|
};
|
||||||
|
const service = new CategoriesService(db as any, redis as any, pl24Service as any, emexService as any, partsCatalogsService as any, storage as any, pl24FordLegacyService as any);
|
||||||
return { service, db, redis, pl24Service };
|
return { service, db, redis, pl24Service };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { Inject, Injectable, Logger, NotFoundException } from "@nestjs/common";
|
import { Inject, Injectable, Logger, NotFoundException } from "@nestjs/common";
|
||||||
import { eq, inArray, sql } from "drizzle-orm";
|
import { eq, inArray, isNull, sql } from "drizzle-orm";
|
||||||
import { DATABASE, Database } from "../database/database.provider";
|
import { DATABASE, Database } from "../database/database.provider";
|
||||||
import { categories, vehicles, schemaPics, parts } from "../database/schema/core";
|
import { categories, vehicles, schemaPics, parts } from "../database/schema/core";
|
||||||
import { RedisService } from "../redis/redis.service";
|
import { RedisService } from "../redis/redis.service";
|
||||||
import { PL24Service } from "../integrations/pl24/pl24.service";
|
import { PL24Service } from "../integrations/pl24/pl24.service";
|
||||||
|
import { PL24FordLegacyService } from "../integrations/pl24/pl24-ford-legacy.service";
|
||||||
import { EmexService } from "../integrations/emex/emex.service";
|
import { EmexService } from "../integrations/emex/emex.service";
|
||||||
import { PartsCatalogsService } from "../integrations/parts-catalogs/parts-catalogs.service";
|
import { PartsCatalogsService } from "../integrations/parts-catalogs/parts-catalogs.service";
|
||||||
|
import type { PcatGroup } from "../integrations/parts-catalogs/parts-catalogs.types";
|
||||||
import { StorageService } from "../storage/storage.service";
|
import { StorageService } from "../storage/storage.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -19,6 +21,7 @@ export class CategoriesService {
|
|||||||
private emexService: EmexService,
|
private emexService: EmexService,
|
||||||
private partsCatalogsService: PartsCatalogsService,
|
private partsCatalogsService: PartsCatalogsService,
|
||||||
private storage: StorageService,
|
private storage: StorageService,
|
||||||
|
private pl24FordLegacyService: PL24FordLegacyService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getCategoryTree(vehicleId: string) {
|
async getCategoryTree(vehicleId: string) {
|
||||||
@@ -65,6 +68,7 @@ export class CategoriesService {
|
|||||||
|
|
||||||
const insertData = uniquePl24.map((c) => ({
|
const insertData = uniquePl24.map((c) => ({
|
||||||
vehicleId,
|
vehicleId,
|
||||||
|
catalogVehicleId: null as string | null,
|
||||||
name: c.nameTr || c.nameEn,
|
name: c.nameTr || c.nameEn,
|
||||||
nameOriginal: c.nameEn,
|
nameOriginal: c.nameEn,
|
||||||
parentId: null as string | null,
|
parentId: null as string | null,
|
||||||
@@ -82,6 +86,82 @@ export class CategoriesService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── PSA (Citroën/Peugeot): gerçek scope'ları session ile çek ──
|
||||||
|
// rawData.categories'de nav linkler var (Portal, vehicle.action, vin-group) — gerçek parça
|
||||||
|
// kategorileri değil. Bu yüzden rawData bypass edip PSA session flow'u çağırıyoruz.
|
||||||
|
if (dbCategories.length === 0 && vehicle.rawData) {
|
||||||
|
const rawData = vehicle.rawData as any;
|
||||||
|
const catPath: string = rawData?.catalogInfo?.catalogPath ?? "";
|
||||||
|
const svcName: string = rawData?.catalogInfo?.serviceName ?? "";
|
||||||
|
if (catPath.startsWith("/psa/") && svcName && vehicle.vin) {
|
||||||
|
try {
|
||||||
|
const scopes = await this.pl24FordLegacyService.fetchCategoriesForPsaVin(svcName, vehicle.vin);
|
||||||
|
if (scopes.length > 0) {
|
||||||
|
const insertData = scopes.map((s) => ({
|
||||||
|
vehicleId,
|
||||||
|
catalogVehicleId: null as string | null,
|
||||||
|
name: s.nameTr || s.nameEn,
|
||||||
|
nameOriginal: s.nameEn,
|
||||||
|
parentId: null as string | null,
|
||||||
|
externalId: s.code,
|
||||||
|
linkPath: s.linkPath || null,
|
||||||
|
linkWid: null as string | null,
|
||||||
|
source: "pl24" as const,
|
||||||
|
}));
|
||||||
|
dbCategories = await this.db
|
||||||
|
.insert(categories)
|
||||||
|
.values(insertData)
|
||||||
|
.onConflictDoNothing()
|
||||||
|
.returning();
|
||||||
|
this.logger.log(`Stored ${dbCategories.length} PSA scope categories for ${vehicle.vin}`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.warn(`PSA scope fetch failed for ${vehicleId}: ${(err as Error).message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// P4 Legacy: categories already decoded from VIN HTML (rawData.categories)
|
||||||
|
// PSA araçları üstte işlendi — burada /psa/ path'lerini atla
|
||||||
|
if (dbCategories.length === 0 && vehicle.rawData) {
|
||||||
|
const rawData = vehicle.rawData as any;
|
||||||
|
const catPath: string = rawData?.catalogInfo?.catalogPath ?? "";
|
||||||
|
if (!catPath.startsWith("/psa/")) {
|
||||||
|
const decodedCats = Array.isArray(rawData?.categories)
|
||||||
|
? (rawData.categories as Array<{ code: string; nameEn: string; nameTr?: string; linkPath?: string; linkWid?: string }>)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (decodedCats && decodedCats.length > 0) {
|
||||||
|
try {
|
||||||
|
const seenNames = new Set<string>();
|
||||||
|
const uniqueCats = decodedCats.filter((c) => {
|
||||||
|
const name = c.nameTr || c.nameEn;
|
||||||
|
if (seenNames.has(name)) return false;
|
||||||
|
seenNames.add(name);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const insertData = uniqueCats.map((c) => ({
|
||||||
|
vehicleId,
|
||||||
|
catalogVehicleId: null as string | null,
|
||||||
|
name: c.nameTr || c.nameEn,
|
||||||
|
nameOriginal: c.nameEn,
|
||||||
|
parentId: null as string | null,
|
||||||
|
externalId: c.code,
|
||||||
|
linkPath: c.linkPath || null,
|
||||||
|
linkWid: c.linkWid || null,
|
||||||
|
source: "pl24" as const,
|
||||||
|
}));
|
||||||
|
|
||||||
|
dbCategories = await this.db.insert(categories).values(insertData).onConflictDoNothing().returning();
|
||||||
|
this.logger.log(`Stored ${dbCategories.length} P4 legacy categories for ${vehicle.vin}`);
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.warn(`P4 legacy category insert failed for ${vehicleId}: ${(err as Error).message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If still no categories, try PartsCatalogs
|
// If still no categories, try PartsCatalogs
|
||||||
if (dbCategories.length === 0 && vehicle.rawData) {
|
if (dbCategories.length === 0 && vehicle.rawData) {
|
||||||
const rawData = vehicle.rawData as any;
|
const rawData = vehicle.rawData as any;
|
||||||
@@ -98,6 +178,7 @@ export class CategoriesService {
|
|||||||
if (groups.length > 0) {
|
if (groups.length > 0) {
|
||||||
const insertData = groups.map((g) => ({
|
const insertData = groups.map((g) => ({
|
||||||
vehicleId,
|
vehicleId,
|
||||||
|
catalogVehicleId: null as string | null,
|
||||||
name: g.name,
|
name: g.name,
|
||||||
nameOriginal: g.name,
|
nameOriginal: g.name,
|
||||||
parentId: null as string | null,
|
parentId: null as string | null,
|
||||||
@@ -154,6 +235,7 @@ export class CategoriesService {
|
|||||||
.insert(categories)
|
.insert(categories)
|
||||||
.values({
|
.values({
|
||||||
vehicleId,
|
vehicleId,
|
||||||
|
catalogVehicleId: null as string | null,
|
||||||
name: node.name,
|
name: node.name,
|
||||||
nameOriginal: node.name,
|
nameOriginal: node.name,
|
||||||
parentId,
|
parentId,
|
||||||
@@ -191,6 +273,7 @@ export class CategoriesService {
|
|||||||
|
|
||||||
const insertData = uniqueCategories.map((c) => ({
|
const insertData = uniqueCategories.map((c) => ({
|
||||||
vehicleId,
|
vehicleId,
|
||||||
|
catalogVehicleId: null as string | null,
|
||||||
name: c.nameTr || c.nameEn,
|
name: c.nameTr || c.nameEn,
|
||||||
nameOriginal: c.nameEn,
|
nameOriginal: c.nameEn,
|
||||||
parentId: null as string | null,
|
parentId: null as string | null,
|
||||||
@@ -249,6 +332,8 @@ export class CategoriesService {
|
|||||||
|
|
||||||
if (!category) throw new NotFoundException("Kategori bulunamadı");
|
if (!category) throw new NotFoundException("Kategori bulunamadı");
|
||||||
|
|
||||||
|
if (!category.vehicleId) return [];
|
||||||
|
|
||||||
const [vehicle] = await this.db
|
const [vehicle] = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(vehicles)
|
.from(vehicles)
|
||||||
@@ -263,9 +348,10 @@ export class CategoriesService {
|
|||||||
|
|
||||||
// PartsCatalogs subgroups (on-demand drill-down)
|
// PartsCatalogs subgroups (on-demand drill-down)
|
||||||
if (category.source === "parts-catalogs" && rawData?.source === "parts-catalogs" && category.externalId) {
|
if (category.source === "parts-catalogs" && rawData?.source === "parts-catalogs" && category.externalId) {
|
||||||
|
let subGroups: PcatGroup[] = [];
|
||||||
try {
|
try {
|
||||||
const carParams = this.buildPcatCarParams(rawData.parameters);
|
const carParams = this.buildPcatCarParams(rawData.parameters);
|
||||||
const subGroups = await this.partsCatalogsService.fetchGroups(
|
subGroups = await this.partsCatalogsService.fetchGroups(
|
||||||
rawData.catalogId,
|
rawData.catalogId,
|
||||||
rawData.carId,
|
rawData.carId,
|
||||||
category.externalId,
|
category.externalId,
|
||||||
@@ -273,8 +359,30 @@ export class CategoriesService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (subGroups.length > 0) {
|
if (subGroups.length > 0) {
|
||||||
const insertData = subGroups.map((g) => ({
|
// Guard: if the API returned root-level groups as a fallback (happens when
|
||||||
|
// the groupId is a leaf-item reference, not a real sub-group ID), all returned
|
||||||
|
// groups will match existing root-level category externalIds for this vehicle.
|
||||||
|
// In that case, skip insertion — this category has no real sub-groups.
|
||||||
|
const rootExtIds = await this.db
|
||||||
|
.select({ externalId: categories.externalId })
|
||||||
|
.from(categories)
|
||||||
|
.where(eq(categories.vehicleId, category.vehicleId!));
|
||||||
|
const rootOnlyIds = rootExtIds
|
||||||
|
.filter((r) => r.externalId)
|
||||||
|
.map((r) => r.externalId as string);
|
||||||
|
const rootExtSet = new Set(rootOnlyIds);
|
||||||
|
const realSubGroups = subGroups.filter((g) => !rootExtSet.has(g.id));
|
||||||
|
|
||||||
|
if (realSubGroups.length === 0) {
|
||||||
|
this.logger.warn(
|
||||||
|
`getChildren: API returned root-level fallback groups for ${categoryId} (externalId=${category.externalId}) — skipping insert`,
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const insertData = realSubGroups.map((g) => ({
|
||||||
vehicleId: category.vehicleId,
|
vehicleId: category.vehicleId,
|
||||||
|
catalogVehicleId: category.catalogVehicleId,
|
||||||
name: g.name,
|
name: g.name,
|
||||||
nameOriginal: g.name,
|
nameOriginal: g.name,
|
||||||
parentId: categoryId,
|
parentId: categoryId,
|
||||||
@@ -303,7 +411,18 @@ export class CategoriesService {
|
|||||||
this.logger.error(`PartsCatalogs subgroup fetch failed for ${categoryId} (externalId=${category.externalId}): ${(err as Error).message}`);
|
this.logger.error(`PartsCatalogs subgroup fetch failed for ${categoryId} (externalId=${category.externalId}): ${(err as Error).message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return children.length > 0 ? this.enrichWithSchemaImages(children) : children;
|
if (children.length > 0) {
|
||||||
|
const enriched = await this.enrichWithSchemaImages(children);
|
||||||
|
// Use the API's hasSubgroups flag to correctly mark leaves vs parents.
|
||||||
|
// enrichWithSchemaImages only checks dbChildCount (always 0 for fresh inserts),
|
||||||
|
// so without this override, all sub-groups would be misidentified as leaves.
|
||||||
|
const hasSubgroupsMap = new Map(subGroups.map((g) => [g.id, g.hasSubgroups]));
|
||||||
|
return enriched.map((c: any) => ({
|
||||||
|
...c,
|
||||||
|
children: hasSubgroupsMap.get(c.externalId) === false ? [] : c.children,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!catalogInfo?.serviceName || !linkPath) {
|
if (!catalogInfo?.serviceName || !linkPath) {
|
||||||
@@ -311,7 +430,8 @@ export class CategoriesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BOM / servicepart item links are leaf categories — they return parts, not subgroups
|
// BOM / servicepart item links are leaf categories — they return parts, not subgroups
|
||||||
if (linkPath.includes("/bom/") || linkPath.includes("/bomdetails") || linkPath.includes("/partinfo/") || linkPath.includes("/servicepart/vin_items")) {
|
const lp = linkPath.toLowerCase();
|
||||||
|
if (lp.includes("/bom/") || lp.includes("/bomdetails") || lp.includes("/partinfo/") || lp.includes("/servicepart/vin_items")) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,6 +451,7 @@ export class CategoriesService {
|
|||||||
|
|
||||||
const insertData = uniqueSubGroups.map((sg) => ({
|
const insertData = uniqueSubGroups.map((sg) => ({
|
||||||
vehicleId: category.vehicleId,
|
vehicleId: category.vehicleId,
|
||||||
|
catalogVehicleId: category.catalogVehicleId,
|
||||||
name: sg.name,
|
name: sg.name,
|
||||||
nameOriginal: sg.name,
|
nameOriginal: sg.name,
|
||||||
parentId: categoryId,
|
parentId: categoryId,
|
||||||
@@ -377,16 +498,11 @@ export class CategoriesService {
|
|||||||
if (!category) throw new NotFoundException("Kategori bulunamadı");
|
if (!category) throw new NotFoundException("Kategori bulunamadı");
|
||||||
|
|
||||||
// Check if this category has children
|
// Check if this category has children
|
||||||
let children = await this.db
|
const children = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(categories)
|
.from(categories)
|
||||||
.where(eq(categories.parentId, categoryId));
|
.where(eq(categories.parentId, categoryId));
|
||||||
|
|
||||||
// For parts-catalogs categories with no DB children, fetch from API first
|
|
||||||
if (children.length === 0 && category.source === "parts-catalogs" && category.linkPath?.startsWith("pcat:")) {
|
|
||||||
children = await this.getChildren(categoryId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
return {
|
return {
|
||||||
id: category.id,
|
id: category.id,
|
||||||
@@ -400,7 +516,28 @@ export class CategoriesService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PSA parent nodes — always fetch children on-demand:
|
||||||
|
// • psa:: scope paths (top-level scopes)
|
||||||
|
// • json-illustrations.action paths (mid-level main groups → illustration lists)
|
||||||
|
const isPsaParent =
|
||||||
|
category.linkPath?.startsWith("psa::") ||
|
||||||
|
(category.linkPath?.includes("/psa/") && category.linkPath?.includes("json-illustrations.action"));
|
||||||
|
if (isPsaParent && category.vehicleId) {
|
||||||
|
const psaChildren = await this.getChildren(categoryId);
|
||||||
|
return {
|
||||||
|
id: category.id,
|
||||||
|
name: category.name,
|
||||||
|
description: category.nameOriginal || null,
|
||||||
|
parentId: category.parentId || null,
|
||||||
|
parts: [],
|
||||||
|
schemaPics: [],
|
||||||
|
hotspots: [],
|
||||||
|
children: psaChildren,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Leaf category — get or fetch parts
|
// Leaf category — get or fetch parts
|
||||||
|
let discoveredChildren: any[] = [];
|
||||||
let dbParts = await this.db
|
let dbParts = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(parts)
|
.from(parts)
|
||||||
@@ -420,11 +557,13 @@ export class CategoriesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((needParts || needImage) && category.linkPath) {
|
if ((needParts || needImage) && category.linkPath) {
|
||||||
const [vehicle] = await this.db
|
const [vehicle] = category.vehicleId
|
||||||
|
? await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(vehicles)
|
.from(vehicles)
|
||||||
.where(eq(vehicles.id, category.vehicleId))
|
.where(eq(vehicles.id, category.vehicleId))
|
||||||
.limit(1);
|
.limit(1)
|
||||||
|
: [];
|
||||||
|
|
||||||
if (vehicle && category.source === "parts-catalogs" && category.linkPath?.startsWith("pcat:")) {
|
if (vehicle && category.source === "parts-catalogs" && category.linkPath?.startsWith("pcat:")) {
|
||||||
// PartsCatalogs: fetch parts + schema image via API
|
// PartsCatalogs: fetch parts + schema image via API
|
||||||
@@ -536,8 +675,10 @@ export class CategoriesService {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
const msg = (err as Error).message;
|
const msg = (err as Error).message;
|
||||||
this.logger.error(`Failed to fetch PartsCatalogs parts for category ${categoryId}: ${msg}`);
|
this.logger.error(`Failed to fetch PartsCatalogs parts for category ${categoryId}: ${msg}`);
|
||||||
// HTTP 400 = upstream API has no parts for this group; mark unavailable to prevent infinite retries
|
// HTTP 400 = upstream API has no direct parts for this group — it may be a parent group
|
||||||
if (msg.includes("HTTP 400")) {
|
if (msg.includes("HTTP 400")) {
|
||||||
|
discoveredChildren = await this.getChildren(categoryId);
|
||||||
|
if (discoveredChildren.length === 0) {
|
||||||
await this.db
|
await this.db
|
||||||
.update(categories)
|
.update(categories)
|
||||||
.set({ unavailable: true })
|
.set({ unavailable: true })
|
||||||
@@ -545,6 +686,7 @@ export class CategoriesService {
|
|||||||
this.logger.warn(`Marked category ${categoryId} as unavailable (empty group from PartsCatalogs)`);
|
this.logger.warn(`Marked category ${categoryId} as unavailable (empty group from PartsCatalogs)`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (vehicle && category.source === "emex") {
|
} else if (vehicle && category.source === "emex") {
|
||||||
// EMEX: fetch parts + schema image via Puppeteer from QuickDetails URL
|
// EMEX: fetch parts + schema image via Puppeteer from QuickDetails URL
|
||||||
try {
|
try {
|
||||||
@@ -642,7 +784,7 @@ export class CategoriesService {
|
|||||||
name: p.name,
|
name: p.name,
|
||||||
nameOriginal: p.name,
|
nameOriginal: p.name,
|
||||||
description: p.description || null,
|
description: p.description || null,
|
||||||
quantity: p.quantity || null,
|
quantity: p.quantity ? (parseInt(String(p.quantity), 10) || null) : null,
|
||||||
position: p.positionCode || null,
|
position: p.positionCode || null,
|
||||||
hotspotIndex: p.hotspotId ? (() => {
|
hotspotIndex: p.hotspotId ? (() => {
|
||||||
const val = parseInt(p.hotspotId!, 10);
|
const val = parseInt(p.hotspotId!, 10);
|
||||||
@@ -659,9 +801,55 @@ export class CategoriesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store schema image if available
|
// Store schema image if available
|
||||||
if (needImage && pl24Result.schemaImageUrl) {
|
// PSA: if cache hit returned no buffer, re-fetch fresh to get the image
|
||||||
|
const isPsaBoard = category.linkPath.includes("/psa/") && category.linkPath.includes("image-board.action");
|
||||||
|
if (needImage && isPsaBoard && !pl24Result.schemaImageBuffer) {
|
||||||
|
try {
|
||||||
|
const freshResult = await this.pl24FordLegacyService.fetchPsaParts(
|
||||||
|
category.linkPath, catalogInfo.serviceName, "_all_", "_all_", "_all_", true,
|
||||||
|
);
|
||||||
|
if (freshResult.schemaImageBuffer) {
|
||||||
|
(pl24Result as any).schemaImageBuffer = freshResult.schemaImageBuffer;
|
||||||
|
(pl24Result as any).schemaImageContentType = freshResult.schemaImageContentType;
|
||||||
|
(pl24Result as any).schemaWidth = freshResult.schemaWidth;
|
||||||
|
(pl24Result as any).schemaHeight = freshResult.schemaHeight;
|
||||||
|
(pl24Result as any).hotspots = freshResult.hotspots;
|
||||||
|
}
|
||||||
|
} catch (refetchErr) {
|
||||||
|
this.logger.warn(`PSA image re-fetch failed for ${categoryId}: ${(refetchErr as Error).message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needImage && (pl24Result.schemaImageBuffer || (!isPsaBoard && pl24Result.schemaImageUrl))) {
|
||||||
|
// PSA: image already downloaded as buffer — upload directly to MinIO
|
||||||
|
if (pl24Result.schemaImageBuffer) {
|
||||||
|
try {
|
||||||
|
const ct = pl24Result.schemaImageContentType || "image/png";
|
||||||
|
const ext = ct.includes("gif") ? "gif" : "png";
|
||||||
|
const key = `schemas/psa-${categoryId}.${ext}`;
|
||||||
|
const minioUrl = await this.storage.upload(key, pl24Result.schemaImageBuffer, ct);
|
||||||
|
const hotspotsData = {
|
||||||
|
width: pl24Result.schemaWidth || null,
|
||||||
|
height: pl24Result.schemaHeight || null,
|
||||||
|
items: pl24Result.hotspots || [],
|
||||||
|
};
|
||||||
|
const [inserted] = await this.db
|
||||||
|
.insert(schemaPics)
|
||||||
|
.values({
|
||||||
|
categoryId,
|
||||||
|
imageUrl: minioUrl,
|
||||||
|
hotspots: JSON.stringify(hotspotsData),
|
||||||
|
source: "pl24",
|
||||||
|
})
|
||||||
|
.returning();
|
||||||
|
pics.push(inserted);
|
||||||
|
this.logger.log(`Stored PSA schema image for category ${categoryId}: ${minioUrl}`);
|
||||||
|
} catch (imgErr) {
|
||||||
|
this.logger.warn(`Failed to upload PSA schema image: ${(imgErr as Error).message}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// P5 REST: download via getSchemaImage
|
||||||
const imageResult = await this.pl24Service.getSchemaImage(
|
const imageResult = await this.pl24Service.getSchemaImage(
|
||||||
pl24Result.schemaImageUrl,
|
pl24Result.schemaImageUrl!,
|
||||||
catalogInfo.serviceName,
|
catalogInfo.serviceName,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -687,6 +875,7 @@ export class CategoriesService {
|
|||||||
pics.push(inserted);
|
pics.push(inserted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(`Failed to fetch parts for category ${categoryId}: ${(err as Error).message}`);
|
this.logger.error(`Failed to fetch parts for category ${categoryId}: ${(err as Error).message}`);
|
||||||
}
|
}
|
||||||
@@ -694,6 +883,20 @@ export class CategoriesService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If fetchParts revealed this is actually a parent group (HTTP 400 → sub-groups found), return children
|
||||||
|
if (discoveredChildren.length > 0) {
|
||||||
|
return {
|
||||||
|
id: category.id,
|
||||||
|
name: category.name,
|
||||||
|
description: category.nameOriginal || null,
|
||||||
|
parentId: category.parentId || null,
|
||||||
|
parts: [],
|
||||||
|
schemaPics: [],
|
||||||
|
hotspots: [],
|
||||||
|
children: discoveredChildren,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Parse hotspots data (may include width/height metadata)
|
// Parse hotspots data (may include width/height metadata)
|
||||||
let hotspots: any[] = [];
|
let hotspots: any[] = [];
|
||||||
let schemaWidth = 0;
|
let schemaWidth = 0;
|
||||||
@@ -803,7 +1006,7 @@ export class CategoriesService {
|
|||||||
? (!!c.linkPath && dbChildCount === 0)
|
? (!!c.linkPath && dbChildCount === 0)
|
||||||
: c.source === "parts-catalogs"
|
: c.source === "parts-catalogs"
|
||||||
? (!!c.linkPath?.startsWith("pcat:") && dbChildCount === 0)
|
? (!!c.linkPath?.startsWith("pcat:") && dbChildCount === 0)
|
||||||
: (c.linkPath?.includes("/bom/") || c.linkPath?.includes("/bomdetails") || c.linkPath?.includes("/partinfo/") || c.linkPath?.includes("/servicepart/vin_items") || (!c.linkPath && dbChildCount === 0));
|
: (c.linkPath?.toLowerCase()?.includes("/bom/") || c.linkPath?.toLowerCase()?.includes("/bomdetails") || c.linkPath?.toLowerCase()?.includes("/partinfo/") || c.linkPath?.toLowerCase()?.includes("/servicepart/vin_items") || (!c.linkPath && dbChildCount === 0));
|
||||||
return {
|
return {
|
||||||
...c,
|
...c,
|
||||||
schemaImageUrl: picMap.get(c.id) || null,
|
schemaImageUrl: picMap.get(c.id) || null,
|
||||||
|
|||||||
@@ -231,6 +231,36 @@ export const oemCodeCopies = pgTable(
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ─── Catalog Vehicles (VIN-less catalog browse — one record per PL24 vehicleId) ──
|
||||||
|
export const catalogVehicles = pgTable(
|
||||||
|
"catalog_vehicles",
|
||||||
|
{
|
||||||
|
id: uuid("id").primaryKey().defaultRandom(),
|
||||||
|
source: varchar("source", { length: 20 }).default("pl24").notNull(),
|
||||||
|
serviceName: varchar("service_name", { length: 100 }).notNull(),
|
||||||
|
brandName: varchar("brand_name", { length: 100 }).notNull(),
|
||||||
|
brandId: uuid("brand_id").references(() => brands.id),
|
||||||
|
model: varchar("model", { length: 255 }).notNull(),
|
||||||
|
year: varchar("year", { length: 50 }),
|
||||||
|
engine: varchar("engine", { length: 255 }),
|
||||||
|
bodyType: varchar("body_type", { length: 100 }),
|
||||||
|
transmission: varchar("transmission", { length: 100 }),
|
||||||
|
market: varchar("market", { length: 100 }),
|
||||||
|
serviceVehicleId: varchar("service_vehicle_id", { length: 255 }).notNull(),
|
||||||
|
catalogPath: text("catalog_path"),
|
||||||
|
architecture: varchar("architecture", { length: 30 }),
|
||||||
|
metadata: jsonb("metadata"),
|
||||||
|
categoriesFetched: boolean("categories_fetched").default(false).notNull(),
|
||||||
|
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
||||||
|
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
|
||||||
|
},
|
||||||
|
(table) => [
|
||||||
|
uniqueIndex("catalog_vehicles_source_vid_idx").on(table.source, table.serviceVehicleId),
|
||||||
|
index("catalog_vehicles_brand_name_idx").on(table.brandName),
|
||||||
|
index("catalog_vehicles_service_name_idx").on(table.serviceName),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
// ─── Vehicles (shared config — one record per VIN) ──
|
// ─── Vehicles (shared config — one record per VIN) ──
|
||||||
export const vehicles = pgTable(
|
export const vehicles = pgTable(
|
||||||
"vehicles",
|
"vehicles",
|
||||||
@@ -280,13 +310,12 @@ export const categories = pgTable(
|
|||||||
"categories",
|
"categories",
|
||||||
{
|
{
|
||||||
id: uuid("id").primaryKey().defaultRandom(),
|
id: uuid("id").primaryKey().defaultRandom(),
|
||||||
vehicleId: uuid("vehicle_id")
|
vehicleId: uuid("vehicle_id").references(() => vehicles.id, { onDelete: "cascade" }),
|
||||||
.notNull()
|
catalogVehicleId: uuid("catalog_vehicle_id").references(() => catalogVehicles.id, { onDelete: "cascade" }),
|
||||||
.references(() => vehicles.id, { onDelete: "cascade" }),
|
|
||||||
name: varchar("name", { length: 500 }).notNull(),
|
name: varchar("name", { length: 500 }).notNull(),
|
||||||
nameOriginal: varchar("name_original", { length: 500 }),
|
nameOriginal: varchar("name_original", { length: 500 }),
|
||||||
parentId: uuid("parent_id"),
|
parentId: uuid("parent_id"),
|
||||||
externalId: varchar("external_id", { length: 500 }),
|
externalId: text("external_id"),
|
||||||
linkPath: text("link_path"),
|
linkPath: text("link_path"),
|
||||||
linkWid: varchar("link_wid", { length: 100 }),
|
linkWid: varchar("link_wid", { length: 100 }),
|
||||||
unavailable: boolean("unavailable").default(false).notNull(),
|
unavailable: boolean("unavailable").default(false).notNull(),
|
||||||
@@ -295,8 +324,9 @@ export const categories = pgTable(
|
|||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
index("categories_vehicle_id_idx").on(table.vehicleId),
|
index("categories_vehicle_id_idx").on(table.vehicleId),
|
||||||
|
index("categories_catalog_vehicle_id_idx").on(table.catalogVehicleId),
|
||||||
index("categories_parent_id_idx").on(table.parentId),
|
index("categories_parent_id_idx").on(table.parentId),
|
||||||
uniqueIndex("categories_vehicle_name_source_idx").on(table.vehicleId, table.name, table.source),
|
uniqueIndex("categories_vehicle_name_source_idx").on(table.vehicleId, table.catalogVehicleId, table.name, table.source),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -305,9 +335,8 @@ export const parts = pgTable(
|
|||||||
"parts",
|
"parts",
|
||||||
{
|
{
|
||||||
id: uuid("id").primaryKey().defaultRandom(),
|
id: uuid("id").primaryKey().defaultRandom(),
|
||||||
vehicleId: uuid("vehicle_id")
|
vehicleId: uuid("vehicle_id").references(() => vehicles.id, { onDelete: "cascade" }),
|
||||||
.notNull()
|
catalogVehicleId: uuid("catalog_vehicle_id").references(() => catalogVehicles.id, { onDelete: "cascade" }),
|
||||||
.references(() => vehicles.id, { onDelete: "cascade" }),
|
|
||||||
categoryId: uuid("category_id")
|
categoryId: uuid("category_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => categories.id, { onDelete: "cascade" }),
|
.references(() => categories.id, { onDelete: "cascade" }),
|
||||||
@@ -327,6 +356,7 @@ export const parts = pgTable(
|
|||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
index("parts_vehicle_id_idx").on(table.vehicleId),
|
index("parts_vehicle_id_idx").on(table.vehicleId),
|
||||||
|
index("parts_catalog_vehicle_id_idx").on(table.catalogVehicleId),
|
||||||
index("parts_category_id_idx").on(table.categoryId),
|
index("parts_category_id_idx").on(table.categoryId),
|
||||||
index("parts_oem_code_idx").on(table.oemCode),
|
index("parts_oem_code_idx").on(table.oemCode),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
parts,
|
parts,
|
||||||
schemaPics,
|
schemaPics,
|
||||||
referrals,
|
referrals,
|
||||||
|
catalogVehicles,
|
||||||
} from "./core";
|
} from "./core";
|
||||||
|
|
||||||
export const usersRelations = relations(users, ({ many }) => ({
|
export const usersRelations = relations(users, ({ many }) => ({
|
||||||
@@ -59,6 +60,13 @@ export const userBrandsRelations = relations(userBrands, ({ one }) => ({
|
|||||||
|
|
||||||
export const brandsRelations = relations(brands, ({ many }) => ({
|
export const brandsRelations = relations(brands, ({ many }) => ({
|
||||||
userBrands: many(userBrands),
|
userBrands: many(userBrands),
|
||||||
|
catalogVehicles: many(catalogVehicles),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const catalogVehiclesRelations = relations(catalogVehicles, ({ one, many }) => ({
|
||||||
|
brand: one(brands, { fields: [catalogVehicles.brandId], references: [brands.id] }),
|
||||||
|
categories: many(categories),
|
||||||
|
parts: many(parts),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const paymentsRelations = relations(payments, ({ one }) => ({
|
export const paymentsRelations = relations(payments, ({ one }) => ({
|
||||||
@@ -88,6 +96,7 @@ export const userVehiclesRelations = relations(userVehicles, ({ one }) => ({
|
|||||||
|
|
||||||
export const categoriesRelations = relations(categories, ({ one, many }) => ({
|
export const categoriesRelations = relations(categories, ({ one, many }) => ({
|
||||||
vehicle: one(vehicles, { fields: [categories.vehicleId], references: [vehicles.id] }),
|
vehicle: one(vehicles, { fields: [categories.vehicleId], references: [vehicles.id] }),
|
||||||
|
catalogVehicle: one(catalogVehicles, { fields: [categories.catalogVehicleId], references: [catalogVehicles.id] }),
|
||||||
parent: one(categories, {
|
parent: one(categories, {
|
||||||
fields: [categories.parentId],
|
fields: [categories.parentId],
|
||||||
references: [categories.id],
|
references: [categories.id],
|
||||||
@@ -100,6 +109,7 @@ export const categoriesRelations = relations(categories, ({ one, many }) => ({
|
|||||||
|
|
||||||
export const partsRelations = relations(parts, ({ one }) => ({
|
export const partsRelations = relations(parts, ({ one }) => ({
|
||||||
vehicle: one(vehicles, { fields: [parts.vehicleId], references: [vehicles.id] }),
|
vehicle: one(vehicles, { fields: [parts.vehicleId], references: [vehicles.id] }),
|
||||||
|
catalogVehicle: one(catalogVehicles, { fields: [parts.catalogVehicleId], references: [catalogVehicles.id] }),
|
||||||
category: one(categories, { fields: [parts.categoryId], references: [categories.id] }),
|
category: one(categories, { fields: [parts.categoryId], references: [categories.id] }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -4,33 +4,43 @@ import postgres from "postgres";
|
|||||||
import { brands, plans, users, accounts } from "./schema/core";
|
import { brands, plans, users, accounts } from "./schema/core";
|
||||||
|
|
||||||
const BRANDS_DATA = [
|
const BRANDS_DATA = [
|
||||||
{ name: "BMW", slug: "bmw" },
|
// Mevcut markalar
|
||||||
{ name: "Mercedes-Benz", slug: "mercedes-benz" },
|
|
||||||
{ name: "Audi", slug: "audi" },
|
{ name: "Audi", slug: "audi" },
|
||||||
{ name: "Volkswagen", slug: "volkswagen" },
|
{ name: "BMW", slug: "bmw" },
|
||||||
{ name: "Fiat", slug: "fiat" },
|
|
||||||
{ name: "Renault", slug: "renault" },
|
|
||||||
{ name: "Peugeot", slug: "peugeot" },
|
|
||||||
{ name: "Citroen", slug: "citroen" },
|
{ name: "Citroen", slug: "citroen" },
|
||||||
{ name: "Toyota", slug: "toyota" },
|
{ name: "Dacia", slug: "dacia" },
|
||||||
|
{ name: "Fiat", slug: "fiat" },
|
||||||
|
{ name: "Ford", slug: "ford" },
|
||||||
{ name: "Honda", slug: "honda" },
|
{ name: "Honda", slug: "honda" },
|
||||||
{ name: "Hyundai", slug: "hyundai" },
|
{ name: "Hyundai", slug: "hyundai" },
|
||||||
{ name: "Kia", slug: "kia" },
|
|
||||||
{ name: "Ford", slug: "ford" },
|
|
||||||
{ name: "Opel", slug: "opel" },
|
|
||||||
{ name: "Skoda", slug: "skoda" },
|
|
||||||
{ name: "Seat", slug: "seat" },
|
|
||||||
{ name: "Volvo", slug: "volvo" },
|
|
||||||
{ name: "Nissan", slug: "nissan" },
|
|
||||||
{ name: "Mazda", slug: "mazda" },
|
|
||||||
{ name: "Porsche", slug: "porsche" },
|
|
||||||
{ name: "Land Rover", slug: "land-rover" },
|
|
||||||
{ name: "Jaguar", slug: "jaguar" },
|
{ name: "Jaguar", slug: "jaguar" },
|
||||||
|
{ name: "Kia", slug: "kia" },
|
||||||
|
{ name: "Land Rover", slug: "land-rover" },
|
||||||
|
{ name: "Mazda", slug: "mazda" },
|
||||||
|
{ name: "Mercedes-Benz", slug: "mercedes-benz" },
|
||||||
{ name: "Mini", slug: "mini" },
|
{ name: "Mini", slug: "mini" },
|
||||||
{ name: "Dacia", slug: "dacia" },
|
{ name: "Mitsubishi", slug: "mitsubishi" },
|
||||||
|
{ name: "Nissan", slug: "nissan" },
|
||||||
|
{ name: "Opel", slug: "opel" },
|
||||||
|
{ name: "Peugeot", slug: "peugeot" },
|
||||||
|
{ name: "Porsche", slug: "porsche" },
|
||||||
|
{ name: "Renault", slug: "renault" },
|
||||||
|
{ name: "Seat", slug: "seat" },
|
||||||
|
{ name: "Skoda", slug: "skoda" },
|
||||||
{ name: "Subaru", slug: "subaru" },
|
{ name: "Subaru", slug: "subaru" },
|
||||||
{ name: "Suzuki", slug: "suzuki" },
|
{ name: "Suzuki", slug: "suzuki" },
|
||||||
{ name: "Mitsubishi", slug: "mitsubishi" },
|
{ name: "Toyota", slug: "toyota" },
|
||||||
|
{ name: "Volkswagen", slug: "volkswagen" },
|
||||||
|
{ name: "Volvo", slug: "volvo" },
|
||||||
|
// PL24 kataloglarında olan, sase.tr'ye eklenen markalar
|
||||||
|
{ name: "Alpine", slug: "alpine" },
|
||||||
|
{ name: "Bentley", slug: "bentley" },
|
||||||
|
{ name: "Cupra", slug: "cupra" },
|
||||||
|
{ name: "Infiniti", slug: "infiniti" },
|
||||||
|
{ name: "Lexus", slug: "lexus" },
|
||||||
|
{ name: "MAN", slug: "man" },
|
||||||
|
{ name: "Polestar", slug: "polestar" },
|
||||||
|
{ name: "Smart", slug: "smart" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const PLANS_DATA = [
|
const PLANS_DATA = [
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
getServiceApiPath,
|
getServiceApiPath,
|
||||||
getServiceConfig,
|
getServiceConfig,
|
||||||
isP5Modern,
|
isP5Modern,
|
||||||
|
isLegacyArchitecture,
|
||||||
SERVICE_TO_BRAND,
|
SERVICE_TO_BRAND,
|
||||||
} from "./pl24.types";
|
} from "./pl24.types";
|
||||||
|
|
||||||
@@ -76,14 +77,12 @@ export class PL24Service {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch legacy architectures to their dedicated services
|
// Dispatch P4 legacy architectures to the generic legacy service
|
||||||
if (!isP5Modern(serviceName)) {
|
if (!isP5Modern(serviceName)) {
|
||||||
if (serviceName === "fordt_parts") {
|
if (isLegacyArchitecture(serviceName)) {
|
||||||
return this.fordLegacyService.decodeVin(cleanVin);
|
return this.fordLegacyService.decodeVinForService(cleanVin, serviceName);
|
||||||
}
|
}
|
||||||
this.logger.warn(
|
this.logger.warn(`Unknown architecture for service: ${serviceName}`);
|
||||||
`Legacy architecture not supported yet: ${serviceName}`,
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,11 +254,18 @@ export class PL24Service {
|
|||||||
async fetchPartsByPath(
|
async fetchPartsByPath(
|
||||||
linkPath: string,
|
linkPath: string,
|
||||||
serviceName: string,
|
serviceName: string,
|
||||||
|
body?: string,
|
||||||
|
engine?: string,
|
||||||
|
gearbox?: string,
|
||||||
): Promise<PL24PartsResponse> {
|
): Promise<PL24PartsResponse> {
|
||||||
// Ford legacy dispatch
|
// Ford legacy dispatch
|
||||||
if (this.isFordLegacyPath(linkPath)) {
|
if (this.isP4LegacyPath(linkPath)) {
|
||||||
return this.fordLegacyService.fetchPartsByPath(linkPath, serviceName);
|
return this.fordLegacyService.fetchPartsByPath(linkPath, serviceName);
|
||||||
}
|
}
|
||||||
|
// PSA image-board dispatch
|
||||||
|
if (this.isPsaBoardPath(linkPath)) {
|
||||||
|
return this.fordLegacyService.fetchPsaParts(linkPath, serviceName, body, engine, gearbox);
|
||||||
|
}
|
||||||
|
|
||||||
await this.touchActivity();
|
await this.touchActivity();
|
||||||
const pathHash = createHash("sha256").update(linkPath).digest("hex").substring(0, 16);
|
const pathHash = createHash("sha256").update(linkPath).digest("hex").substring(0, 16);
|
||||||
@@ -378,11 +384,22 @@ export class PL24Service {
|
|||||||
async fetchSubGroupsByPath(
|
async fetchSubGroupsByPath(
|
||||||
linkPath: string,
|
linkPath: string,
|
||||||
serviceName: string,
|
serviceName: string,
|
||||||
|
body?: string,
|
||||||
|
engine?: string,
|
||||||
|
gearbox?: string,
|
||||||
): Promise<PL24MainGroup[]> {
|
): Promise<PL24MainGroup[]> {
|
||||||
// Ford legacy dispatch
|
// Ford legacy dispatch
|
||||||
if (this.isFordLegacyPath(linkPath)) {
|
if (this.isP4LegacyPath(linkPath)) {
|
||||||
return this.fordLegacyService.fetchSubGroupsByPath(linkPath, serviceName);
|
return this.fordLegacyService.fetchSubGroupsByPath(linkPath, serviceName);
|
||||||
}
|
}
|
||||||
|
// PSA scope dispatch ("psa::{svc}::scope=..." → main groups)
|
||||||
|
if (this.isPsaPath(linkPath)) {
|
||||||
|
return this.fordLegacyService.fetchPsaSubGroups(linkPath, body, engine, gearbox);
|
||||||
|
}
|
||||||
|
// PSA illustrations dispatch (/psa/.../json-illustrations.action → illustrations)
|
||||||
|
if (this.isPsaIllusPath(linkPath)) {
|
||||||
|
return this.fordLegacyService.fetchPsaIllustrations(linkPath, serviceName, body, engine, gearbox);
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.log(`Fetching sub-groups by path: ${linkPath}`);
|
this.logger.log(`Fetching sub-groups by path: ${linkPath}`);
|
||||||
await this.touchActivity();
|
await this.touchActivity();
|
||||||
@@ -406,6 +423,122 @@ export class PL24Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch category tree scopes for a PSA legacy catalog vehicle.
|
||||||
|
* Delegates to fordLegacyService which handles PSA HTML scraping flow.
|
||||||
|
*/
|
||||||
|
async fetchMainGroupsForPsa(
|
||||||
|
serviceName: string,
|
||||||
|
familyId: string,
|
||||||
|
salesTypeId: string,
|
||||||
|
mode: string,
|
||||||
|
upds: string,
|
||||||
|
body?: string,
|
||||||
|
engine?: string,
|
||||||
|
gearbox?: string,
|
||||||
|
): Promise<PL24DecodedCategory[]> {
|
||||||
|
return this.fordLegacyService.fetchMainGroupsForPsa(
|
||||||
|
serviceName,
|
||||||
|
familyId,
|
||||||
|
salesTypeId,
|
||||||
|
mode,
|
||||||
|
upds,
|
||||||
|
body,
|
||||||
|
engine,
|
||||||
|
gearbox,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch body types for a PSA catalog vehicle variant selector.
|
||||||
|
*/
|
||||||
|
async fetchPsaBodies(
|
||||||
|
svc: string,
|
||||||
|
familyId: string,
|
||||||
|
salesTypeId: string,
|
||||||
|
mode: string,
|
||||||
|
upds: string,
|
||||||
|
): Promise<{ code: string; name: string }[]> {
|
||||||
|
return this.fordLegacyService.fetchPsaBodies(svc, familyId, salesTypeId, mode, upds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch engines for a PSA catalog vehicle given a selected body code.
|
||||||
|
*/
|
||||||
|
async fetchPsaEnginesForBody(
|
||||||
|
svc: string,
|
||||||
|
familyId: string,
|
||||||
|
salesTypeId: string,
|
||||||
|
bodyCode: string,
|
||||||
|
mode: string,
|
||||||
|
upds: string,
|
||||||
|
): Promise<{ code: string; name: string }[]> {
|
||||||
|
return this.fordLegacyService.fetchPsaEnginesForBody(svc, familyId, salesTypeId, bodyCode, mode, upds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch gearboxes for a PSA catalog vehicle given selected body + engine codes.
|
||||||
|
*/
|
||||||
|
async fetchPsaGearboxes(
|
||||||
|
svc: string,
|
||||||
|
familyId: string,
|
||||||
|
salesTypeId: string,
|
||||||
|
bodyCode: string,
|
||||||
|
engineCode: string,
|
||||||
|
mode: string,
|
||||||
|
upds: string,
|
||||||
|
): Promise<{ code: string; name: string }[]> {
|
||||||
|
return this.fordLegacyService.fetchPsaGearboxes(svc, familyId, salesTypeId, bodyCode, engineCode, mode, upds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch model config (variant options) for a Ford catalog vehicle.
|
||||||
|
*/
|
||||||
|
async fetchFordModelConfig(
|
||||||
|
svc: string,
|
||||||
|
familyId: string,
|
||||||
|
mode: string,
|
||||||
|
upds: string,
|
||||||
|
): Promise<{
|
||||||
|
modelYears: { code: string; name: string }[];
|
||||||
|
engines: { code: string; name: string }[];
|
||||||
|
gearboxes: { code: string; name: string }[];
|
||||||
|
}> {
|
||||||
|
return this.fordLegacyService.fetchFordModelConfig(svc, familyId, mode, upds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch model config (year variant options) for a Volvo catalog vehicle.
|
||||||
|
*/
|
||||||
|
async fetchVolvoModelConfig(
|
||||||
|
svc: string,
|
||||||
|
mdlId: string,
|
||||||
|
mode: string,
|
||||||
|
upds: string,
|
||||||
|
): Promise<{
|
||||||
|
modelYears: { code: string; name: string }[];
|
||||||
|
engines: { code: string; name: string }[];
|
||||||
|
gearboxes: { code: string; name: string }[];
|
||||||
|
}> {
|
||||||
|
return this.fordLegacyService.fetchVolvoModelConfig(svc, mdlId, mode, upds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch main category groups for a Ford catalog vehicle variant.
|
||||||
|
*/
|
||||||
|
async fetchFordMainGroups(
|
||||||
|
svc: string,
|
||||||
|
familyId: string,
|
||||||
|
modelYear: string,
|
||||||
|
engine: string,
|
||||||
|
gearbox: string,
|
||||||
|
mode: string,
|
||||||
|
upds: string,
|
||||||
|
catCode?: string,
|
||||||
|
): Promise<PL24DecodedCategory[]> {
|
||||||
|
return this.fordLegacyService.fetchFordMainGroups(svc, familyId, modelYear, engine, gearbox, mode, upds, catCode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-fetch main groups using a stored mainGroupsPath.
|
* Re-fetch main groups using a stored mainGroupsPath.
|
||||||
*/
|
*/
|
||||||
@@ -414,6 +547,21 @@ export class PL24Service {
|
|||||||
mainGroupsPath: string,
|
mainGroupsPath: string,
|
||||||
): Promise<PL24DecodedCategory[]> {
|
): Promise<PL24DecodedCategory[]> {
|
||||||
await this.touchActivity();
|
await this.touchActivity();
|
||||||
|
// Ford legacy catalog vehicles store the vehicle.action URL as catalogPath.
|
||||||
|
// Dispatch to fordLegacyService which fetches and extracts group links from the HTML.
|
||||||
|
if (this.isP4LegacyPath(mainGroupsPath)) {
|
||||||
|
const groups = await this.fordLegacyService.fetchSubGroupsByPath(mainGroupsPath, serviceName);
|
||||||
|
return groups.map((g) => ({
|
||||||
|
code: g.code,
|
||||||
|
nameEn: g.name,
|
||||||
|
nameTr: g.name,
|
||||||
|
description: g.description || null,
|
||||||
|
iconUrl: g.iconUrl || null,
|
||||||
|
subGroups: [],
|
||||||
|
linkPath: g.linkPath,
|
||||||
|
linkWid: g.linkWid,
|
||||||
|
}));
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await this.authService.authorizeService(serviceName);
|
await this.authService.authorizeService(serviceName);
|
||||||
const headers = await this.authService.buildAuthHeaders(serviceName);
|
const headers = await this.authService.buildAuthHeaders(serviceName);
|
||||||
@@ -553,6 +701,15 @@ export class PL24Service {
|
|||||||
return isP5Modern(serviceName) || serviceName === "fordt_parts";
|
return isP5Modern(serviceName) || serviceName === "fordt_parts";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this VIN's WMI maps to any PL24 service (P5 Modern or P4 Legacy).
|
||||||
|
* Use this to gate VIN decode attempts; use isSupported() for catalog browser eligibility.
|
||||||
|
*/
|
||||||
|
isDecodeable(vin: string): boolean {
|
||||||
|
if (!vin || vin.length < 3) return false;
|
||||||
|
return !!this.getServiceName(vin);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get supported brands list.
|
* Get supported brands list.
|
||||||
*/
|
*/
|
||||||
@@ -1017,7 +1174,9 @@ export class PL24Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const partRecords = records.filter(
|
const partRecords = records.filter(
|
||||||
(record) => record.characteristic !== "sectionrow" && record.partno,
|
(record) =>
|
||||||
|
record.characteristic !== "sectionrow" &&
|
||||||
|
(record.partno || (record.values as Record<string, unknown>)?.partno),
|
||||||
);
|
);
|
||||||
|
|
||||||
return partRecords.map((part) => {
|
return partRecords.map((part) => {
|
||||||
@@ -1152,7 +1311,9 @@ export class PL24Service {
|
|||||||
const mercedesMatch = imageUrl.match(/[?&]illu=([a-zA-Z0-9_]+)/);
|
const mercedesMatch = imageUrl.match(/[?&]illu=([a-zA-Z0-9_]+)/);
|
||||||
if (mercedesMatch) return mercedesMatch[1];
|
if (mercedesMatch) return mercedesMatch[1];
|
||||||
|
|
||||||
return null;
|
// PSA and other legacy brands use ticket-based URLs that don't match above patterns.
|
||||||
|
// Fall back to a hash of the URL so caching still works.
|
||||||
|
return createHash("sha256").update(imageUrl).digest("hex").substring(0, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== PRIVATE: Brand-specific flows ====================
|
// ==================== PRIVATE: Brand-specific flows ====================
|
||||||
@@ -1183,8 +1344,20 @@ export class PL24Service {
|
|||||||
return `${url.pathname}?${url.searchParams.toString()}`;
|
return `${url.pathname}?${url.searchParams.toString()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isFordLegacyPath(linkPath: string): boolean {
|
private isP4LegacyPath(linkPath: string): boolean {
|
||||||
return linkPath.includes("/ford/") && linkPath.includes(".action");
|
return linkPath.includes(".action");
|
||||||
|
}
|
||||||
|
|
||||||
|
private isPsaPath(linkPath: string): boolean {
|
||||||
|
return linkPath.startsWith("psa::");
|
||||||
|
}
|
||||||
|
|
||||||
|
private isPsaIllusPath(linkPath: string): boolean {
|
||||||
|
return linkPath.includes("/psa/") && linkPath.includes("json-illustrations.action");
|
||||||
|
}
|
||||||
|
|
||||||
|
private isPsaBoardPath(linkPath: string): boolean {
|
||||||
|
return linkPath.includes("/psa/") && linkPath.includes("image-board.action");
|
||||||
}
|
}
|
||||||
|
|
||||||
private isDaimlerService(serviceName: string): boolean {
|
private isDaimlerService(serviceName: string): boolean {
|
||||||
@@ -1540,6 +1713,237 @@ export class PL24Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== PUBLIC: Catalog browse (VIN-less) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a list of vehicles/models for a service (VIN-less catalog browse).
|
||||||
|
* Tries P5 Modern selection wizard endpoints.
|
||||||
|
* Returns empty array if unavailable (requires discovery to find correct endpoint).
|
||||||
|
*/
|
||||||
|
async fetchVehicleList(serviceName: string): Promise<
|
||||||
|
Array<{
|
||||||
|
vehicleId: string;
|
||||||
|
model: string;
|
||||||
|
year?: string;
|
||||||
|
engine?: string;
|
||||||
|
bodyType?: string;
|
||||||
|
transmission?: string;
|
||||||
|
market?: string;
|
||||||
|
catalogPath?: string;
|
||||||
|
metadata?: Record<string, unknown>;
|
||||||
|
}>
|
||||||
|
> {
|
||||||
|
await this.touchActivity();
|
||||||
|
|
||||||
|
// Legacy architecture dispatch
|
||||||
|
const serviceConfig = getServiceConfig(serviceName);
|
||||||
|
if (serviceConfig?.architecture === "LEGACY_PSA") {
|
||||||
|
return this.fordLegacyService.fetchVehicleListForPsa(serviceName);
|
||||||
|
}
|
||||||
|
if (serviceConfig?.architecture === "LEGACY_FORD") {
|
||||||
|
return this.fordLegacyService.fetchVehicleListForFord(serviceName);
|
||||||
|
}
|
||||||
|
if (serviceConfig?.architecture === "LEGACY_HYUNDAI_KIA") {
|
||||||
|
return this.fordLegacyService.fetchVehicleListForHyundaiKia(serviceName);
|
||||||
|
}
|
||||||
|
if (serviceConfig?.architecture === "LEGACY_NISSAN") {
|
||||||
|
return this.fordLegacyService.fetchVehicleListForNissan(serviceName);
|
||||||
|
}
|
||||||
|
if (serviceConfig?.architecture === "LEGACY_OPEL") {
|
||||||
|
return this.fordLegacyService.fetchVehicleListForOpel(serviceName);
|
||||||
|
}
|
||||||
|
if (serviceConfig?.architecture === "LEGACY_VOLVO") {
|
||||||
|
return this.fordLegacyService.fetchVehicleListForVolvo(serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheKey = `${PL24_DEFAULTS.CACHE_PREFIX}vehicle_list:${serviceName}`;
|
||||||
|
const cached = await this.redis.getJson<any[]>(cacheKey);
|
||||||
|
if (cached) return cached;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.authService.authorizeService(serviceName);
|
||||||
|
const headers = await this.authService.buildAuthHeaders(serviceName);
|
||||||
|
|
||||||
|
const catalogBase = getServiceApiPath(serviceName);
|
||||||
|
|
||||||
|
// Discovered via Playwright explorer (scripts/pl24-catalog-explorer.js → docs/pl24-catalog/*.md)
|
||||||
|
// Each P5 backend uses a different initial model listing endpoint
|
||||||
|
const BACKEND_MODEL_PATH: Record<string, string> = {
|
||||||
|
p5vwag: "/extern/vehicle/modelfamilies", // VW, Audi, Skoda, SEAT, Cupra, Porsche, Bentley
|
||||||
|
p5bmw: "/extern/vehicle/models", // BMW, MINI, Motorrad
|
||||||
|
p5daimler: "/extern/vehicle/scope", // Mercedes-Benz, smart
|
||||||
|
p5renault: "/extern/vehicle/catalogs", // Renault, Dacia, Alpine
|
||||||
|
p5jlr: "/extern/vehicle/models", // Jaguar, Land Rover
|
||||||
|
p5toyota: "/extern/vehicle/modelFamilies", // Toyota, Lexus (capital F)
|
||||||
|
p5mitsubishi: "/extern/vehicles/vehiclesOverview", // Mitsubishi
|
||||||
|
p5suzuki: "/extern/vehicle/modelFamilies", // Suzuki
|
||||||
|
p5man: "/extern/model/categories", // MAN trucks
|
||||||
|
};
|
||||||
|
|
||||||
|
// catalogBase is like "/p5vwag" — strip leading slash for map lookup
|
||||||
|
const backendKey = catalogBase.replace(/^\//, "");
|
||||||
|
const modelPath = BACKEND_MODEL_PATH[backendKey] ?? "/extern/vehicle/modelfamilies";
|
||||||
|
|
||||||
|
const url = `${this.baseUrl}${catalogBase}${modelPath}?lang=${this.language}&serviceName=${serviceName}`;
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers,
|
||||||
|
signal: AbortSignal.timeout(15000),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = (await response.json()) as Record<string, any>;
|
||||||
|
let vehicles = this.parseVehicleListResponse(data, serviceName);
|
||||||
|
|
||||||
|
// p5daimler "scope" endpoint returns 1 record whose link.path points to "modeltype" (Smart).
|
||||||
|
// Follow that link to retrieve the actual model type list (C450–C454).
|
||||||
|
if (vehicles.length === 1 && vehicles[0].catalogPath?.includes("modeltype")) {
|
||||||
|
const modeltypePath = vehicles[0].catalogPath;
|
||||||
|
const modeltypeUrl = modeltypePath.startsWith("http")
|
||||||
|
? modeltypePath
|
||||||
|
: `${this.baseUrl}${modeltypePath}`;
|
||||||
|
try {
|
||||||
|
const modeltypeResp = await fetch(modeltypeUrl, {
|
||||||
|
method: "GET",
|
||||||
|
headers,
|
||||||
|
signal: AbortSignal.timeout(15000),
|
||||||
|
});
|
||||||
|
if (modeltypeResp.ok) {
|
||||||
|
const modeltypeData = (await modeltypeResp.json()) as Record<string, any>;
|
||||||
|
const modeltypeVehicles = this.parseVehicleListResponse(modeltypeData, serviceName);
|
||||||
|
if (modeltypeVehicles.length > 0) {
|
||||||
|
this.logger.log(`Smart: modeltype returned ${modeltypeVehicles.length} models`);
|
||||||
|
vehicles = modeltypeVehicles;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.logger.warn(`Smart: modeltype HTTP ${modeltypeResp.status}`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.warn(`Smart: modeltype fetch failed: ${(err as Error).message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vehicles.length > 0) {
|
||||||
|
await this.redis.setJson(cacheKey, vehicles, 86400); // 24h
|
||||||
|
return vehicles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.log(`No vehicle list available for ${serviceName} (HTTP ${response.status})`);
|
||||||
|
return [];
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.warn(`fetchVehicleList failed for ${serviceName}: ${(err as Error).message}`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseVehicleListResponse(
|
||||||
|
data: Record<string, any>,
|
||||||
|
serviceName: string,
|
||||||
|
): Array<{
|
||||||
|
vehicleId: string;
|
||||||
|
model: string;
|
||||||
|
year?: string;
|
||||||
|
engine?: string;
|
||||||
|
bodyType?: string;
|
||||||
|
transmission?: string;
|
||||||
|
market?: string;
|
||||||
|
catalogPath?: string;
|
||||||
|
metadata?: Record<string, unknown>;
|
||||||
|
}> {
|
||||||
|
let records: any[] = [];
|
||||||
|
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
records = data;
|
||||||
|
} else if (Array.isArray(data.data?.records)) {
|
||||||
|
records = data.data.records;
|
||||||
|
} else if (Array.isArray(data.vehicles)) {
|
||||||
|
records = data.vehicles;
|
||||||
|
} else if (Array.isArray(data.models)) {
|
||||||
|
records = data.models;
|
||||||
|
} else if (Array.isArray(data.data)) {
|
||||||
|
records = data.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return records
|
||||||
|
.filter((r) => r.id || r.vehicleId || r.vid)
|
||||||
|
.map((r) => {
|
||||||
|
const values = r.values || {};
|
||||||
|
const vehicleId = String(r.id || r.vehicleId || r.vid || "");
|
||||||
|
// modelfamilies uses values.caption; older formats use values.model / r.description
|
||||||
|
const model =
|
||||||
|
values.caption || values.model || values.description || r.description || r.name || vehicleId;
|
||||||
|
const link = r.link || {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
vehicleId,
|
||||||
|
model,
|
||||||
|
year: values.year || values.modelYear || r.year || undefined,
|
||||||
|
engine: values.engine || values.engineCode || undefined,
|
||||||
|
bodyType: values.bodyType || values.body || undefined,
|
||||||
|
transmission: values.transmission || undefined,
|
||||||
|
market: values.market || undefined,
|
||||||
|
catalogPath: link.path || undefined,
|
||||||
|
metadata: r,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explore a P5 Modern service catalog — tries various endpoints and returns raw results.
|
||||||
|
* Used by admin endpoint for discovery.
|
||||||
|
*/
|
||||||
|
async exploreP5Service(serviceName: string): Promise<Record<string, any>> {
|
||||||
|
await this.touchActivity();
|
||||||
|
const results: Record<string, any> = {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.authService.authorizeService(serviceName);
|
||||||
|
const headers = await this.authService.buildAuthHeaders(serviceName);
|
||||||
|
const catalogBase = getServiceApiPath(serviceName);
|
||||||
|
|
||||||
|
const probeEndpoints = [
|
||||||
|
"extern/vehicles",
|
||||||
|
"extern/vehicleList",
|
||||||
|
"extern/models",
|
||||||
|
"extern/selection/vehicles",
|
||||||
|
"extern/selection/rootNode",
|
||||||
|
"extern/catalogs",
|
||||||
|
"extern/modelSeries",
|
||||||
|
];
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
probeEndpoints.map(async (endpoint) => {
|
||||||
|
const url = `${this.baseUrl}${catalogBase}/${endpoint}?lang=${this.language}&serviceName=${serviceName}`;
|
||||||
|
try {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers,
|
||||||
|
signal: AbortSignal.timeout(8000),
|
||||||
|
});
|
||||||
|
const status = response.status;
|
||||||
|
let body: any = null;
|
||||||
|
if (response.ok) {
|
||||||
|
try {
|
||||||
|
body = await response.json();
|
||||||
|
} catch {
|
||||||
|
body = await response.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results[endpoint] = { status, body: body ? JSON.stringify(body).substring(0, 2000) : null };
|
||||||
|
} catch (err) {
|
||||||
|
results[endpoint] = { error: (err as Error).message };
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
results._authError = (err as Error).message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
private parseJlrIllustrations(
|
private parseJlrIllustrations(
|
||||||
response: unknown,
|
response: unknown,
|
||||||
): Array<{ btnr: number; name: string; code: string }> {
|
): Array<{ btnr: number; name: string; code: string }> {
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ export const PL24_SERVICE_CATALOGS: Record<string, PL24CatalogConfig> = {
|
|||||||
// Mitsubishi
|
// Mitsubishi
|
||||||
mmc_parts: {
|
mmc_parts: {
|
||||||
basePath: "/pl24-app/mmc_parts",
|
basePath: "/pl24-app/mmc_parts",
|
||||||
apiPath: "/p5mmc",
|
apiPath: "/p5mitsubishi",
|
||||||
architecture: "P5_MODERN",
|
architecture: "P5_MODERN",
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -287,12 +287,84 @@ export const PL24_SERVICE_CATALOGS: Record<string, PL24CatalogConfig> = {
|
|||||||
architecture: "P5_MODERN",
|
architecture: "P5_MODERN",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Ford
|
// ==================== LEGACY P4 ARCHITECTURE ====================
|
||||||
fordt_parts: {
|
|
||||||
basePath: "/ford/fordt_parts",
|
// PSA Group (Citroën, Peugeot)
|
||||||
apiPath: "/ford/fordt_parts",
|
citroen_parts: {
|
||||||
|
basePath: "/psa",
|
||||||
|
apiPath: "/psa",
|
||||||
|
architecture: "LEGACY_PSA",
|
||||||
|
},
|
||||||
|
citroenDs_parts: {
|
||||||
|
basePath: "/psa",
|
||||||
|
apiPath: "/psa",
|
||||||
|
architecture: "LEGACY_PSA",
|
||||||
|
},
|
||||||
|
peugeot_parts: {
|
||||||
|
basePath: "/psa",
|
||||||
|
apiPath: "/psa",
|
||||||
|
architecture: "LEGACY_PSA",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Ford Group
|
||||||
|
fordp_parts: {
|
||||||
|
basePath: "/ford",
|
||||||
|
apiPath: "/ford",
|
||||||
architecture: "LEGACY_FORD",
|
architecture: "LEGACY_FORD",
|
||||||
},
|
},
|
||||||
|
fordt_parts: {
|
||||||
|
basePath: "/ford",
|
||||||
|
apiPath: "/ford",
|
||||||
|
architecture: "LEGACY_FORD",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hyundai-Kia Automotive Group
|
||||||
|
hyundai_parts: {
|
||||||
|
basePath: "/hyundai-kia-automotive-group",
|
||||||
|
apiPath: "/hyundai-kia-automotive-group",
|
||||||
|
architecture: "LEGACY_HYUNDAI_KIA",
|
||||||
|
},
|
||||||
|
kia_parts: {
|
||||||
|
basePath: "/hyundai-kia-automotive-group",
|
||||||
|
apiPath: "/hyundai-kia-automotive-group",
|
||||||
|
architecture: "LEGACY_HYUNDAI_KIA",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Nissan/Infiniti
|
||||||
|
nissan_parts: {
|
||||||
|
basePath: "/nissan",
|
||||||
|
apiPath: "/nissan",
|
||||||
|
architecture: "LEGACY_NISSAN",
|
||||||
|
},
|
||||||
|
infiniti_parts: {
|
||||||
|
basePath: "/nissan",
|
||||||
|
apiPath: "/nissan",
|
||||||
|
architecture: "LEGACY_NISSAN",
|
||||||
|
},
|
||||||
|
|
||||||
|
// GM / Stellantis (Opel, Vauxhall)
|
||||||
|
opel_parts: {
|
||||||
|
basePath: "/opel",
|
||||||
|
apiPath: "/opel",
|
||||||
|
architecture: "LEGACY_OPEL",
|
||||||
|
},
|
||||||
|
vauxhall_parts: {
|
||||||
|
basePath: "/opel",
|
||||||
|
apiPath: "/opel",
|
||||||
|
architecture: "LEGACY_OPEL",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Volvo/Polestar
|
||||||
|
volvo_parts: {
|
||||||
|
basePath: "/volvo",
|
||||||
|
apiPath: "/volvo",
|
||||||
|
architecture: "LEGACY_VOLVO",
|
||||||
|
},
|
||||||
|
polestar_parts: {
|
||||||
|
basePath: "/volvo",
|
||||||
|
apiPath: "/volvo",
|
||||||
|
architecture: "LEGACY_VOLVO",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== HELPER FUNCTIONS ====================
|
// ==================== HELPER FUNCTIONS ====================
|
||||||
@@ -436,11 +508,43 @@ export const PL24_WMI_SERVICE_MAP: Record<string, string> = {
|
|||||||
MA3: "suzuki_parts",
|
MA3: "suzuki_parts",
|
||||||
MBH: "suzuki_parts",
|
MBH: "suzuki_parts",
|
||||||
|
|
||||||
// Ford
|
// Ford Commercial (Transit vans — Turkey Otosan, etc.)
|
||||||
NM0: "fordt_parts",
|
NM0: "fordt_parts",
|
||||||
WF0: "fordt_parts",
|
|
||||||
"1FA": "fordt_parts",
|
// Ford Passenger (European passenger cars — Germany Cologne plant)
|
||||||
"3FA": "fordt_parts",
|
WF0: "fordp_parts",
|
||||||
|
"1FA": "fordp_parts",
|
||||||
|
"3FA": "fordp_parts",
|
||||||
|
|
||||||
|
// Hyundai
|
||||||
|
KMH: "hyundai_parts", // Hyundai Korea Motor House
|
||||||
|
TMK: "hyundai_parts", // Hyundai (Turkey/other markets)
|
||||||
|
|
||||||
|
// Kia
|
||||||
|
KNA: "kia_parts", // Kia (worldwide production)
|
||||||
|
U5Y: "kia_parts", // Kia Slovakia
|
||||||
|
|
||||||
|
// Nissan
|
||||||
|
JN1: "nissan_parts", // Nissan Japan (passenger)
|
||||||
|
JN6: "nissan_parts", // Nissan Japan (pickup/van)
|
||||||
|
JN8: "nissan_parts", // Nissan Japan (SUV)
|
||||||
|
VNK: "nissan_parts", // Nissan UK/Europe
|
||||||
|
|
||||||
|
// Infiniti
|
||||||
|
JNK: "infiniti_parts", // Infiniti (Japan/Korea)
|
||||||
|
|
||||||
|
// Opel / Vauxhall
|
||||||
|
W0L: "opel_parts", // Opel AG (Germany)
|
||||||
|
|
||||||
|
// Citroën (PSA)
|
||||||
|
VF7: "citroen_parts", // Citroën SA (France)
|
||||||
|
|
||||||
|
// Peugeot (PSA)
|
||||||
|
VF3: "peugeot_parts", // Peugeot SA (France)
|
||||||
|
|
||||||
|
// Volvo
|
||||||
|
YV1: "volvo_parts", // Volvo Cars (Sweden)
|
||||||
|
YV4: "volvo_parts", // Volvo Cars (specific models)
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== VEHICLE TYPES ====================
|
// ==================== VEHICLE TYPES ====================
|
||||||
@@ -451,6 +555,11 @@ export interface PL24CatalogInfo {
|
|||||||
catalogPath: string;
|
catalogPath: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
mainGroupsPath?: string;
|
mainGroupsPath?: string;
|
||||||
|
// PSA VIN decode session parameters (set by decodeVinPsa)
|
||||||
|
psaFamilyId?: string;
|
||||||
|
psaSalesTypeId?: string;
|
||||||
|
psaMode?: string;
|
||||||
|
psaUpds?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PL24MainGroup {
|
export interface PL24MainGroup {
|
||||||
@@ -518,6 +627,8 @@ export interface PL24PartsResponse {
|
|||||||
groupId: string;
|
groupId: string;
|
||||||
groupName: string;
|
groupName: string;
|
||||||
schemaImageUrl?: string;
|
schemaImageUrl?: string;
|
||||||
|
schemaImageBuffer?: Buffer; // pre-downloaded buffer (PSA: ticket URLs expire quickly)
|
||||||
|
schemaImageContentType?: string;
|
||||||
schemaWidth?: number;
|
schemaWidth?: number;
|
||||||
schemaHeight?: number;
|
schemaHeight?: number;
|
||||||
parts: PL24Part[];
|
parts: PL24Part[];
|
||||||
@@ -589,37 +700,96 @@ export interface PL24DecodedPart {
|
|||||||
// ==================== BRAND MAP ====================
|
// ==================== BRAND MAP ====================
|
||||||
|
|
||||||
export const SERVICE_TO_BRAND: Record<string, string> = {
|
export const SERVICE_TO_BRAND: Record<string, string> = {
|
||||||
|
// Volkswagen Group
|
||||||
vw_parts: "Volkswagen",
|
vw_parts: "Volkswagen",
|
||||||
vwclassic_parts: "Volkswagen",
|
vwclassic_parts: "Volkswagen",
|
||||||
vn_parts: "Volkswagen",
|
vn_parts: "Volkswagen",
|
||||||
audi_parts: "Audi",
|
audi_parts: "Audi",
|
||||||
seat_parts: "SEAT",
|
seat_parts: "Seat",
|
||||||
cupra_parts: "Cupra",
|
cupra_parts: "Cupra",
|
||||||
skoda_parts: "Skoda",
|
skoda_parts: "Skoda",
|
||||||
bentley_parts: "Bentley",
|
bentley_parts: "Bentley",
|
||||||
|
// BMW Group
|
||||||
bmw_parts: "BMW",
|
bmw_parts: "BMW",
|
||||||
bmwclassic_parts: "BMW",
|
bmwclassic_parts: "BMW",
|
||||||
bmwmotorrad_parts: "BMW",
|
bmwmotorrad_parts: "BMW",
|
||||||
bmwmotorradclassic_parts: "BMW",
|
bmwmotorradclassic_parts: "BMW",
|
||||||
mini_parts: "MINI",
|
mini_parts: "Mini",
|
||||||
miniclassic_parts: "MINI",
|
miniclassic_parts: "Mini",
|
||||||
|
// Mercedes-Benz Group
|
||||||
mercedes_parts: "Mercedes-Benz",
|
mercedes_parts: "Mercedes-Benz",
|
||||||
mercedesclassic_parts: "Mercedes-Benz",
|
mercedesclassic_parts: "Mercedes-Benz",
|
||||||
mercedesvans_parts: "Mercedes-Benz",
|
mercedesvans_parts: "Mercedes-Benz",
|
||||||
mercedestrucks_parts: "Mercedes-Benz",
|
mercedestrucks_parts: "Mercedes-Benz",
|
||||||
mercedesunimog_parts: "Mercedes-Benz",
|
mercedesunimog_parts: "Mercedes-Benz",
|
||||||
smart_parts: "smart",
|
smart_parts: "Smart",
|
||||||
|
// Porsche (VAG backend)
|
||||||
porsche_parts: "Porsche",
|
porsche_parts: "Porsche",
|
||||||
porscheclassic_parts: "Porsche",
|
porscheclassic_parts: "Porsche",
|
||||||
|
// Toyota Group
|
||||||
toyota_parts: "Toyota",
|
toyota_parts: "Toyota",
|
||||||
lexus_parts: "Lexus",
|
lexus_parts: "Lexus",
|
||||||
|
// Renault Group
|
||||||
renault_parts: "Renault",
|
renault_parts: "Renault",
|
||||||
dacia_parts: "Dacia",
|
dacia_parts: "Dacia",
|
||||||
alpine_parts: "Alpine",
|
alpine_parts: "Alpine",
|
||||||
|
// Jaguar Land Rover
|
||||||
jaguar_parts: "Jaguar",
|
jaguar_parts: "Jaguar",
|
||||||
landrover_parts: "Land Rover",
|
landrover_parts: "Land Rover",
|
||||||
|
// Other P5
|
||||||
man_parts: "MAN",
|
man_parts: "MAN",
|
||||||
mmc_parts: "Mitsubishi",
|
mmc_parts: "Mitsubishi",
|
||||||
suzuki_parts: "Suzuki",
|
suzuki_parts: "Suzuki",
|
||||||
|
// PSA Group
|
||||||
|
citroen_parts: "Citroen",
|
||||||
|
citroenDs_parts: "Citroen",
|
||||||
|
peugeot_parts: "Peugeot",
|
||||||
|
// Ford Group
|
||||||
|
fordp_parts: "Ford",
|
||||||
fordt_parts: "Ford",
|
fordt_parts: "Ford",
|
||||||
|
// Hyundai-Kia Group
|
||||||
|
hyundai_parts: "Hyundai",
|
||||||
|
kia_parts: "Kia",
|
||||||
|
// Nissan/Infiniti
|
||||||
|
nissan_parts: "Nissan",
|
||||||
|
infiniti_parts: "Infiniti",
|
||||||
|
// GM / Stellantis
|
||||||
|
opel_parts: "Opel",
|
||||||
|
vauxhall_parts: "Opel",
|
||||||
|
// Volvo/Polestar
|
||||||
|
volvo_parts: "Volvo",
|
||||||
|
polestar_parts: "Polestar",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Display names for services that share a brand (multi-catalog brands)
|
||||||
|
export const SERVICE_DISPLAY_NAMES: Record<string, string> = {
|
||||||
|
// BMW Group
|
||||||
|
bmw_parts: "BMW",
|
||||||
|
bmwclassic_parts: "BMW Classic",
|
||||||
|
bmwmotorrad_parts: "BMW Motorrad",
|
||||||
|
bmwmotorradclassic_parts: "BMW Motorrad Classic",
|
||||||
|
mini_parts: "Mini",
|
||||||
|
miniclassic_parts: "Mini Classic",
|
||||||
|
// Mercedes-Benz Group
|
||||||
|
mercedes_parts: "Mercedes-Benz",
|
||||||
|
mercedesclassic_parts: "Mercedes-Benz Classic",
|
||||||
|
mercedesvans_parts: "Mercedes-Benz Vans",
|
||||||
|
mercedestrucks_parts: "Mercedes-Benz Trucks",
|
||||||
|
mercedesunimog_parts: "Mercedes-Benz Unimog",
|
||||||
|
// Volkswagen Group
|
||||||
|
vw_parts: "Volkswagen",
|
||||||
|
vwclassic_parts: "Volkswagen Classic",
|
||||||
|
vn_parts: "Volkswagen Nfz",
|
||||||
|
porsche_parts: "Porsche",
|
||||||
|
porscheclassic_parts: "Porsche Classic",
|
||||||
|
// Renault Group
|
||||||
|
renault_parts: "Renault",
|
||||||
|
dacia_parts: "Dacia",
|
||||||
|
alpine_parts: "Alpine",
|
||||||
|
// Ford
|
||||||
|
fordp_parts: "Ford",
|
||||||
|
fordt_parts: "Ford Ticari",
|
||||||
|
// Citroen
|
||||||
|
citroen_parts: "Citroen",
|
||||||
|
citroenDs_parts: "Citroen DS",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ export class PartsService {
|
|||||||
|
|
||||||
if (!category) throw new NotFoundException("Kategori bulunamadı");
|
if (!category) throw new NotFoundException("Kategori bulunamadı");
|
||||||
|
|
||||||
|
if (!category.vehicleId) {
|
||||||
|
return dbParts;
|
||||||
|
}
|
||||||
|
|
||||||
const [vehicle] = await this.db
|
const [vehicle] = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(vehicles)
|
.from(vehicles)
|
||||||
@@ -61,7 +65,7 @@ export class PartsService {
|
|||||||
name: p.name,
|
name: p.name,
|
||||||
nameOriginal: p.name,
|
nameOriginal: p.name,
|
||||||
description: p.description || null,
|
description: p.description || null,
|
||||||
quantity: p.quantity || null,
|
quantity: p.quantity ? (parseInt(String(p.quantity), 10) || null) : null,
|
||||||
position: p.positionCode || null,
|
position: p.positionCode || null,
|
||||||
hotspotIndex: p.hotspotId ? (() => {
|
hotspotIndex: p.hotspotId ? (() => {
|
||||||
const val = parseInt(p.hotspotId!, 10);
|
const val = parseInt(p.hotspotId!, 10);
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ export class SubscriptionsService {
|
|||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const endDate = new Date(now);
|
const endDate = new Date(now);
|
||||||
endDate.setDate(endDate.getDate() + 3);
|
endDate.setDate(endDate.getDate() + 7);
|
||||||
|
|
||||||
// Create trial subscription
|
// Create trial subscription
|
||||||
const [subscription] = await this.db
|
const [subscription] = await this.db
|
||||||
|
|||||||
@@ -165,13 +165,30 @@ export class VehiclesService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Public VIN preview — no auth, no DB save, no brand access check.
|
* Public VIN preview — no auth, no DB save, no brand access check.
|
||||||
* Uses resolveVin() which caches results in Redis for 5 minutes.
|
* Checks DB first, then Redis, then external API chain.
|
||||||
*/
|
*/
|
||||||
async previewVin(vin: string) {
|
async previewVin(vin: string) {
|
||||||
if (!isValidVin(vin)) {
|
if (!isValidVin(vin)) {
|
||||||
throw new BadRequestException("Geçersiz şase numarası");
|
throw new BadRequestException("Geçersiz şase numarası");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DB'de varsa direkt dön — dış API çağrısına gerek yok
|
||||||
|
const [existing] = await this.db
|
||||||
|
.select({
|
||||||
|
brandName: vehicles.brandName,
|
||||||
|
model: vehicles.model,
|
||||||
|
year: vehicles.year,
|
||||||
|
engine: vehicles.engine,
|
||||||
|
source: vehicles.source,
|
||||||
|
})
|
||||||
|
.from(vehicles)
|
||||||
|
.where(eq(vehicles.vin, vin))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
const resolved = await this.resolveVin(vin);
|
const resolved = await this.resolveVin(vin);
|
||||||
if (!resolved) {
|
if (!resolved) {
|
||||||
throw new BadRequestException("Şase numarası tanınamadı");
|
throw new BadRequestException("Şase numarası tanınamadı");
|
||||||
@@ -249,7 +266,7 @@ export class VehiclesService {
|
|||||||
|
|
||||||
// 3. PL24 (if PC had multiple results, or PC failed entirely)
|
// 3. PL24 (if PC had multiple results, or PC failed entirely)
|
||||||
let pl24Vehicle: any = null;
|
let pl24Vehicle: any = null;
|
||||||
if (this.pl24Service.isSupported(vin)) {
|
if (this.pl24Service.isDecodeable(vin)) {
|
||||||
try {
|
try {
|
||||||
pl24Vehicle = await this.pl24Service.decodeVin(vin);
|
pl24Vehicle = await this.pl24Service.decodeVin(vin);
|
||||||
if (!brandName && pl24Vehicle) {
|
if (!brandName && pl24Vehicle) {
|
||||||
|
|||||||
175
apps/web/src/components/catalog/ford-variant-selector.tsx
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { api } from "@/lib/api-client";
|
||||||
|
import { useTranslation } from "@/lib/i18n";
|
||||||
|
import { Button, Card, CardContent, CardHeader, CardTitle } from "@sase/ui";
|
||||||
|
import { Loader2 } from "lucide-react";
|
||||||
|
|
||||||
|
interface VariantItem {
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FordModelConfig {
|
||||||
|
modelYears: VariantItem[];
|
||||||
|
engines: VariantItem[];
|
||||||
|
gearboxes: VariantItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FordVariantSelectorProps {
|
||||||
|
vehicleId: string;
|
||||||
|
onSelect: (modelYear: string, engine: string, gearbox: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FordVariantSelector({ vehicleId, onSelect }: FordVariantSelectorProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [selectedYear, setSelectedYear] = useState<string | null>(null);
|
||||||
|
const [selectedEngine, setSelectedEngine] = useState<string | null>(null);
|
||||||
|
const [selectedGearbox, setSelectedGearbox] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const { data: config, isLoading } = useQuery<FordModelConfig>({
|
||||||
|
queryKey: ["ford-config", vehicleId],
|
||||||
|
queryFn: () => api.get<FordModelConfig>(`/catalog/vehicles/${vehicleId}/ford-config`),
|
||||||
|
enabled: !!vehicleId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modelYears = config?.modelYears ?? [];
|
||||||
|
const engines = config?.engines ?? [];
|
||||||
|
const gearboxes = config?.gearboxes ?? [];
|
||||||
|
|
||||||
|
const hasYears = modelYears.length > 0;
|
||||||
|
const hasEngines = engines.length > 0;
|
||||||
|
const hasGearboxes = gearboxes.length > 0;
|
||||||
|
|
||||||
|
const handleYearSelect = (code: string) => {
|
||||||
|
setSelectedYear(code);
|
||||||
|
setSelectedEngine(null);
|
||||||
|
setSelectedGearbox(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEngineSelect = (code: string) => {
|
||||||
|
setSelectedEngine(code);
|
||||||
|
setSelectedGearbox(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleGearboxSelect = (code: string) => {
|
||||||
|
setSelectedGearbox(code);
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasAny = hasYears || hasEngines || hasGearboxes;
|
||||||
|
const canProceed =
|
||||||
|
!hasAny || // No variants available — can always proceed
|
||||||
|
((!hasYears || !!selectedYear) &&
|
||||||
|
(!hasEngines || !!selectedEngine) &&
|
||||||
|
(!hasGearboxes || !!selectedGearbox));
|
||||||
|
|
||||||
|
const handleProceed = () => {
|
||||||
|
if (!canProceed) return;
|
||||||
|
// When no variants, use "_nor_" so hasVariant=true and variant selector is skipped
|
||||||
|
onSelect(selectedYear ?? "_nor_", selectedEngine ?? "_nor_", selectedGearbox ?? "_nor_");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-base">{t("catalog.fordVariant.title")}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-6">
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
|
<Loader2 className="size-4 animate-spin" />
|
||||||
|
{t("catalog.fordVariant.loading")}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{/* Model Year */}
|
||||||
|
{hasYears && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-sm font-medium">{t("catalog.fordVariant.modelYear")}</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{modelYears.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item.code}
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleYearSelect(item.code)}
|
||||||
|
className={`rounded-md border px-3 py-1.5 text-sm transition-colors ${
|
||||||
|
selectedYear === item.code
|
||||||
|
? "border-primary bg-primary text-primary-foreground"
|
||||||
|
: "border-border bg-background hover:bg-accent"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Engine — shown after year selected or if no years */}
|
||||||
|
{hasEngines && (!hasYears || selectedYear) && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-sm font-medium">{t("catalog.fordVariant.engine")}</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{engines.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item.code}
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleEngineSelect(item.code)}
|
||||||
|
className={`rounded-md border px-3 py-1.5 text-sm transition-colors ${
|
||||||
|
selectedEngine === item.code
|
||||||
|
? "border-primary bg-primary text-primary-foreground"
|
||||||
|
: "border-border bg-background hover:bg-accent"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Gearbox — shown after engine selected or if no engines */}
|
||||||
|
{hasGearboxes && (!hasYears || selectedYear) && (!hasEngines || selectedEngine) && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-sm font-medium">{t("catalog.fordVariant.gearbox")}</p>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{gearboxes.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item.code}
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleGearboxSelect(item.code)}
|
||||||
|
className={`rounded-md border px-3 py-1.5 text-sm transition-colors ${
|
||||||
|
selectedGearbox === item.code
|
||||||
|
? "border-primary bg-primary text-primary-foreground"
|
||||||
|
: "border-border bg-background hover:bg-accent"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* No config available — allow skipping */}
|
||||||
|
{!hasYears && !hasEngines && !hasGearboxes && (
|
||||||
|
<p className="text-sm text-muted-foreground">{t("catalog.fordVariant.noConfig")}</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Proceed button — only enabled when all required dimensions are selected */}
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button
|
||||||
|
onClick={handleProceed}
|
||||||
|
disabled={!canProceed}
|
||||||
|
className="w-full sm:w-auto"
|
||||||
|
>
|
||||||
|
{t("catalog.fordVariant.proceed")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
209
apps/web/src/components/catalog/psa-variant-selector.tsx
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { api } from "@/lib/api-client";
|
||||||
|
import { useTranslation } from "@/lib/i18n";
|
||||||
|
import { Button, Card, CardContent, CardHeader, CardTitle } from "@sase/ui";
|
||||||
|
import { Loader2 } from "lucide-react";
|
||||||
|
|
||||||
|
interface VariantItem {
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PsaVariantSelectorProps {
|
||||||
|
vehicleId: string;
|
||||||
|
onSelect: (body: string, engine: string, gearbox: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PsaVariantSelector({ vehicleId, onSelect }: PsaVariantSelectorProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [selectedBody, setSelectedBody] = useState<string | null>(null);
|
||||||
|
const [selectedEngine, setSelectedEngine] = useState<string | null>(null);
|
||||||
|
const [selectedGearbox, setSelectedGearbox] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const { data: bodies = [], isLoading: loadingBodies } = useQuery<VariantItem[]>({
|
||||||
|
queryKey: ["psa-bodies", vehicleId],
|
||||||
|
queryFn: () => api.get<VariantItem[]>(`/catalog/vehicles/${vehicleId}/psa-bodies`),
|
||||||
|
enabled: !!vehicleId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data: engines = [], isLoading: loadingEngines } = useQuery<VariantItem[]>({
|
||||||
|
queryKey: ["psa-engines", vehicleId, selectedBody],
|
||||||
|
queryFn: () =>
|
||||||
|
api.get<VariantItem[]>(
|
||||||
|
`/catalog/vehicles/${vehicleId}/psa-engines?body=${encodeURIComponent(selectedBody!)}`,
|
||||||
|
),
|
||||||
|
enabled: !!vehicleId && !!selectedBody,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data: gearboxes = [], isLoading: loadingGearboxes } = useQuery<VariantItem[]>({
|
||||||
|
queryKey: ["psa-gearboxes", vehicleId, selectedBody, selectedEngine],
|
||||||
|
queryFn: () =>
|
||||||
|
api.get<VariantItem[]>(
|
||||||
|
`/catalog/vehicles/${vehicleId}/psa-gearboxes?body=${encodeURIComponent(selectedBody!)}&engine=${encodeURIComponent(selectedEngine!)}`,
|
||||||
|
),
|
||||||
|
enabled: !!vehicleId && !!selectedBody && !!selectedEngine,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleBodySelect = (code: string | "_all_") => {
|
||||||
|
if (code === "_all_") {
|
||||||
|
onSelect("_all_", "_all_", "_all_");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedBody(code);
|
||||||
|
setSelectedEngine(null);
|
||||||
|
setSelectedGearbox(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEngineSelect = (code: string | "_all_") => {
|
||||||
|
if (code === "_all_") {
|
||||||
|
onSelect(selectedBody!, "_all_", "_all_");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedEngine(code);
|
||||||
|
setSelectedGearbox(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleGearboxSelect = (code: string | "_all_") => {
|
||||||
|
if (code === "_all_") {
|
||||||
|
onSelect(selectedBody!, selectedEngine!, "_all_");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedGearbox(code);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleProceed = () => {
|
||||||
|
if (selectedBody && selectedEngine && selectedGearbox) {
|
||||||
|
onSelect(selectedBody, selectedEngine, selectedGearbox);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const canProceed = selectedBody && selectedEngine && selectedGearbox;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-base">{t("catalog.psaVariant.title")}</CardTitle>
|
||||||
|
<p className="text-sm text-muted-foreground">{t("catalog.psaVariant.subtitle")}</p>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-6">
|
||||||
|
{/* Body Type */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-sm font-medium">{t("catalog.psaVariant.body")}</p>
|
||||||
|
{loadingBodies ? (
|
||||||
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
|
<Loader2 className="size-4 animate-spin" />
|
||||||
|
{t("catalog.psaVariant.loading")}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{bodies.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item.code}
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleBodySelect(item.code)}
|
||||||
|
className={`rounded-md border px-3 py-1.5 text-sm transition-colors ${
|
||||||
|
selectedBody === item.code
|
||||||
|
? "border-primary bg-primary text-primary-foreground"
|
||||||
|
: "border-border bg-background hover:bg-accent"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleBodySelect("_all_")}
|
||||||
|
className="rounded-md border border-dashed border-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent"
|
||||||
|
>
|
||||||
|
{t("catalog.psaVariant.showAll")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Engine */}
|
||||||
|
{selectedBody && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-sm font-medium">{t("catalog.psaVariant.engine")}</p>
|
||||||
|
{loadingEngines ? (
|
||||||
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
|
<Loader2 className="size-4 animate-spin" />
|
||||||
|
{t("catalog.psaVariant.loading")}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{engines.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item.code}
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleEngineSelect(item.code)}
|
||||||
|
className={`rounded-md border px-3 py-1.5 text-sm transition-colors ${
|
||||||
|
selectedEngine === item.code
|
||||||
|
? "border-primary bg-primary text-primary-foreground"
|
||||||
|
: "border-border bg-background hover:bg-accent"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleEngineSelect("_all_")}
|
||||||
|
className="rounded-md border border-dashed border-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent"
|
||||||
|
>
|
||||||
|
{t("catalog.psaVariant.showAll")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Gearbox */}
|
||||||
|
{selectedBody && selectedEngine && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-sm font-medium">{t("catalog.psaVariant.gearbox")}</p>
|
||||||
|
{loadingGearboxes ? (
|
||||||
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
|
<Loader2 className="size-4 animate-spin" />
|
||||||
|
{t("catalog.psaVariant.loading")}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{gearboxes.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item.code}
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleGearboxSelect(item.code)}
|
||||||
|
className={`rounded-md border px-3 py-1.5 text-sm transition-colors ${
|
||||||
|
selectedGearbox === item.code
|
||||||
|
? "border-primary bg-primary text-primary-foreground"
|
||||||
|
: "border-border bg-background hover:bg-accent"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleGearboxSelect("_all_")}
|
||||||
|
className="rounded-md border border-dashed border-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent"
|
||||||
|
>
|
||||||
|
{t("catalog.psaVariant.showAll")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Proceed button */}
|
||||||
|
{canProceed && (
|
||||||
|
<Button onClick={handleProceed} className="w-full sm:w-auto">
|
||||||
|
{t("catalog.psaVariant.proceed")}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -19,9 +19,13 @@ interface Category {
|
|||||||
interface CategoryGridProps {
|
interface CategoryGridProps {
|
||||||
categories: Category[];
|
categories: Category[];
|
||||||
vehicleId: string;
|
vehicleId: string;
|
||||||
|
catalogMode?: boolean;
|
||||||
|
brandName?: string;
|
||||||
|
parentId?: string;
|
||||||
|
variantSearch?: { body?: string; engine?: string; gearbox?: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CategoryGrid({ categories, vehicleId }: CategoryGridProps) {
|
export function CategoryGrid({ categories, vehicleId, catalogMode, brandName, parentId, variantSearch }: CategoryGridProps) {
|
||||||
const [prefetchingIds, setPrefetchingIds] = useState<Set<string>>(new Set());
|
const [prefetchingIds, setPrefetchingIds] = useState<Set<string>>(new Set());
|
||||||
const [imageOverrides, setImageOverrides] = useState<Map<string, string>>(new Map());
|
const [imageOverrides, setImageOverrides] = useState<Map<string, string>>(new Map());
|
||||||
const prefetchedRef = useRef<Set<string>>(new Set());
|
const prefetchedRef = useRef<Set<string>>(new Set());
|
||||||
@@ -104,8 +108,13 @@ export function CategoryGrid({ categories, vehicleId }: CategoryGridProps) {
|
|||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
key={category.id}
|
key={category.id}
|
||||||
to="/dashboard/vehicles/$id/categories/$categoryId"
|
to={catalogMode
|
||||||
params={{ id: vehicleId, categoryId: category.id }}
|
? "/dashboard/catalog/$brandName/$modelId/categories/$categoryId"
|
||||||
|
: "/dashboard/vehicles/$id/categories/$categoryId"}
|
||||||
|
params={catalogMode
|
||||||
|
? { brandName: brandName ?? vehicleId, modelId: vehicleId, categoryId: category.id }
|
||||||
|
: { id: vehicleId, categoryId: category.id }}
|
||||||
|
search={catalogMode && variantSearch ? variantSearch : undefined}
|
||||||
className={category.unavailable ? "opacity-40" : undefined}
|
className={category.unavailable ? "opacity-40" : undefined}
|
||||||
>
|
>
|
||||||
<CategoryCard
|
<CategoryCard
|
||||||
|
|||||||
@@ -17,21 +17,43 @@ interface Category {
|
|||||||
source?: string;
|
source?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CategoryTree({ categories, vehicleId }: { categories: Category[]; vehicleId: string }) {
|
export function CategoryTree({
|
||||||
|
categories,
|
||||||
|
vehicleId,
|
||||||
|
catalogMode,
|
||||||
|
brandName,
|
||||||
|
variantSearch,
|
||||||
|
}: {
|
||||||
|
categories: Category[];
|
||||||
|
vehicleId: string;
|
||||||
|
catalogMode?: boolean;
|
||||||
|
brandName?: string;
|
||||||
|
variantSearch?: { body?: string; engine?: string; gearbox?: string };
|
||||||
|
}) {
|
||||||
if (!categories || categories.length === 0) {
|
if (!categories || categories.length === 0) {
|
||||||
return <p className="py-4 text-center text-sm text-muted-foreground">Kategori bulunamadi.</p>;
|
return <p className="py-4 text-center text-sm text-muted-foreground">Kategori bulunamadi.</p>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{categories.map((cat) => (
|
{categories.map((cat) => (
|
||||||
<CategoryNode key={cat.id} category={cat} vehicleId={vehicleId} level={0} parentPrefetching={false} />
|
<CategoryNode
|
||||||
|
key={cat.id}
|
||||||
|
category={cat}
|
||||||
|
vehicleId={vehicleId}
|
||||||
|
level={0}
|
||||||
|
parentPrefetching={false}
|
||||||
|
catalogMode={catalogMode}
|
||||||
|
brandName={brandName}
|
||||||
|
variantSearch={variantSearch}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function CategoryNode({ category, vehicleId, level, parentPrefetching }: {
|
function CategoryNode({ category, vehicleId, level, parentPrefetching, catalogMode, brandName, variantSearch }: {
|
||||||
category: Category; vehicleId: string; level: number; parentPrefetching: boolean;
|
category: Category; vehicleId: string; level: number; parentPrefetching: boolean;
|
||||||
|
catalogMode?: boolean; brandName?: string; variantSearch?: { body?: string; engine?: string; gearbox?: string };
|
||||||
}) {
|
}) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
@@ -131,8 +153,14 @@ function CategoryNode({ category, vehicleId, level, parentPrefetching }: {
|
|||||||
)}
|
)}
|
||||||
<SchemaIcon Icon={Icon} schemaImageUrl={category.schemaImageUrl} name={category.name} shimmer={isShimmering} />
|
<SchemaIcon Icon={Icon} schemaImageUrl={category.schemaImageUrl} name={category.name} shimmer={isShimmering} />
|
||||||
{isLeaf ? (
|
{isLeaf ? (
|
||||||
<Link to="/dashboard/vehicles/$id/categories/$categoryId"
|
<Link
|
||||||
params={{ id: vehicleId, categoryId: category.id }}
|
to={catalogMode
|
||||||
|
? "/dashboard/catalog/$brandName/$modelId/categories/$categoryId"
|
||||||
|
: "/dashboard/vehicles/$id/categories/$categoryId"}
|
||||||
|
params={catalogMode
|
||||||
|
? { brandName: brandName ?? vehicleId, modelId: vehicleId, categoryId: category.id }
|
||||||
|
: { id: vehicleId, categoryId: category.id }}
|
||||||
|
search={catalogMode && variantSearch ? variantSearch : undefined}
|
||||||
className="flex-1 truncate hover:underline">
|
className="flex-1 truncate hover:underline">
|
||||||
{category.name}
|
{category.name}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -150,7 +178,8 @@ function CategoryNode({ category, vehicleId, level, parentPrefetching }: {
|
|||||||
<div>
|
<div>
|
||||||
{children.map((child) => (
|
{children.map((child) => (
|
||||||
<CategoryNode key={child.id} category={child} vehicleId={vehicleId}
|
<CategoryNode key={child.id} category={child} vehicleId={vehicleId}
|
||||||
level={level + 1} parentPrefetching={prefetching} />
|
level={level + 1} parentPrefetching={prefetching}
|
||||||
|
catalogMode={catalogMode} brandName={brandName} variantSearch={variantSearch} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -30,12 +30,52 @@
|
|||||||
"nav": {
|
"nav": {
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"history": "History",
|
"history": "History",
|
||||||
|
"catalog": "Catalog",
|
||||||
"subscription": "Subscription",
|
"subscription": "Subscription",
|
||||||
"billing": "Billing",
|
"billing": "Billing",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"admin": "Admin Panel",
|
"admin": "Admin Panel",
|
||||||
"logout": "Log Out"
|
"logout": "Log Out"
|
||||||
},
|
},
|
||||||
|
"catalog": {
|
||||||
|
"title": "Parts Catalog",
|
||||||
|
"brands": "Brands",
|
||||||
|
"models": "Models",
|
||||||
|
"allBrands": "All Brands",
|
||||||
|
"modelCount": "{count} models",
|
||||||
|
"noBrands": "Catalog data is being prepared",
|
||||||
|
"noModels": "No models found",
|
||||||
|
"locked": "This brand is not in your plan",
|
||||||
|
"upgradeCta": "Upgrade Plan",
|
||||||
|
"loadingModels": "Loading models...",
|
||||||
|
"categories": "Categories",
|
||||||
|
"parts": "Parts",
|
||||||
|
"backToBrands": "Back to Brands",
|
||||||
|
"backToModels": "Back to Models",
|
||||||
|
"backToCategories": "Back to Categories",
|
||||||
|
"selectCatalog": "Select a catalog",
|
||||||
|
"psaVariant": {
|
||||||
|
"title": "Select Vehicle Variant",
|
||||||
|
"subtitle": "Optional — use Show All to browse all variants",
|
||||||
|
"body": "Body Type",
|
||||||
|
"engine": "Engine",
|
||||||
|
"gearbox": "Gearbox",
|
||||||
|
"showAll": "Show All",
|
||||||
|
"proceed": "Go to Catalog",
|
||||||
|
"loading": "Loading..."
|
||||||
|
},
|
||||||
|
"fordVariant": {
|
||||||
|
"title": "Select Model",
|
||||||
|
"subtitle": "Optional — use Show All to browse all variants",
|
||||||
|
"modelYear": "Model Year",
|
||||||
|
"engine": "Engine",
|
||||||
|
"gearbox": "Gearbox",
|
||||||
|
"showAll": "Show All",
|
||||||
|
"proceed": "Go to Catalog",
|
||||||
|
"loading": "Loading...",
|
||||||
|
"noConfig": "Variant info unavailable. You can still browse all categories."
|
||||||
|
}
|
||||||
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": "Log In",
|
"login": "Log In",
|
||||||
"register": "Sign Up",
|
"register": "Sign Up",
|
||||||
@@ -124,10 +164,10 @@
|
|||||||
"expired": "Expired"
|
"expired": "Expired"
|
||||||
},
|
},
|
||||||
"popular": "Popular",
|
"popular": "Popular",
|
||||||
"trialTitle": "3-Day Full Package Trial",
|
"trialTitle": "7-Day Full Package Trial",
|
||||||
"trialDescription": "Free access to all brands for 3 days. No credit card required.",
|
"trialDescription": "Free access to all brands for 7 days. No credit card required.",
|
||||||
"startTrial": "Start Free Trial",
|
"startTrial": "Start Free Trial",
|
||||||
"trialStarted": "Your 3-day Full Package trial has started!",
|
"trialStarted": "Your 7-day Full Package trial has started!",
|
||||||
"onboarding": {
|
"onboarding": {
|
||||||
"provisioning": "Setting up your free trial",
|
"provisioning": "Setting up your free trial",
|
||||||
"step1": "Verifying account",
|
"step1": "Verifying account",
|
||||||
@@ -135,7 +175,7 @@
|
|||||||
"step3": "Activating Full Package",
|
"step3": "Activating Full Package",
|
||||||
"step4": "Completed!",
|
"step4": "Completed!",
|
||||||
"completed": "You can test all catalogs without limits!",
|
"completed": "You can test all catalogs without limits!",
|
||||||
"trialDuration": "3-Day Trial",
|
"trialDuration": "7-Day Trial",
|
||||||
"startSearching": "Start Searching",
|
"startSearching": "Start Searching",
|
||||||
"error": "An error occurred while starting your trial.",
|
"error": "An error occurred while starting your trial.",
|
||||||
"retry": "Try Again"
|
"retry": "Try Again"
|
||||||
|
|||||||
@@ -30,12 +30,52 @@
|
|||||||
"nav": {
|
"nav": {
|
||||||
"search": "Arama",
|
"search": "Arama",
|
||||||
"history": "Geçmiş",
|
"history": "Geçmiş",
|
||||||
|
"catalog": "Katalog",
|
||||||
"subscription": "Abonelik",
|
"subscription": "Abonelik",
|
||||||
"billing": "Fatura",
|
"billing": "Fatura",
|
||||||
"settings": "Ayarlar",
|
"settings": "Ayarlar",
|
||||||
"admin": "Admin Panel",
|
"admin": "Admin Panel",
|
||||||
"logout": "Çıkış Yap"
|
"logout": "Çıkış Yap"
|
||||||
},
|
},
|
||||||
|
"catalog": {
|
||||||
|
"title": "Parça Kataloğu",
|
||||||
|
"brands": "Markalar",
|
||||||
|
"models": "Modeller",
|
||||||
|
"allBrands": "Tüm Markalar",
|
||||||
|
"modelCount": "{count} model",
|
||||||
|
"noBrands": "Katalog verisi hazırlanıyor",
|
||||||
|
"noModels": "Model bulunamadı",
|
||||||
|
"locked": "Bu marka planınızda yok",
|
||||||
|
"upgradeCta": "Planını Yükselt",
|
||||||
|
"loadingModels": "Modeller yükleniyor...",
|
||||||
|
"categories": "Kategoriler",
|
||||||
|
"parts": "Parçalar",
|
||||||
|
"backToBrands": "Markalara Dön",
|
||||||
|
"backToModels": "Modellere Dön",
|
||||||
|
"backToCategories": "Kategorilere Dön",
|
||||||
|
"selectCatalog": "Bir katalog seçin",
|
||||||
|
"psaVariant": {
|
||||||
|
"title": "Araç Varyantını Seçin",
|
||||||
|
"subtitle": "İsteğe bağlı — tüm varyantlar için Tümü seçeneğini kullanın",
|
||||||
|
"body": "Kasa Tipi",
|
||||||
|
"engine": "Motor",
|
||||||
|
"gearbox": "Şanzıman",
|
||||||
|
"showAll": "Tümü",
|
||||||
|
"proceed": "Kataloga Git",
|
||||||
|
"loading": "Yükleniyor..."
|
||||||
|
},
|
||||||
|
"fordVariant": {
|
||||||
|
"title": "Model Seçin",
|
||||||
|
"subtitle": "İsteğe bağlı — tüm varyantlar için Tümü seçeneğini kullanın",
|
||||||
|
"modelYear": "Model Yılı",
|
||||||
|
"engine": "Motor",
|
||||||
|
"gearbox": "Şanzıman",
|
||||||
|
"showAll": "Tümü",
|
||||||
|
"proceed": "Kataloga Git",
|
||||||
|
"loading": "Yükleniyor...",
|
||||||
|
"noConfig": "Varyant bilgisi yüklenemedi. Tüm kategorilere göz atabilirsiniz."
|
||||||
|
}
|
||||||
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": "Giriş Yap",
|
"login": "Giriş Yap",
|
||||||
"register": "Kayıt Ol",
|
"register": "Kayıt Ol",
|
||||||
@@ -124,10 +164,10 @@
|
|||||||
"expired": "Süresi Doldu"
|
"expired": "Süresi Doldu"
|
||||||
},
|
},
|
||||||
"popular": "Popüler",
|
"popular": "Popüler",
|
||||||
"trialTitle": "3 Gün Full Paket Denemesi",
|
"trialTitle": "7 Gün Full Paket Denemesi",
|
||||||
"trialDescription": "Tüm markalara 3 gün boyunca ücretsiz erişim. Kredi kartı gerekmez.",
|
"trialDescription": "Tüm markalara 7 gün boyunca ücretsiz erişim. Kredi kartı gerekmez.",
|
||||||
"startTrial": "Ücretsiz Denemeyi Başlat",
|
"startTrial": "Ücretsiz Denemeyi Başlat",
|
||||||
"trialStarted": "3 günlük Full Paket denemeniz başlatıldı!",
|
"trialStarted": "7 günlük Full Paket denemeniz başlatıldı!",
|
||||||
"onboarding": {
|
"onboarding": {
|
||||||
"provisioning": "Ücretsiz kullanım hakkınız tanımlanıyor",
|
"provisioning": "Ücretsiz kullanım hakkınız tanımlanıyor",
|
||||||
"step1": "Hesap doğrulanıyor",
|
"step1": "Hesap doğrulanıyor",
|
||||||
@@ -135,7 +175,7 @@
|
|||||||
"step3": "Full Paket aktif ediliyor",
|
"step3": "Full Paket aktif ediliyor",
|
||||||
"step4": "Tamamlandı!",
|
"step4": "Tamamlandı!",
|
||||||
"completed": "Tüm katalogları sınırsız test edebilirsiniz!",
|
"completed": "Tüm katalogları sınırsız test edebilirsiniz!",
|
||||||
"trialDuration": "3 Gün Deneme",
|
"trialDuration": "7 Gün Deneme",
|
||||||
"startSearching": "Şase Aramaya Başla",
|
"startSearching": "Şase Aramaya Başla",
|
||||||
"error": "Deneme başlatılırken bir hata oluştu.",
|
"error": "Deneme başlatılırken bir hata oluştu.",
|
||||||
"retry": "Tekrar Dene"
|
"retry": "Tekrar Dene"
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { Route as AuthRegisterRouteImport } from "./routes/_auth/register"
|
|||||||
import { Route as AuthLoginRouteImport } from "./routes/_auth/login"
|
import { Route as AuthLoginRouteImport } from "./routes/_auth/login"
|
||||||
import { Route as AuthForgotPasswordRouteImport } from "./routes/_auth/forgot-password"
|
import { Route as AuthForgotPasswordRouteImport } from "./routes/_auth/forgot-password"
|
||||||
import { Route as DashboardSubscriptionIndexRouteImport } from "./routes/dashboard/subscription/index"
|
import { Route as DashboardSubscriptionIndexRouteImport } from "./routes/dashboard/subscription/index"
|
||||||
|
import { Route as DashboardCatalogIndexRouteImport } from "./routes/dashboard/catalog/index"
|
||||||
import { Route as DashboardAdminIndexRouteImport } from "./routes/dashboard/admin/index"
|
import { Route as DashboardAdminIndexRouteImport } from "./routes/dashboard/admin/index"
|
||||||
import { Route as DashboardSubscriptionPayRouteImport } from "./routes/dashboard/subscription/pay"
|
import { Route as DashboardSubscriptionPayRouteImport } from "./routes/dashboard/subscription/pay"
|
||||||
import { Route as DashboardAdminUsersRouteImport } from "./routes/dashboard/admin/users"
|
import { Route as DashboardAdminUsersRouteImport } from "./routes/dashboard/admin/users"
|
||||||
@@ -39,7 +40,10 @@ import { Route as DashboardAdminPaymentsRouteImport } from "./routes/dashboard/a
|
|||||||
import { Route as DashboardAdminCopyLogsRouteImport } from "./routes/dashboard/admin/copy-logs"
|
import { Route as DashboardAdminCopyLogsRouteImport } from "./routes/dashboard/admin/copy-logs"
|
||||||
import { Route as DashboardAdminAnalyticsRouteImport } from "./routes/dashboard/admin/analytics"
|
import { Route as DashboardAdminAnalyticsRouteImport } from "./routes/dashboard/admin/analytics"
|
||||||
import { Route as DashboardVehiclesIdIndexRouteImport } from "./routes/dashboard/vehicles_/$id/index"
|
import { Route as DashboardVehiclesIdIndexRouteImport } from "./routes/dashboard/vehicles_/$id/index"
|
||||||
|
import { Route as DashboardCatalogBrandNameIndexRouteImport } from "./routes/dashboard/catalog_/$brandName/index"
|
||||||
|
import { Route as DashboardCatalogBrandNameModelIdIndexRouteImport } from "./routes/dashboard/catalog_/$brandName_/$modelId/index"
|
||||||
import { Route as DashboardVehiclesIdCategoriesCategoryIdRouteImport } from "./routes/dashboard/vehicles_/$id/categories_/$categoryId"
|
import { Route as DashboardVehiclesIdCategoriesCategoryIdRouteImport } from "./routes/dashboard/vehicles_/$id/categories_/$categoryId"
|
||||||
|
import { Route as DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport } from "./routes/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId"
|
||||||
|
|
||||||
const TermsRoute = TermsRouteImport.update({
|
const TermsRoute = TermsRouteImport.update({
|
||||||
id: "/terms",
|
id: "/terms",
|
||||||
@@ -151,6 +155,11 @@ const DashboardSubscriptionIndexRoute =
|
|||||||
path: "/subscription/",
|
path: "/subscription/",
|
||||||
getParentRoute: () => DashboardRoute,
|
getParentRoute: () => DashboardRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
const DashboardCatalogIndexRoute = DashboardCatalogIndexRouteImport.update({
|
||||||
|
id: "/catalog/",
|
||||||
|
path: "/catalog/",
|
||||||
|
getParentRoute: () => DashboardRoute,
|
||||||
|
} as any)
|
||||||
const DashboardAdminIndexRoute = DashboardAdminIndexRouteImport.update({
|
const DashboardAdminIndexRoute = DashboardAdminIndexRouteImport.update({
|
||||||
id: "/admin/",
|
id: "/admin/",
|
||||||
path: "/admin/",
|
path: "/admin/",
|
||||||
@@ -193,12 +202,30 @@ const DashboardVehiclesIdIndexRoute =
|
|||||||
path: "/vehicles/$id/",
|
path: "/vehicles/$id/",
|
||||||
getParentRoute: () => DashboardRoute,
|
getParentRoute: () => DashboardRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
const DashboardCatalogBrandNameIndexRoute =
|
||||||
|
DashboardCatalogBrandNameIndexRouteImport.update({
|
||||||
|
id: "/catalog_/$brandName/",
|
||||||
|
path: "/catalog/$brandName/",
|
||||||
|
getParentRoute: () => DashboardRoute,
|
||||||
|
} as any)
|
||||||
|
const DashboardCatalogBrandNameModelIdIndexRoute =
|
||||||
|
DashboardCatalogBrandNameModelIdIndexRouteImport.update({
|
||||||
|
id: "/catalog_/$brandName_/$modelId/",
|
||||||
|
path: "/catalog/$brandName/$modelId/",
|
||||||
|
getParentRoute: () => DashboardRoute,
|
||||||
|
} as any)
|
||||||
const DashboardVehiclesIdCategoriesCategoryIdRoute =
|
const DashboardVehiclesIdCategoriesCategoryIdRoute =
|
||||||
DashboardVehiclesIdCategoriesCategoryIdRouteImport.update({
|
DashboardVehiclesIdCategoriesCategoryIdRouteImport.update({
|
||||||
id: "/vehicles_/$id/categories_/$categoryId",
|
id: "/vehicles_/$id/categories_/$categoryId",
|
||||||
path: "/vehicles/$id/categories/$categoryId",
|
path: "/vehicles/$id/categories/$categoryId",
|
||||||
getParentRoute: () => DashboardRoute,
|
getParentRoute: () => DashboardRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
const DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute =
|
||||||
|
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport.update({
|
||||||
|
id: "/catalog_/$brandName_/$modelId/categories_/$categoryId",
|
||||||
|
path: "/catalog/$brandName/$modelId/categories/$categoryId",
|
||||||
|
getParentRoute: () => DashboardRoute,
|
||||||
|
} as any)
|
||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
"/": typeof IndexRoute
|
"/": typeof IndexRoute
|
||||||
@@ -228,9 +255,13 @@ export interface FileRoutesByFullPath {
|
|||||||
"/dashboard/admin/users": typeof DashboardAdminUsersRoute
|
"/dashboard/admin/users": typeof DashboardAdminUsersRoute
|
||||||
"/dashboard/subscription/pay": typeof DashboardSubscriptionPayRoute
|
"/dashboard/subscription/pay": typeof DashboardSubscriptionPayRoute
|
||||||
"/dashboard/admin/": typeof DashboardAdminIndexRoute
|
"/dashboard/admin/": typeof DashboardAdminIndexRoute
|
||||||
|
"/dashboard/catalog/": typeof DashboardCatalogIndexRoute
|
||||||
"/dashboard/subscription/": typeof DashboardSubscriptionIndexRoute
|
"/dashboard/subscription/": typeof DashboardSubscriptionIndexRoute
|
||||||
|
"/dashboard/catalog/$brandName/": typeof DashboardCatalogBrandNameIndexRoute
|
||||||
"/dashboard/vehicles/$id/": typeof DashboardVehiclesIdIndexRoute
|
"/dashboard/vehicles/$id/": typeof DashboardVehiclesIdIndexRoute
|
||||||
"/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
"/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||||
|
"/dashboard/catalog/$brandName/$modelId/": typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||||
|
"/dashboard/catalog/$brandName/$modelId/categories/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
"/": typeof IndexRoute
|
"/": typeof IndexRoute
|
||||||
@@ -259,9 +290,13 @@ export interface FileRoutesByTo {
|
|||||||
"/dashboard/admin/users": typeof DashboardAdminUsersRoute
|
"/dashboard/admin/users": typeof DashboardAdminUsersRoute
|
||||||
"/dashboard/subscription/pay": typeof DashboardSubscriptionPayRoute
|
"/dashboard/subscription/pay": typeof DashboardSubscriptionPayRoute
|
||||||
"/dashboard/admin": typeof DashboardAdminIndexRoute
|
"/dashboard/admin": typeof DashboardAdminIndexRoute
|
||||||
|
"/dashboard/catalog": typeof DashboardCatalogIndexRoute
|
||||||
"/dashboard/subscription": typeof DashboardSubscriptionIndexRoute
|
"/dashboard/subscription": typeof DashboardSubscriptionIndexRoute
|
||||||
|
"/dashboard/catalog/$brandName": typeof DashboardCatalogBrandNameIndexRoute
|
||||||
"/dashboard/vehicles/$id": typeof DashboardVehiclesIdIndexRoute
|
"/dashboard/vehicles/$id": typeof DashboardVehiclesIdIndexRoute
|
||||||
"/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
"/dashboard/vehicles/$id/categories/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||||
|
"/dashboard/catalog/$brandName/$modelId": typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||||
|
"/dashboard/catalog/$brandName/$modelId/categories/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesById {
|
export interface FileRoutesById {
|
||||||
__root__: typeof rootRouteImport
|
__root__: typeof rootRouteImport
|
||||||
@@ -293,9 +328,13 @@ export interface FileRoutesById {
|
|||||||
"/dashboard/admin/users": typeof DashboardAdminUsersRoute
|
"/dashboard/admin/users": typeof DashboardAdminUsersRoute
|
||||||
"/dashboard/subscription/pay": typeof DashboardSubscriptionPayRoute
|
"/dashboard/subscription/pay": typeof DashboardSubscriptionPayRoute
|
||||||
"/dashboard/admin/": typeof DashboardAdminIndexRoute
|
"/dashboard/admin/": typeof DashboardAdminIndexRoute
|
||||||
|
"/dashboard/catalog/": typeof DashboardCatalogIndexRoute
|
||||||
"/dashboard/subscription/": typeof DashboardSubscriptionIndexRoute
|
"/dashboard/subscription/": typeof DashboardSubscriptionIndexRoute
|
||||||
|
"/dashboard/catalog_/$brandName/": typeof DashboardCatalogBrandNameIndexRoute
|
||||||
"/dashboard/vehicles_/$id/": typeof DashboardVehiclesIdIndexRoute
|
"/dashboard/vehicles_/$id/": typeof DashboardVehiclesIdIndexRoute
|
||||||
"/dashboard/vehicles_/$id/categories_/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
"/dashboard/vehicles_/$id/categories_/$categoryId": typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||||
|
"/dashboard/catalog_/$brandName_/$modelId/": typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||||
|
"/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId": typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||||
}
|
}
|
||||||
export interface FileRouteTypes {
|
export interface FileRouteTypes {
|
||||||
fileRoutesByFullPath: FileRoutesByFullPath
|
fileRoutesByFullPath: FileRoutesByFullPath
|
||||||
@@ -327,9 +366,13 @@ export interface FileRouteTypes {
|
|||||||
| "/dashboard/admin/users"
|
| "/dashboard/admin/users"
|
||||||
| "/dashboard/subscription/pay"
|
| "/dashboard/subscription/pay"
|
||||||
| "/dashboard/admin/"
|
| "/dashboard/admin/"
|
||||||
|
| "/dashboard/catalog/"
|
||||||
| "/dashboard/subscription/"
|
| "/dashboard/subscription/"
|
||||||
|
| "/dashboard/catalog/$brandName/"
|
||||||
| "/dashboard/vehicles/$id/"
|
| "/dashboard/vehicles/$id/"
|
||||||
| "/dashboard/vehicles/$id/categories/$categoryId"
|
| "/dashboard/vehicles/$id/categories/$categoryId"
|
||||||
|
| "/dashboard/catalog/$brandName/$modelId/"
|
||||||
|
| "/dashboard/catalog/$brandName/$modelId/categories/$categoryId"
|
||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to:
|
to:
|
||||||
| "/"
|
| "/"
|
||||||
@@ -358,9 +401,13 @@ export interface FileRouteTypes {
|
|||||||
| "/dashboard/admin/users"
|
| "/dashboard/admin/users"
|
||||||
| "/dashboard/subscription/pay"
|
| "/dashboard/subscription/pay"
|
||||||
| "/dashboard/admin"
|
| "/dashboard/admin"
|
||||||
|
| "/dashboard/catalog"
|
||||||
| "/dashboard/subscription"
|
| "/dashboard/subscription"
|
||||||
|
| "/dashboard/catalog/$brandName"
|
||||||
| "/dashboard/vehicles/$id"
|
| "/dashboard/vehicles/$id"
|
||||||
| "/dashboard/vehicles/$id/categories/$categoryId"
|
| "/dashboard/vehicles/$id/categories/$categoryId"
|
||||||
|
| "/dashboard/catalog/$brandName/$modelId"
|
||||||
|
| "/dashboard/catalog/$brandName/$modelId/categories/$categoryId"
|
||||||
id:
|
id:
|
||||||
| "__root__"
|
| "__root__"
|
||||||
| "/"
|
| "/"
|
||||||
@@ -391,9 +438,13 @@ export interface FileRouteTypes {
|
|||||||
| "/dashboard/admin/users"
|
| "/dashboard/admin/users"
|
||||||
| "/dashboard/subscription/pay"
|
| "/dashboard/subscription/pay"
|
||||||
| "/dashboard/admin/"
|
| "/dashboard/admin/"
|
||||||
|
| "/dashboard/catalog/"
|
||||||
| "/dashboard/subscription/"
|
| "/dashboard/subscription/"
|
||||||
|
| "/dashboard/catalog_/$brandName/"
|
||||||
| "/dashboard/vehicles_/$id/"
|
| "/dashboard/vehicles_/$id/"
|
||||||
| "/dashboard/vehicles_/$id/categories_/$categoryId"
|
| "/dashboard/vehicles_/$id/categories_/$categoryId"
|
||||||
|
| "/dashboard/catalog_/$brandName_/$modelId/"
|
||||||
|
| "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId"
|
||||||
fileRoutesById: FileRoutesById
|
fileRoutesById: FileRoutesById
|
||||||
}
|
}
|
||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
@@ -567,6 +618,13 @@ declare module "@tanstack/react-router" {
|
|||||||
preLoaderRoute: typeof DashboardSubscriptionIndexRouteImport
|
preLoaderRoute: typeof DashboardSubscriptionIndexRouteImport
|
||||||
parentRoute: typeof DashboardRoute
|
parentRoute: typeof DashboardRoute
|
||||||
}
|
}
|
||||||
|
"/dashboard/catalog/": {
|
||||||
|
id: "/dashboard/catalog/"
|
||||||
|
path: "/catalog"
|
||||||
|
fullPath: "/dashboard/catalog/"
|
||||||
|
preLoaderRoute: typeof DashboardCatalogIndexRouteImport
|
||||||
|
parentRoute: typeof DashboardRoute
|
||||||
|
}
|
||||||
"/dashboard/admin/": {
|
"/dashboard/admin/": {
|
||||||
id: "/dashboard/admin/"
|
id: "/dashboard/admin/"
|
||||||
path: "/admin"
|
path: "/admin"
|
||||||
@@ -623,6 +681,20 @@ declare module "@tanstack/react-router" {
|
|||||||
preLoaderRoute: typeof DashboardVehiclesIdIndexRouteImport
|
preLoaderRoute: typeof DashboardVehiclesIdIndexRouteImport
|
||||||
parentRoute: typeof DashboardRoute
|
parentRoute: typeof DashboardRoute
|
||||||
}
|
}
|
||||||
|
"/dashboard/catalog_/$brandName/": {
|
||||||
|
id: "/dashboard/catalog_/$brandName/"
|
||||||
|
path: "/catalog/$brandName"
|
||||||
|
fullPath: "/dashboard/catalog/$brandName/"
|
||||||
|
preLoaderRoute: typeof DashboardCatalogBrandNameIndexRouteImport
|
||||||
|
parentRoute: typeof DashboardRoute
|
||||||
|
}
|
||||||
|
"/dashboard/catalog_/$brandName_/$modelId/": {
|
||||||
|
id: "/dashboard/catalog_/$brandName_/$modelId/"
|
||||||
|
path: "/catalog/$brandName/$modelId"
|
||||||
|
fullPath: "/dashboard/catalog/$brandName/$modelId/"
|
||||||
|
preLoaderRoute: typeof DashboardCatalogBrandNameModelIdIndexRouteImport
|
||||||
|
parentRoute: typeof DashboardRoute
|
||||||
|
}
|
||||||
"/dashboard/vehicles_/$id/categories_/$categoryId": {
|
"/dashboard/vehicles_/$id/categories_/$categoryId": {
|
||||||
id: "/dashboard/vehicles_/$id/categories_/$categoryId"
|
id: "/dashboard/vehicles_/$id/categories_/$categoryId"
|
||||||
path: "/vehicles/$id/categories/$categoryId"
|
path: "/vehicles/$id/categories/$categoryId"
|
||||||
@@ -630,6 +702,13 @@ declare module "@tanstack/react-router" {
|
|||||||
preLoaderRoute: typeof DashboardVehiclesIdCategoriesCategoryIdRouteImport
|
preLoaderRoute: typeof DashboardVehiclesIdCategoriesCategoryIdRouteImport
|
||||||
parentRoute: typeof DashboardRoute
|
parentRoute: typeof DashboardRoute
|
||||||
}
|
}
|
||||||
|
"/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId": {
|
||||||
|
id: "/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId"
|
||||||
|
path: "/catalog/$brandName/$modelId/categories/$categoryId"
|
||||||
|
fullPath: "/dashboard/catalog/$brandName/$modelId/categories/$categoryId"
|
||||||
|
preLoaderRoute: typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRouteImport
|
||||||
|
parentRoute: typeof DashboardRoute
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,9 +741,13 @@ interface DashboardRouteChildren {
|
|||||||
DashboardAdminUsersRoute: typeof DashboardAdminUsersRoute
|
DashboardAdminUsersRoute: typeof DashboardAdminUsersRoute
|
||||||
DashboardSubscriptionPayRoute: typeof DashboardSubscriptionPayRoute
|
DashboardSubscriptionPayRoute: typeof DashboardSubscriptionPayRoute
|
||||||
DashboardAdminIndexRoute: typeof DashboardAdminIndexRoute
|
DashboardAdminIndexRoute: typeof DashboardAdminIndexRoute
|
||||||
|
DashboardCatalogIndexRoute: typeof DashboardCatalogIndexRoute
|
||||||
DashboardSubscriptionIndexRoute: typeof DashboardSubscriptionIndexRoute
|
DashboardSubscriptionIndexRoute: typeof DashboardSubscriptionIndexRoute
|
||||||
|
DashboardCatalogBrandNameIndexRoute: typeof DashboardCatalogBrandNameIndexRoute
|
||||||
DashboardVehiclesIdIndexRoute: typeof DashboardVehiclesIdIndexRoute
|
DashboardVehiclesIdIndexRoute: typeof DashboardVehiclesIdIndexRoute
|
||||||
DashboardVehiclesIdCategoriesCategoryIdRoute: typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
DashboardVehiclesIdCategoriesCategoryIdRoute: typeof DashboardVehiclesIdCategoriesCategoryIdRoute
|
||||||
|
DashboardCatalogBrandNameModelIdIndexRoute: typeof DashboardCatalogBrandNameModelIdIndexRoute
|
||||||
|
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute: typeof DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
const DashboardRouteChildren: DashboardRouteChildren = {
|
const DashboardRouteChildren: DashboardRouteChildren = {
|
||||||
@@ -680,10 +763,16 @@ const DashboardRouteChildren: DashboardRouteChildren = {
|
|||||||
DashboardAdminUsersRoute: DashboardAdminUsersRoute,
|
DashboardAdminUsersRoute: DashboardAdminUsersRoute,
|
||||||
DashboardSubscriptionPayRoute: DashboardSubscriptionPayRoute,
|
DashboardSubscriptionPayRoute: DashboardSubscriptionPayRoute,
|
||||||
DashboardAdminIndexRoute: DashboardAdminIndexRoute,
|
DashboardAdminIndexRoute: DashboardAdminIndexRoute,
|
||||||
|
DashboardCatalogIndexRoute: DashboardCatalogIndexRoute,
|
||||||
DashboardSubscriptionIndexRoute: DashboardSubscriptionIndexRoute,
|
DashboardSubscriptionIndexRoute: DashboardSubscriptionIndexRoute,
|
||||||
|
DashboardCatalogBrandNameIndexRoute: DashboardCatalogBrandNameIndexRoute,
|
||||||
DashboardVehiclesIdIndexRoute: DashboardVehiclesIdIndexRoute,
|
DashboardVehiclesIdIndexRoute: DashboardVehiclesIdIndexRoute,
|
||||||
DashboardVehiclesIdCategoriesCategoryIdRoute:
|
DashboardVehiclesIdCategoriesCategoryIdRoute:
|
||||||
DashboardVehiclesIdCategoriesCategoryIdRoute,
|
DashboardVehiclesIdCategoriesCategoryIdRoute,
|
||||||
|
DashboardCatalogBrandNameModelIdIndexRoute:
|
||||||
|
DashboardCatalogBrandNameModelIdIndexRoute,
|
||||||
|
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute:
|
||||||
|
DashboardCatalogBrandNameModelIdCategoriesCategoryIdRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DashboardRouteWithChildren = DashboardRoute._addFileChildren(
|
const DashboardRouteWithChildren = DashboardRoute._addFileChildren(
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ function AuthLayout() {
|
|||||||
{/* Bottom trial badge */}
|
{/* Bottom trial badge */}
|
||||||
<div className="flex items-center gap-2 pt-6 text-sm text-neutral-400">
|
<div className="flex items-center gap-2 pt-6 text-sm text-neutral-400">
|
||||||
<ShieldCheck className="size-4" />
|
<ShieldCheck className="size-4" />
|
||||||
3 gün Full Paket ücretsiz deneyin — kredi kartı gerekmez
|
7 gün Full Paket ücretsiz deneyin — kredi kartı gerekmez
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link, createFileRoute, useNavigate } from "@tanstack/react-router";
|
import { Link, createFileRoute } from "@tanstack/react-router";
|
||||||
import { Button } from "@sase/ui";
|
import { Button } from "@sase/ui";
|
||||||
import { Input } from "@sase/ui";
|
import { Input } from "@sase/ui";
|
||||||
import { Label } from "@sase/ui";
|
import { Label } from "@sase/ui";
|
||||||
@@ -14,7 +14,6 @@ export const Route = createFileRoute("/_auth/login")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function LoginPage() {
|
function LoginPage() {
|
||||||
const navigate = useNavigate();
|
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -41,7 +40,7 @@ function LoginPage() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
capture("user_logged_in", { method: "email" });
|
capture("user_logged_in", { method: "email" });
|
||||||
navigate({ to: "/dashboard/search" });
|
window.location.href = "/dashboard/search";
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ function RegisterPage() {
|
|||||||
{/* Trial messaging */}
|
{/* Trial messaging */}
|
||||||
<div className="mt-3 flex items-center gap-2 rounded-lg bg-emerald-500/10 px-3 py-2 text-sm text-emerald-600 dark:text-emerald-400">
|
<div className="mt-3 flex items-center gap-2 rounded-lg bg-emerald-500/10 px-3 py-2 text-sm text-emerald-600 dark:text-emerald-400">
|
||||||
<ShieldCheck className="size-4 shrink-0" />
|
<ShieldCheck className="size-4 shrink-0" />
|
||||||
3 gün Full Paket ücretsiz deneyin — kredi kartı gerekmez
|
7 gün Full Paket ücretsiz deneyin — kredi kartı gerekmez
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
Sun,
|
Sun,
|
||||||
Moon,
|
Moon,
|
||||||
Copy,
|
Copy,
|
||||||
|
Library,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { getUserSettings, setUserSetting } from "@/lib/user-settings";
|
import { getUserSettings, setUserSetting } from "@/lib/user-settings";
|
||||||
@@ -40,6 +41,7 @@ export const Route = createFileRoute("/dashboard")({
|
|||||||
const mainMenuItems = [
|
const mainMenuItems = [
|
||||||
{ to: "/dashboard", label: "Gösterge Paneli", icon: LayoutDashboard, exact: true },
|
{ to: "/dashboard", label: "Gösterge Paneli", icon: LayoutDashboard, exact: true },
|
||||||
{ to: "/dashboard/search", label: "nav.search", translatable: true, icon: Search },
|
{ to: "/dashboard/search", label: "nav.search", translatable: true, icon: Search },
|
||||||
|
{ to: "/dashboard/catalog", label: "nav.catalog", translatable: true, icon: Library },
|
||||||
{ to: "/dashboard/history", label: "nav.history", translatable: true, icon: History },
|
{ to: "/dashboard/history", label: "nav.history", translatable: true, icon: History },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
|||||||
97
apps/web/src/routes/dashboard/catalog/index.tsx
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { createFileRoute, Link } from "@tanstack/react-router";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { api } from "@/lib/api-client";
|
||||||
|
import { useTranslation } from "@/lib/i18n";
|
||||||
|
import { Skeleton } from "@sase/ui";
|
||||||
|
import { Library, Lock } from "lucide-react";
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/dashboard/catalog/")({
|
||||||
|
component: CatalogBrandsPage,
|
||||||
|
});
|
||||||
|
|
||||||
|
interface CatalogBrand {
|
||||||
|
brandName: string;
|
||||||
|
brandId: string | null;
|
||||||
|
logoUrl: string | null;
|
||||||
|
serviceNames: string[];
|
||||||
|
hasAccess: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function CatalogBrandsPage() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { data: brands, isLoading } = useQuery({
|
||||||
|
queryKey: ["catalog-brands"],
|
||||||
|
queryFn: () => api.get<CatalogBrand[]>("/catalog/brands"),
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold">{t("catalog.title")}</h1>
|
||||||
|
<p className="text-sm text-muted-foreground">{t("catalog.brands")}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
|
||||||
|
{Array.from({ length: 10 }).map((_, i) => (
|
||||||
|
<Skeleton key={`brand-skel-${i}`} className="h-28 w-full rounded-xl" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : !brands || brands.length === 0 ? (
|
||||||
|
<div className="flex flex-col items-center justify-center py-16 text-center">
|
||||||
|
<Library className="mb-4 size-12 text-muted-foreground/40" />
|
||||||
|
<p className="text-muted-foreground">{t("catalog.noBrands")}</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
|
||||||
|
{brands.map((brand) => (
|
||||||
|
<BrandCard key={brand.brandName} brand={brand} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function BrandCard({ brand }: { brand: CatalogBrand }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
if (!brand.hasAccess) {
|
||||||
|
return (
|
||||||
|
<div className="relative flex flex-col items-center justify-center rounded-xl border border-border/50 bg-muted/30 p-4 text-center opacity-60 select-none">
|
||||||
|
<Lock className="mb-2 size-5 text-muted-foreground" />
|
||||||
|
<p className="text-sm font-semibold text-foreground">{brand.brandName}</p>
|
||||||
|
<p className="mt-1 text-xs text-muted-foreground">{t("catalog.locked")}</p>
|
||||||
|
<Link
|
||||||
|
to="/dashboard/subscription"
|
||||||
|
className="mt-2 text-xs font-medium text-primary hover:underline"
|
||||||
|
>
|
||||||
|
{t("catalog.upgradeCta")}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
to="/dashboard/catalog/$brandName"
|
||||||
|
params={{ brandName: encodeURIComponent(brand.brandName) }}
|
||||||
|
search={{ catalog: undefined }}
|
||||||
|
className="flex flex-col items-center justify-center rounded-xl border border-border bg-card p-4 text-center transition-colors hover:bg-accent hover:border-accent-foreground/20"
|
||||||
|
>
|
||||||
|
{brand.logoUrl ? (
|
||||||
|
<img
|
||||||
|
src={brand.logoUrl}
|
||||||
|
alt={brand.brandName}
|
||||||
|
className="mb-2 h-10 w-auto object-contain"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="mb-2 flex size-10 items-center justify-center rounded-full bg-primary/10">
|
||||||
|
<Library className="size-5 text-primary" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<p className="text-sm font-semibold">{brand.brandName}</p>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
211
apps/web/src/routes/dashboard/catalog_/$brandName/index.tsx
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { api } from "@/lib/api-client";
|
||||||
|
import { useTranslation } from "@/lib/i18n";
|
||||||
|
import { Button, Skeleton } from "@sase/ui";
|
||||||
|
import { ArrowLeft, BookOpen, Car, ChevronRight, Loader2 } from "lucide-react";
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/dashboard/catalog_/$brandName/")({
|
||||||
|
validateSearch: (search: Record<string, unknown>) => ({
|
||||||
|
catalog: typeof search.catalog === "string" ? search.catalog : undefined,
|
||||||
|
}),
|
||||||
|
component: CatalogModelsPage,
|
||||||
|
});
|
||||||
|
|
||||||
|
interface CatalogEntry {
|
||||||
|
serviceName: string;
|
||||||
|
displayName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CatalogVehicle {
|
||||||
|
id: string;
|
||||||
|
serviceName: string;
|
||||||
|
brandName: string;
|
||||||
|
model: string;
|
||||||
|
year: string | null;
|
||||||
|
engine: string | null;
|
||||||
|
bodyType: string | null;
|
||||||
|
transmission: string | null;
|
||||||
|
architecture: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function CatalogModelsPage() {
|
||||||
|
const { brandName } = Route.useParams();
|
||||||
|
const { catalog: activeCatalog } = Route.useSearch();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const decodedBrandName = decodeURIComponent(brandName);
|
||||||
|
|
||||||
|
// Always fetch catalogs to know whether this brand has multiple sub-catalogs
|
||||||
|
const { data: catalogs, isLoading: catalogsLoading } = useQuery({
|
||||||
|
queryKey: ["catalog-catalogs", decodedBrandName],
|
||||||
|
queryFn: () =>
|
||||||
|
api.get<CatalogEntry[]>(`/catalog/brands/${encodeURIComponent(decodedBrandName)}/catalogs`),
|
||||||
|
staleTime: 1000 * 60 * 30, // 30 min
|
||||||
|
});
|
||||||
|
|
||||||
|
const isMultiCatalog = (catalogs?.length ?? 0) > 1;
|
||||||
|
// Show models when: single-service brand, OR user has selected a sub-catalog
|
||||||
|
const shouldShowModels = !isMultiCatalog || !!activeCatalog;
|
||||||
|
|
||||||
|
const activeCatalogLabel = activeCatalog
|
||||||
|
? (catalogs?.find((c) => c.serviceName === activeCatalog)?.displayName ?? activeCatalog)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const { data: models, isLoading: modelsLoading } = useQuery({
|
||||||
|
queryKey: ["catalog-models", decodedBrandName, activeCatalog ?? null],
|
||||||
|
queryFn: () => {
|
||||||
|
const serviceParam = activeCatalog ? `?service=${encodeURIComponent(activeCatalog)}` : "";
|
||||||
|
return api.get<CatalogVehicle[]>(
|
||||||
|
`/catalog/brands/${encodeURIComponent(decodedBrandName)}/models${serviceParam}`,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
enabled: shouldShowModels && !catalogsLoading,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
if (isMultiCatalog && activeCatalog) {
|
||||||
|
// Go back to catalog selector
|
||||||
|
navigate({ to: ".", search: { catalog: undefined } });
|
||||||
|
} else {
|
||||||
|
navigate({ to: "/dashboard/catalog" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6">
|
||||||
|
{/* Breadcrumb */}
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Button variant="ghost" size="icon" onClick={handleBack}>
|
||||||
|
<ArrowLeft className="size-4" />
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
<Link to="/dashboard/catalog" className="hover:underline">
|
||||||
|
{t("catalog.title")}
|
||||||
|
</Link>
|
||||||
|
{" / "}
|
||||||
|
{isMultiCatalog && activeCatalog ? (
|
||||||
|
<>
|
||||||
|
<Link
|
||||||
|
to="."
|
||||||
|
search={{ catalog: undefined }}
|
||||||
|
className="hover:underline"
|
||||||
|
>
|
||||||
|
{decodedBrandName}
|
||||||
|
</Link>
|
||||||
|
{" / "}
|
||||||
|
<span className="font-medium text-foreground">{activeCatalogLabel}</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<span className="font-medium text-foreground">{decodedBrandName}</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<h1 className="text-xl font-bold">
|
||||||
|
{isMultiCatalog && activeCatalog ? activeCatalogLabel : decodedBrandName}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{catalogsLoading ? (
|
||||||
|
<div className="grid grid-cols-2 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{Array.from({ length: 4 }).map((_, i) => (
|
||||||
|
<Skeleton key={`cat-skel-${i}`} className="h-24 w-full rounded-xl" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : isMultiCatalog && !activeCatalog ? (
|
||||||
|
// Sub-catalog selector
|
||||||
|
<CatalogSelector
|
||||||
|
catalogs={catalogs!}
|
||||||
|
brandName={brandName}
|
||||||
|
brandLabel={decodedBrandName}
|
||||||
|
/>
|
||||||
|
) : modelsLoading ? (
|
||||||
|
<div>
|
||||||
|
<div className="mb-4 flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
|
<Loader2 className="size-4 animate-spin" />
|
||||||
|
{t("catalog.loadingModels")}
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{Array.from({ length: 9 }).map((_, i) => (
|
||||||
|
<Skeleton key={`model-skel-${i}`} className="h-24 w-full rounded-lg" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : !models || models.length === 0 ? (
|
||||||
|
<div className="flex flex-col items-center justify-center py-16 text-center">
|
||||||
|
<Car className="mb-4 size-12 text-muted-foreground/40" />
|
||||||
|
<p className="text-muted-foreground">{t("catalog.noModels")}</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{models.map((model) => (
|
||||||
|
<ModelCard key={model.id} model={model} brandName={brandName} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CatalogSelector({
|
||||||
|
catalogs,
|
||||||
|
brandName,
|
||||||
|
brandLabel,
|
||||||
|
}: {
|
||||||
|
catalogs: CatalogEntry[];
|
||||||
|
brandName: string;
|
||||||
|
brandLabel: string;
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
{t("catalog.selectCatalog")} — {brandLabel}
|
||||||
|
</p>
|
||||||
|
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||||
|
{catalogs.map((cat) => (
|
||||||
|
<Link
|
||||||
|
key={cat.serviceName}
|
||||||
|
to="/dashboard/catalog/$brandName"
|
||||||
|
params={{ brandName }}
|
||||||
|
search={{ catalog: cat.serviceName }}
|
||||||
|
className="flex items-center justify-between rounded-xl border border-border bg-card p-5 transition-colors hover:bg-accent hover:border-accent-foreground/20"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="flex size-10 items-center justify-center rounded-full bg-primary/10">
|
||||||
|
<BookOpen className="size-5 text-primary" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold">{cat.displayName}</p>
|
||||||
|
<p className="text-xs text-muted-foreground">{cat.serviceName}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ChevronRight className="size-4 text-muted-foreground" />
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ModelCard({ model, brandName }: { model: CatalogVehicle; brandName: string }) {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
to="/dashboard/catalog/$brandName/$modelId"
|
||||||
|
params={{ brandName, modelId: model.id }}
|
||||||
|
search={{ body: undefined, engine: undefined, gearbox: undefined }}
|
||||||
|
className="flex flex-col rounded-lg border border-border bg-card p-4 transition-colors hover:bg-accent hover:border-accent-foreground/20"
|
||||||
|
>
|
||||||
|
<p className="font-semibold">{model.model}</p>
|
||||||
|
<div className="mt-1.5 flex flex-wrap gap-x-3 gap-y-0.5 text-xs text-muted-foreground">
|
||||||
|
{model.year && <span>{model.year}</span>}
|
||||||
|
{model.engine && <span>{model.engine}</span>}
|
||||||
|
{model.bodyType && <span>{model.bodyType}</span>}
|
||||||
|
{model.transmission && <span>{model.transmission}</span>}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
import { lazy, Suspense } from "react";
|
||||||
|
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { api } from "@/lib/api-client";
|
||||||
|
import { useTranslation } from "@/lib/i18n";
|
||||||
|
import { Button, Skeleton } from "@sase/ui";
|
||||||
|
import { ArrowLeft } from "lucide-react";
|
||||||
|
import { CategoryGrid } from "@/components/categories/category-grid";
|
||||||
|
|
||||||
|
const SchemaViewer = lazy(() =>
|
||||||
|
import("@/components/schema/schema-viewer").then((mod) => ({
|
||||||
|
default: mod.SchemaViewer,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
function SchemaViewerFallback() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-4 rounded-lg border border-border md:h-[600px] md:flex-row">
|
||||||
|
<div className="flex h-[300px] items-center justify-center md:h-auto md:w-[60%]">
|
||||||
|
<Skeleton className="h-[80%] w-[80%]" />
|
||||||
|
</div>
|
||||||
|
<div className="w-full space-y-3 p-4 md:w-[40%]">
|
||||||
|
<Skeleton className="h-6 w-1/2" />
|
||||||
|
{Array.from({ length: 8 }).map((_, i) => (
|
||||||
|
<Skeleton key={`schema-skel-${i}`} className="h-10 w-full" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Route = createFileRoute(
|
||||||
|
"/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId",
|
||||||
|
)({
|
||||||
|
validateSearch: (search) => ({
|
||||||
|
body: typeof search.body === "string" ? search.body : undefined,
|
||||||
|
engine: typeof search.engine === "string" ? search.engine : undefined,
|
||||||
|
gearbox: typeof search.gearbox === "string" ? search.gearbox : undefined,
|
||||||
|
}),
|
||||||
|
component: CatalogCategoryPage,
|
||||||
|
});
|
||||||
|
|
||||||
|
function buildVariantQuery(body?: string, engine?: string, gearbox?: string): string {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (body) params.set("body", body);
|
||||||
|
if (engine) params.set("engine", engine);
|
||||||
|
if (gearbox) params.set("gearbox", gearbox);
|
||||||
|
const qs = params.toString();
|
||||||
|
return qs ? `?${qs}` : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function CatalogCategoryPage() {
|
||||||
|
const { brandName, modelId, categoryId } = Route.useParams();
|
||||||
|
const search = Route.useSearch();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const body = search.body;
|
||||||
|
const engine = search.engine;
|
||||||
|
const gearbox = search.gearbox;
|
||||||
|
|
||||||
|
const variantSearch = body || engine || gearbox ? { body, engine, gearbox } : undefined;
|
||||||
|
|
||||||
|
const { data, isLoading, error } = useQuery({
|
||||||
|
queryKey: ["catalog-category", modelId, categoryId, body, engine, gearbox],
|
||||||
|
queryFn: () =>
|
||||||
|
api.get<any>(
|
||||||
|
`/catalog/vehicles/${modelId}/categories/${categoryId}${buildVariantQuery(body, engine, gearbox)}`,
|
||||||
|
),
|
||||||
|
enabled: !!modelId && !!categoryId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasChildren = data?.children && data.children.length > 0;
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
if (data?.parentId) {
|
||||||
|
navigate({
|
||||||
|
to: "/dashboard/catalog/$brandName/$modelId/categories/$categoryId",
|
||||||
|
params: { brandName, modelId, categoryId: data.parentId },
|
||||||
|
search: variantSearch ?? { body: undefined, engine: undefined, gearbox: undefined },
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
navigate({
|
||||||
|
to: "/dashboard/catalog/$brandName/$modelId",
|
||||||
|
params: { brandName, modelId },
|
||||||
|
search: variantSearch ?? { body: undefined, engine: undefined, gearbox: undefined },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<Skeleton className="h-8 w-48" />
|
||||||
|
<SchemaViewerFallback />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center justify-center py-16 text-center">
|
||||||
|
<p className="text-muted-foreground">{t("errors.generic")}</p>
|
||||||
|
<Button variant="ghost" className="mt-4" onClick={handleBack}>
|
||||||
|
{t("catalog.backToCategories")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Button variant="ghost" size="icon" onClick={handleBack} title={t("common.back")}>
|
||||||
|
<ArrowLeft className="size-4" />
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
<Link to="/dashboard/catalog" className="hover:underline">
|
||||||
|
{t("catalog.title")}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<h1 className="text-xl font-bold">{data?.name || t("catalog.categories")}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
{hasChildren ? (
|
||||||
|
<CategoryGrid
|
||||||
|
categories={data.children}
|
||||||
|
vehicleId={modelId}
|
||||||
|
catalogMode
|
||||||
|
brandName={brandName}
|
||||||
|
parentId={categoryId}
|
||||||
|
variantSearch={variantSearch}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Suspense fallback={<SchemaViewerFallback />}>
|
||||||
|
<SchemaViewer
|
||||||
|
schemaPic={data?.schemaPics?.[0] ?? null}
|
||||||
|
hotspots={data?.hotspots ?? []}
|
||||||
|
parts={data?.parts ?? []}
|
||||||
|
isLoading={isLoading}
|
||||||
|
vehicleId={modelId}
|
||||||
|
categoryId={categoryId}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { api } from "@/lib/api-client";
|
||||||
|
import { useTranslation } from "@/lib/i18n";
|
||||||
|
import { Button, Skeleton, Card, CardContent, CardHeader, CardTitle } from "@sase/ui";
|
||||||
|
import { ArrowLeft, LayoutGrid, List } from "lucide-react";
|
||||||
|
import { CategoryGrid } from "@/components/categories/category-grid";
|
||||||
|
import { CategoryTree } from "@/components/categories/category-tree";
|
||||||
|
import { PsaVariantSelector } from "@/components/catalog/psa-variant-selector";
|
||||||
|
import { FordVariantSelector } from "@/components/catalog/ford-variant-selector";
|
||||||
|
import { getUserSettings, setUserSetting } from "@/lib/user-settings";
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/dashboard/catalog_/$brandName_/$modelId/")({
|
||||||
|
validateSearch: (search) => ({
|
||||||
|
body: typeof search.body === "string" ? search.body : undefined,
|
||||||
|
engine: typeof search.engine === "string" ? search.engine : undefined,
|
||||||
|
gearbox: typeof search.gearbox === "string" ? search.gearbox : undefined,
|
||||||
|
}),
|
||||||
|
component: CatalogVehiclePage,
|
||||||
|
});
|
||||||
|
|
||||||
|
function buildVariantQuery(body?: string, engine?: string, gearbox?: string): string {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (body) params.set("body", body);
|
||||||
|
if (engine) params.set("engine", engine);
|
||||||
|
if (gearbox) params.set("gearbox", gearbox);
|
||||||
|
const qs = params.toString();
|
||||||
|
return qs ? `?${qs}` : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function CatalogVehiclePage() {
|
||||||
|
const { brandName, modelId } = Route.useParams();
|
||||||
|
const search = Route.useSearch();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const body = search.body;
|
||||||
|
const engine = search.engine;
|
||||||
|
const gearbox = search.gearbox;
|
||||||
|
const hasVariant = !!(body || engine || gearbox);
|
||||||
|
|
||||||
|
const [viewMode, setViewMode] = useState<"grid" | "tree">(
|
||||||
|
() => getUserSettings().categoryViewMode ?? "grid",
|
||||||
|
);
|
||||||
|
|
||||||
|
const decodedBrandName = decodeURIComponent(brandName);
|
||||||
|
|
||||||
|
const changeViewMode = (mode: "grid" | "tree") => {
|
||||||
|
setViewMode(mode);
|
||||||
|
setUserSetting("categoryViewMode", mode);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data: vehicle, isLoading: vehicleLoading } = useQuery({
|
||||||
|
queryKey: ["catalog-vehicle", modelId],
|
||||||
|
queryFn: () => api.get<any>(`/catalog/vehicles/${modelId}`),
|
||||||
|
enabled: !!modelId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isPsa = vehicle?.architecture === "LEGACY_PSA";
|
||||||
|
const isP4Legacy = [
|
||||||
|
"LEGACY_FORD",
|
||||||
|
"LEGACY_VOLVO",
|
||||||
|
].includes(vehicle?.architecture);
|
||||||
|
const showPsaVariantSelector = isPsa && !hasVariant;
|
||||||
|
const showFordVariantSelector = isP4Legacy && !hasVariant;
|
||||||
|
const showVariantSelector = showPsaVariantSelector || showFordVariantSelector;
|
||||||
|
|
||||||
|
const variantSearch = hasVariant ? { body, engine, gearbox } : undefined;
|
||||||
|
|
||||||
|
const { data: categoryTree, isLoading: categoriesLoading } = useQuery({
|
||||||
|
queryKey: ["catalog-category-tree", modelId, body, engine, gearbox],
|
||||||
|
queryFn: () =>
|
||||||
|
api.get<any[]>(`/catalog/vehicles/${modelId}/categories${buildVariantQuery(body, engine, gearbox)}`),
|
||||||
|
enabled: !!modelId && !vehicleLoading && !showVariantSelector,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleVariantSelect = (selectedBody: string, selectedEngine: string, selectedGearbox: string) => {
|
||||||
|
const norm = (v: string) => (v && v !== "_all_" && v !== "_nor_" ? v : undefined);
|
||||||
|
navigate({
|
||||||
|
to: "/dashboard/catalog/$brandName/$modelId",
|
||||||
|
params: { brandName, modelId },
|
||||||
|
search: {
|
||||||
|
// For Ford (catCode) / Volvo (year) variants: keep the meaningful selection,
|
||||||
|
// strip _all_ / _nor_ (no-restriction) values to keep URL clean.
|
||||||
|
// Special case: if ALL are _nor_, pass body="_nor_" so hasVariant=true skips re-showing selector.
|
||||||
|
body: norm(selectedBody) ?? (selectedBody === "_nor_" ? "_nor_" : undefined),
|
||||||
|
engine: norm(selectedEngine),
|
||||||
|
gearbox: norm(selectedGearbox),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (vehicleLoading) {
|
||||||
|
return (
|
||||||
|
<div className="mx-auto max-w-4xl space-y-6">
|
||||||
|
<Skeleton className="h-8 w-64" />
|
||||||
|
<Skeleton className="h-64 w-full" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mx-auto max-w-4xl space-y-6">
|
||||||
|
{/* Header / Breadcrumb */}
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={() =>
|
||||||
|
navigate({
|
||||||
|
to: "/dashboard/catalog/$brandName",
|
||||||
|
params: { brandName },
|
||||||
|
search: { catalog: undefined },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ArrowLeft className="size-4" />
|
||||||
|
</Button>
|
||||||
|
<div>
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
<Link to="/dashboard/catalog" className="hover:underline">
|
||||||
|
{t("catalog.title")}
|
||||||
|
</Link>
|
||||||
|
{" / "}
|
||||||
|
<Link
|
||||||
|
to="/dashboard/catalog/$brandName"
|
||||||
|
params={{ brandName }}
|
||||||
|
search={{ catalog: undefined }}
|
||||||
|
className="hover:underline"
|
||||||
|
>
|
||||||
|
{decodedBrandName}
|
||||||
|
</Link>
|
||||||
|
{" / "}
|
||||||
|
<span className="font-medium text-foreground">
|
||||||
|
{vehicle?.model}
|
||||||
|
</span>
|
||||||
|
{hasVariant && (
|
||||||
|
<>
|
||||||
|
{body && body !== "_all_" && (
|
||||||
|
<><span className="mx-1">/</span><span className="font-medium text-foreground">{body}</span></>
|
||||||
|
)}
|
||||||
|
{engine && engine !== "_all_" && (
|
||||||
|
<><span className="mx-1">/</span><span className="font-medium text-foreground">{engine}</span></>
|
||||||
|
)}
|
||||||
|
{gearbox && gearbox !== "_all_" && (
|
||||||
|
<><span className="mx-1">/</span><span className="font-medium text-foreground">{gearbox}</span></>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<h1 className="text-xl font-bold">
|
||||||
|
{vehicle?.model}
|
||||||
|
{vehicle?.year && <span className="ml-2 text-base font-normal text-muted-foreground">({vehicle.year})</span>}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Vehicle Info */}
|
||||||
|
{vehicle && (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-base">{t("catalog.models")}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="grid grid-cols-2 gap-3 text-sm sm:grid-cols-3">
|
||||||
|
{vehicle.engine && (
|
||||||
|
<div>
|
||||||
|
<span className="text-muted-foreground">Motor:</span>{" "}
|
||||||
|
<span className="font-medium">{vehicle.engine}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{vehicle.bodyType && (
|
||||||
|
<div>
|
||||||
|
<span className="text-muted-foreground">Kasa:</span>{" "}
|
||||||
|
<span className="font-medium">{vehicle.bodyType}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{vehicle.transmission && (
|
||||||
|
<div>
|
||||||
|
<span className="text-muted-foreground">Vites:</span>{" "}
|
||||||
|
<span className="font-medium">{vehicle.transmission}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{vehicle.market && (
|
||||||
|
<div>
|
||||||
|
<span className="text-muted-foreground">Pazar:</span>{" "}
|
||||||
|
<span className="font-medium">{vehicle.market}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Variant Selector OR Categories */}
|
||||||
|
{showPsaVariantSelector ? (
|
||||||
|
<PsaVariantSelector vehicleId={modelId} onSelect={handleVariantSelect} />
|
||||||
|
) : showFordVariantSelector ? (
|
||||||
|
<FordVariantSelector vehicleId={modelId} onSelect={handleVariantSelect} />
|
||||||
|
) : (
|
||||||
|
<Card>
|
||||||
|
<CardHeader className="flex flex-row items-center justify-between">
|
||||||
|
<CardTitle className="text-base">{t("catalog.categories")}</CardTitle>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => changeViewMode("grid")}
|
||||||
|
className={`rounded p-1.5 ${viewMode === "grid" ? "bg-accent" : "text-muted-foreground hover:text-foreground"}`}
|
||||||
|
>
|
||||||
|
<LayoutGrid className="size-4" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => changeViewMode("tree")}
|
||||||
|
className={`rounded p-1.5 ${viewMode === "tree" ? "bg-accent" : "text-muted-foreground hover:text-foreground"}`}
|
||||||
|
>
|
||||||
|
<List className="size-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
{categoriesLoading ? (
|
||||||
|
<div className="space-y-2">
|
||||||
|
{Array.from({ length: 8 }).map((_, i) => (
|
||||||
|
<Skeleton key={`cat-skel-${i}`} className="h-8 w-full" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : viewMode === "grid" ? (
|
||||||
|
<CategoryGrid
|
||||||
|
categories={categoryTree || []}
|
||||||
|
vehicleId={modelId}
|
||||||
|
catalogMode
|
||||||
|
brandName={brandName}
|
||||||
|
variantSearch={variantSearch}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<CategoryTree
|
||||||
|
categories={categoryTree || []}
|
||||||
|
vehicleId={modelId}
|
||||||
|
catalogMode
|
||||||
|
brandName={brandName}
|
||||||
|
variantSearch={variantSearch}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
> **Automotive parts search platform** for the Turkish market with VIN decoding, subscription-based access, and multi-source parts catalog integration.
|
> **Automotive parts search platform** for the Turkish market with VIN decoding, subscription-based access, and multi-source parts catalog integration.
|
||||||
> **URL:** https://sase.tr | **Repo:** `/home/s/ss`
|
> **URL:** https://sase.tr | **Repo:** `/home/s/ss`
|
||||||
|
|
||||||
Generated: 2026-02-17
|
Generated: 2026-03-02
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -108,12 +108,13 @@ sase.tr/
|
|||||||
│ │ │ ├── vehicles/ # VIN decoding + vehicle history
|
│ │ │ ├── vehicles/ # VIN decoding + vehicle history
|
||||||
│ │ │ ├── categories/ # Parts category tree
|
│ │ │ ├── categories/ # Parts category tree
|
||||||
│ │ │ ├── parts/ # Auto parts catalog
|
│ │ │ ├── parts/ # Auto parts catalog
|
||||||
|
│ │ │ ├── catalog/ # VIN-less catalog browser (PL24 model families)
|
||||||
│ │ │ ├── translations/ # Automotive term translations
|
│ │ │ ├── translations/ # Automotive term translations
|
||||||
│ │ │ ├── admin/ # Admin dashboard endpoints
|
│ │ │ ├── admin/ # Admin dashboard endpoints
|
||||||
│ │ │ ├── analytics/ # Usage analytics tracking
|
│ │ │ ├── analytics/ # Usage analytics tracking
|
||||||
│ │ │ ├── common/ # Shared guards, pipes, interceptors, filters, decorators
|
│ │ │ ├── common/ # Shared guards, pipes, interceptors, filters, decorators
|
||||||
│ │ │ ├── config/ # Runtime configuration
|
│ │ │ ├── config/ # Runtime configuration
|
||||||
│ │ │ ├── database/ # Drizzle ORM setup + schemas
|
│ │ │ ├── database/ # Drizzle ORM setup + schemas (core, emex, pl24, parts-catalogs, relations)
|
||||||
│ │ │ ├── redis/ # Redis client module
|
│ │ │ ├── redis/ # Redis client module
|
||||||
│ │ │ ├── storage/ # MinIO/S3 service
|
│ │ │ ├── storage/ # MinIO/S3 service
|
||||||
│ │ │ ├── email/ # Postal email service
|
│ │ │ ├── email/ # Postal email service
|
||||||
@@ -122,6 +123,7 @@ sase.tr/
|
|||||||
│ │ │ └── integrations/ # External API integrations
|
│ │ │ └── integrations/ # External API integrations
|
||||||
│ │ │ ├── corgi/ # Offline VIN WMI decoder
|
│ │ │ ├── corgi/ # Offline VIN WMI decoder
|
||||||
│ │ │ ├── pl24/ # PL24 parts catalog API + parsers
|
│ │ │ ├── pl24/ # PL24 parts catalog API + parsers
|
||||||
|
│ │ │ ├── parts-catalogs/ # PartsCatalogs API (groups, parts, auth)
|
||||||
│ │ │ ├── emex/ # EMEX scraper (Playwright)
|
│ │ │ ├── emex/ # EMEX scraper (Playwright)
|
||||||
│ │ │ └── vin-api/ # NHTSA VIN API fallback
|
│ │ │ └── vin-api/ # NHTSA VIN API fallback
|
||||||
│ │ ├── drizzle.config.ts
|
│ │ ├── drizzle.config.ts
|
||||||
@@ -136,7 +138,7 @@ sase.tr/
|
|||||||
│ │ ├── index.tsx # Landing page
|
│ │ ├── index.tsx # Landing page
|
||||||
│ │ ├── _auth.tsx # Auth layout (login, register, etc.)
|
│ │ ├── _auth.tsx # Auth layout (login, register, etc.)
|
||||||
│ │ ├── dashboard.tsx # Dashboard layout (protected)
|
│ │ ├── dashboard.tsx # Dashboard layout (protected)
|
||||||
│ │ └── dashboard/ # Dashboard subroutes
|
│ │ └── dashboard/ # Dashboard subroutes (catalog, vehicles, admin, etc.)
|
||||||
│ ├── components/ # React components
|
│ ├── components/ # React components
|
||||||
│ │ ├── admin/ # DailyChart
|
│ │ ├── admin/ # DailyChart
|
||||||
│ │ ├── schema/ # SchemaViewer, HotspotOverlay, PartsPanel, SchemaToolbar
|
│ │ ├── schema/ # SchemaViewer, HotspotOverlay, PartsPanel, SchemaToolbar
|
||||||
@@ -195,6 +197,7 @@ sase.tr/
|
|||||||
| **VehiclesModule** | module, service, controller, spec | VIN decode (multi-source fallback), vehicle history, brand access check |
|
| **VehiclesModule** | module, service, controller, spec | VIN decode (multi-source fallback), vehicle history, brand access check |
|
||||||
| **CategoriesModule** | module, service, controller, spec | Hierarchical category tree, schema pictures |
|
| **CategoriesModule** | module, service, controller, spec | Hierarchical category tree, schema pictures |
|
||||||
| **PartsModule** | module, service, controller, spec | Parts by category, OEM code search |
|
| **PartsModule** | module, service, controller, spec | Parts by category, OEM code search |
|
||||||
|
| **CatalogModule** | module, service, controller, dto | VIN-less PL24 catalog browser: brands, models, category trees, parts |
|
||||||
| **TranslationsModule** | module, service, controller, spec | Automotive term translation (Redis → DB → Dictionary fallback) |
|
| **TranslationsModule** | module, service, controller, spec | Automotive term translation (Redis → DB → Dictionary fallback) |
|
||||||
| **AdminModule** | module, service, controller, spec | Dashboard stats, user management, payment approval, analytics |
|
| **AdminModule** | module, service, controller, spec | Dashboard stats, user management, payment approval, analytics |
|
||||||
| **AnalyticsModule** | module, service, controller | Usage analytics tracking |
|
| **AnalyticsModule** | module, service, controller | Usage analytics tracking |
|
||||||
@@ -230,12 +233,15 @@ sase.tr/
|
|||||||
|
|
||||||
### Integrations
|
### Integrations
|
||||||
|
|
||||||
**VIN Decode Fallback Chain:** Corgi (offline WMI) → PL24 API → EMEX Scraper → NHTSA VIN API
|
**VIN Decode Fallback Chain:** Corgi (offline WMI) → **PartsCatalogs API** → PL24 API → EMEX Scraper → NHTSA VIN API
|
||||||
|
|
||||||
|
**Category Fetch Fallback Chain (per source):** DB cache → PL24 → PartsCatalogs → EMEX (triggered by `getCategoryTree`)
|
||||||
|
|
||||||
| Integration | Type | Path | Notes |
|
| Integration | Type | Path | Notes |
|
||||||
|-------------|------|------|-------|
|
|-------------|------|------|-------|
|
||||||
| **Corgi** | Offline DB | `corgi/` | WMI database for brand identification (+ spec) |
|
| **Corgi** | Offline DB | `corgi/` | WMI database for brand identification (+ spec) |
|
||||||
| **PL24** | REST API | `pl24/` | Multi-brand catalog API + auth + parsers (BMW, Mercedes, Generic, Ford Legacy) |
|
| **PL24** | REST API | `pl24/` | Multi-brand catalog API + auth + parsers (BMW, Mercedes, Generic, Ford Legacy) |
|
||||||
|
| **PartsCatalogs** | REST API | `parts-catalogs/` | Multi-brand catalog API. Files: service, auth-service, module, types. Supports fetchGroups, fetchParts with parameterized car queries |
|
||||||
| **EMEX** | Browser scraper | `emex/` | Playwright-based (emexdwc.ae), async via BullMQ. Files: service, browser, mapper, types |
|
| **EMEX** | Browser scraper | `emex/` | Playwright-based (emexdwc.ae), async via BullMQ. Files: service, browser, mapper, types |
|
||||||
| **VIN-API** | REST API | `vin-api/` | NHTSA VIN decoder (last-resort fallback) |
|
| **VIN-API** | REST API | `vin-api/` | NHTSA VIN decoder (last-resort fallback) |
|
||||||
| **Iyzico** | Payment API | — | Turkish payment processor for card payments |
|
| **Iyzico** | Payment API | — | Turkish payment processor for card payments |
|
||||||
@@ -249,6 +255,7 @@ sase.tr/
|
|||||||
- `core.ts` — Main application tables
|
- `core.ts` — Main application tables
|
||||||
- `emex.ts` — EMEX scraper cache tables
|
- `emex.ts` — EMEX scraper cache tables
|
||||||
- `pl24.ts` — PL24 catalog cache tables
|
- `pl24.ts` — PL24 catalog cache tables
|
||||||
|
- `parts-catalogs.ts` — PartsCatalogs API cache tables
|
||||||
- `relations.ts` — Drizzle ORM relationships
|
- `relations.ts` — Drizzle ORM relationships
|
||||||
|
|
||||||
#### Core Tables
|
#### Core Tables
|
||||||
@@ -289,20 +296,28 @@ payments
|
|||||||
└── Indexes: userId, status
|
└── Indexes: userId, status
|
||||||
|
|
||||||
vehicles
|
vehicles
|
||||||
├── id (uuid, PK), userId → users, vin, brandId → brands
|
├── id (uuid, PK), vin (unique), brandId → brands
|
||||||
├── brandName, model, year, engine, transmission, bodyType, market
|
├── brandName, model, year, engine, transmission, bodyType, market
|
||||||
├── rawData (jsonb), source
|
├── rawData (jsonb), source
|
||||||
└── Indexes: userId, vin, unique(userId, vin)
|
└── Indexes: vin
|
||||||
|
Note: Shared across users; access via userVehicles junction table
|
||||||
|
|
||||||
|
userVehicles (junction)
|
||||||
|
├── userId → users, vehicleId → vehicles
|
||||||
|
├── lastAccessedAt
|
||||||
|
└── Unique: (userId, vehicleId)
|
||||||
|
|
||||||
categories
|
categories
|
||||||
├── id (uuid, PK), vehicleId → vehicles, name, nameOriginal
|
├── id (uuid, PK), vehicleId → vehicles (nullable), catalogVehicleId → catalogVehicles (nullable)
|
||||||
├── parentId (self-ref), externalId, source
|
├── name, nameOriginal, parentId (self-ref), externalId, source
|
||||||
└── Indexes: vehicleId, parentId
|
└── Indexes: vehicleId, parentId
|
||||||
|
Note: DUAL FK — exactly one of vehicleId (VIN-based) or catalogVehicleId (VIN-less) is non-null per row
|
||||||
|
|
||||||
parts
|
parts
|
||||||
├── id (uuid, PK), vehicleId → vehicles, categoryId → categories
|
├── id (uuid, PK), vehicleId → vehicles (nullable), catalogVehicleId → catalogVehicles (nullable)
|
||||||
├── oemCode, name, nameOriginal, description, quantity, position, hotspotIndex
|
├── categoryId → categories, oemCode, name, nameOriginal, description, quantity, position, hotspotIndex
|
||||||
└── Indexes: vehicleId, categoryId, oemCode
|
└── Indexes: vehicleId, categoryId, oemCode
|
||||||
|
Note: DUAL FK — same pattern as categories
|
||||||
|
|
||||||
schemaPics
|
schemaPics
|
||||||
├── id (uuid, PK), categoryId → categories
|
├── id (uuid, PK), categoryId → categories
|
||||||
@@ -324,11 +339,20 @@ passwordResetTokens
|
|||||||
|
|
||||||
emexCategoryTranslations
|
emexCategoryTranslations
|
||||||
└── id, originalName (unique), translatedName, isManual
|
└── id, originalName (unique), translatedName, isManual
|
||||||
|
|
||||||
|
catalogVehicles
|
||||||
|
├── id (uuid, PK), source (pl24), serviceName, brandName, brandId → brands
|
||||||
|
├── model, year, engine, bodyType, transmission, market
|
||||||
|
├── serviceVehicleId, catalogPath, architecture (P5_MODERN/P4_LEGACY)
|
||||||
|
├── metadata (jsonb), categoriesFetched (bool)
|
||||||
|
└── Unique: (serviceName, serviceVehicleId)
|
||||||
|
Note: categories and parts tables both have catalogVehicleId FK (nullable) for VIN-less catalog data
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Integration Tables
|
#### Integration Tables
|
||||||
- `pl24_*` — PL24 catalog cache (catalogs, vehicles, VINs, part groups, parts, schemas)
|
- `pl24_*` — PL24 catalog cache (catalogs, vehicles, VINs, part groups, parts, schemas)
|
||||||
- `emex_*` — EMEX scraper cache (similar structure with translations)
|
- `emex_*` — EMEX scraper cache (similar structure with translations)
|
||||||
|
- `parts_catalogs_*` — PartsCatalogs API cache (defined in `parts-catalogs.ts`)
|
||||||
|
|
||||||
### Job Queues
|
### Job Queues
|
||||||
|
|
||||||
@@ -337,10 +361,11 @@ emexCategoryTranslations
|
|||||||
| Queue | Trigger | Schedule | Action |
|
| Queue | Trigger | Schedule | Action |
|
||||||
|-------|---------|----------|--------|
|
|-------|---------|----------|--------|
|
||||||
| `EMEX_SCRAPE` | On-demand (VIN decode) | — | Scrapes EMEX via Playwright, stores results |
|
| `EMEX_SCRAPE` | On-demand (VIN decode) | — | Scrapes EMEX via Playwright, stores results |
|
||||||
|
| `CATALOG_PREFETCH` | On-demand (after VIN decode) | — | Prefetches category tree + parts for all sources (depth-limited, rate-limited, cooldown-guarded). Handled by `PrefetchWorkerService`. |
|
||||||
| `SUBSCRIPTION_EXPIRY` | Cron | Daily 3:00 AM | Expires ended subscriptions, removes brand access |
|
| `SUBSCRIPTION_EXPIRY` | Cron | Daily 3:00 AM | Expires ended subscriptions, removes brand access |
|
||||||
| `QUERY_CLEANUP` | Cron | Weekly Sun 4:00 AM | Cleans old query log entries |
|
| `QUERY_CLEANUP` | Cron | Weekly Sun 4:00 AM | Cleans old query log entries |
|
||||||
|
|
||||||
**Files:** `apps/api/src/jobs/` — `jobs.module.ts`, `bull.config.ts`, `processors/`, `queues/`
|
**Files:** `apps/api/src/jobs/` — `jobs.module.ts`, `bull.config.ts`, `processors/`, `queues/`, `prefetch-worker.service.ts`, `prefetch-utils.ts`, `prefetch.types.ts`
|
||||||
|
|
||||||
### Telemetry
|
### Telemetry
|
||||||
|
|
||||||
@@ -440,6 +465,21 @@ Instrumentation: Express, HTTP, ioredis, NestJS Core, BullMQ, Drizzle ORM
|
|||||||
| `GET` | `/api/parts/search?oem=` | User | Search parts by OEM code |
|
| `GET` | `/api/parts/search?oem=` | User | Search parts by OEM code |
|
||||||
| `GET` | `/api/parts/:id` | User | Part by ID |
|
| `GET` | `/api/parts/:id` | User | Part by ID |
|
||||||
|
|
||||||
|
#### Catalog (VIN-less Browser)
|
||||||
|
| Method | Path | Auth | Description |
|
||||||
|
|--------|------|------|-------------|
|
||||||
|
| `GET` | `/api/catalog/brands` | User | List PL24 brands with access flags (hasAccess per subscription) |
|
||||||
|
| `GET` | `/api/catalog/brands/:brandName/catalogs` | User | Service catalog list for a brand (multi-catalog brands like Ford) |
|
||||||
|
| `GET` | `/api/catalog/brands/:brandName/models` | User | Model list for a brand (`?service=` optional) — DB cache → PL24 fetch |
|
||||||
|
| `GET` | `/api/catalog/vehicles/:id` | User | Get a catalog vehicle by ID |
|
||||||
|
| `GET` | `/api/catalog/vehicles/:id/ford-config` | User | Ford model-year/engine/gearbox options (Legacy Ford brands) |
|
||||||
|
| `GET` | `/api/catalog/vehicles/:id/psa-bodies` | User | PSA body style options (Citroën/Peugeot) |
|
||||||
|
| `GET` | `/api/catalog/vehicles/:id/psa-engines` | User | PSA engine options for a given body (`?body=`) |
|
||||||
|
| `GET` | `/api/catalog/vehicles/:id/psa-gearboxes` | User | PSA gearbox options for a given body+engine (`?body=&engine=`) |
|
||||||
|
| `GET` | `/api/catalog/vehicles/:id/categories` | User | Category tree (`?body=&engine=&gearbox=`); Redis cached 2h |
|
||||||
|
| `GET` | `/api/catalog/vehicles/:id/categories/:categoryId` | User | Sub-categories or parts+schema (`?body=&engine=&gearbox=`); lazy PL24 fetch |
|
||||||
|
| `POST` | `/api/catalog/explore/:serviceName` | Admin | Explore PL24 service structure (discovery tool) |
|
||||||
|
|
||||||
#### Translations
|
#### Translations
|
||||||
| Method | Path | Auth | Description |
|
| Method | Path | Auth | Description |
|
||||||
|--------|------|------|-------------|
|
|--------|------|------|-------------|
|
||||||
@@ -459,6 +499,11 @@ Instrumentation: Express, HTTP, ioredis, NestJS Core, BullMQ, Drizzle ORM
|
|||||||
| `GET` | `/api/admin/referrals` | Admin | Referral stats (paginated) |
|
| `GET` | `/api/admin/referrals` | Admin | Referral stats (paginated) |
|
||||||
| `GET` | `/api/admin/stats/daily` | Admin | Daily VIN decode stats (last 30 days) |
|
| `GET` | `/api/admin/stats/daily` | Admin | Daily VIN decode stats (last 30 days) |
|
||||||
|
|
||||||
|
#### Analytics
|
||||||
|
| Method | Path | Auth | Description |
|
||||||
|
|--------|------|------|-------------|
|
||||||
|
| `POST` | `/api/analytics/oem-copy` | User | Track OEM code copy event (oemCode, partId?, vehicleId?, categoryId?) |
|
||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
|
|
||||||
**Provider:** Better Auth 1.2
|
**Provider:** Better Auth 1.2
|
||||||
@@ -481,7 +526,7 @@ Flow:
|
|||||||
|
|
||||||
### Routes & Pages
|
### Routes & Pages
|
||||||
|
|
||||||
**Router:** TanStack Router (file-based, auto-generated route tree — 31 files)
|
**Router:** TanStack Router (file-based, auto-generated route tree — 36 files)
|
||||||
|
|
||||||
#### Public
|
#### Public
|
||||||
| Path | Route File | Description |
|
| Path | Route File | Description |
|
||||||
@@ -490,7 +535,8 @@ Flow:
|
|||||||
| `/pricing` | `routes/pricing.tsx` | Plan comparison (1/2/3 brand, full package) |
|
| `/pricing` | `routes/pricing.tsx` | Plan comparison (1/2/3 brand, full package) |
|
||||||
| `/about` | `routes/about.tsx` | About page |
|
| `/about` | `routes/about.tsx` | About page |
|
||||||
| `/contact` | `routes/contact.tsx` | Contact page |
|
| `/contact` | `routes/contact.tsx` | Contact page |
|
||||||
| `/blog` | `routes/blog.tsx` | Blog page |
|
| `/blog` | `routes/blog.tsx` | Blog listing page |
|
||||||
|
| `/blog/:slug` | `routes/blog_/$slug.tsx` | Blog post detail (SEO pre-rendered) |
|
||||||
| `/demo` | `routes/demo.tsx` | Demo page |
|
| `/demo` | `routes/demo.tsx` | Demo page |
|
||||||
| `/privacy` | `routes/privacy.tsx` | Privacy policy |
|
| `/privacy` | `routes/privacy.tsx` | Privacy policy |
|
||||||
| `/terms` | `routes/terms.tsx` | Terms of service |
|
| `/terms` | `routes/terms.tsx` | Terms of service |
|
||||||
@@ -517,6 +563,14 @@ Flow:
|
|||||||
| `/dashboard/vehicles/$id` | `routes/dashboard/vehicles_/$id/index.tsx` | Vehicle details |
|
| `/dashboard/vehicles/$id` | `routes/dashboard/vehicles_/$id/index.tsx` | Vehicle details |
|
||||||
| `/dashboard/vehicles/$id/categories/$categoryId` | `routes/dashboard/vehicles_/$id/categories_/$categoryId.tsx` | Interactive schema + parts table |
|
| `/dashboard/vehicles/$id/categories/$categoryId` | `routes/dashboard/vehicles_/$id/categories_/$categoryId.tsx` | Interactive schema + parts table |
|
||||||
|
|
||||||
|
#### Catalog Browser (VIN-less, Protected)
|
||||||
|
| Path | Route File | Description |
|
||||||
|
|------|------------|-------------|
|
||||||
|
| `/dashboard/catalog` | `routes/dashboard/catalog/index.tsx` | Brand grid with hasAccess flags; locked brands show upgrade CTA |
|
||||||
|
| `/dashboard/catalog/$brandName` | `routes/dashboard/catalog_/$brandName/index.tsx` | Model list for brand (fetched from PL24) |
|
||||||
|
| `/dashboard/catalog/$brandName/$modelId` | `routes/dashboard/catalog_/$brandName_/$modelId/index.tsx` | Vehicle details + category tree (grid/tree toggle) |
|
||||||
|
| `/dashboard/catalog/$brandName/$modelId/categories/$categoryId` | `routes/dashboard/catalog_/$brandName_/$modelId/categories_/$categoryId.tsx` | Category sub-groups or schema+parts (lazy PL24 fetch) |
|
||||||
|
|
||||||
#### Admin (Role-based)
|
#### Admin (Role-based)
|
||||||
| Path | Route File | Description |
|
| Path | Route File | Description |
|
||||||
|------|------------|-------------|
|
|------|------------|-------------|
|
||||||
@@ -537,12 +591,15 @@ Flow:
|
|||||||
| **SchemaToolbar** | `components/schema/schema-toolbar.tsx` | Zoom/reset/fullscreen controls |
|
| **SchemaToolbar** | `components/schema/schema-toolbar.tsx` | Zoom/reset/fullscreen controls |
|
||||||
| **BrandSelector** | `components/subscription/brand-selector.tsx` | Brand grid with plan-enforced max selection |
|
| **BrandSelector** | `components/subscription/brand-selector.tsx` | Brand grid with plan-enforced max selection |
|
||||||
| **VehicleCard** | `components/vehicles/vehicle-card.tsx` | Vehicle info card (VIN, brand, model, year) |
|
| **VehicleCard** | `components/vehicles/vehicle-card.tsx` | Vehicle info card (VIN, brand, model, year) |
|
||||||
|
| **VehicleSelectModal** | `components/vehicles/vehicle-select-modal.tsx` | Modal for selecting a vehicle from history (used during VIN decode flow) |
|
||||||
| **VinInput** | `components/vehicles/vin-input.tsx` | VIN entry input component |
|
| **VinInput** | `components/vehicles/vin-input.tsx` | VIN entry input component |
|
||||||
| **CategoryTree** | `components/categories/category-tree.tsx` | Recursive expandable category hierarchy |
|
| **CategoryTree** | `components/categories/category-tree.tsx` | Recursive expandable category hierarchy |
|
||||||
| **CategoryGrid** | `components/categories/category-grid.tsx` | Grid layout for category browsing |
|
| **CategoryGrid** | `components/categories/category-grid.tsx` | Grid layout for category browsing |
|
||||||
| **DailyChart** | `components/admin/daily-chart.tsx` | Daily VIN decode stats chart |
|
| **DailyChart** | `components/admin/daily-chart.tsx` | Daily VIN decode stats chart |
|
||||||
| **PaymentContent** | `components/payment/payment-content.tsx` | Payment form and flow |
|
| **PaymentContent** | `components/payment/payment-content.tsx` | Payment form and flow |
|
||||||
| **SettingsContent** | `components/settings/settings-content.tsx` | User settings panel content |
|
| **SettingsContent** | `components/settings/settings-content.tsx` | User settings panel content |
|
||||||
|
| **PsaVariantSelector** | `components/catalog/psa-variant-selector.tsx` | PSA (Citroën/Peugeot) body/engine/gearbox picker for VIN-less catalog |
|
||||||
|
| **FordVariantSelector** | `components/catalog/ford-variant-selector.tsx` | Ford model-year/engine/gearbox picker for VIN-less catalog |
|
||||||
|
|
||||||
**UI primitives** from `@sase/ui`: Button, Card, Input, Label, Badge, Dialog, Tabs, Separator, Skeleton
|
**UI primitives** from `@sase/ui`: Button, Card, Input, Label, Badge, Dialog, Tabs, Separator, Skeleton
|
||||||
|
|
||||||
@@ -554,6 +611,7 @@ Flow:
|
|||||||
| `useAuth()` | Auth state + Better Auth client (`user`, `isAdmin`, `signIn`, `signUp`, `signOut`, `session`) |
|
| `useAuth()` | Auth state + Better Auth client (`user`, `isAdmin`, `signIn`, `signUp`, `signOut`, `session`) |
|
||||||
| `useCategoryParts(vehicleId, categoryId)` | TanStack Query for schema + parts + hotspots |
|
| `useCategoryParts(vehicleId, categoryId)` | TanStack Query for schema + parts + hotspots |
|
||||||
| `useSchemaInteraction()` | Pan/zoom/pinch event handlers for schema viewer |
|
| `useSchemaInteraction()` | Pan/zoom/pinch event handlers for schema viewer |
|
||||||
|
| `usePageMeta(options)` | Sets `<title>`, meta description, canonical, OG/Twitter tags; restores defaults on unmount |
|
||||||
|
|
||||||
**Stores (Zustand):**
|
**Stores (Zustand):**
|
||||||
| Store | State |
|
| Store | State |
|
||||||
@@ -643,6 +701,7 @@ Dependencies: Radix UI (dialog, dropdown-menu, label, popover, select, separator
|
|||||||
### Playwright 1.50
|
### Playwright 1.50
|
||||||
- Installed at root level (`package.json`)
|
- Installed at root level (`package.json`)
|
||||||
- Used by EMEX integration (`emex.browser.ts`) for web scraping
|
- Used by EMEX integration (`emex.browser.ts`) for web scraping
|
||||||
|
- Used by PartsCatalogs auth service for JWT capture via Playwright
|
||||||
- Test scripts in `scripts/` (vin-e2e-test.js)
|
- Test scripts in `scripts/` (vin-e2e-test.js)
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -657,6 +716,13 @@ Dependencies: Radix UI (dialog, dropdown-menu, label, popover, select, separator
|
|||||||
| Redis 7.4 | `redis:7.4-alpine` | 127.0.0.1:6379 | `redis_data` |
|
| Redis 7.4 | `redis:7.4-alpine` | 127.0.0.1:6379 | `redis_data` |
|
||||||
| MinIO | `minio/minio` | 9000 (API), 9001 (Console) | `minio_data` |
|
| MinIO | `minio/minio` | 9000 (API), 9001 (Console) | `minio_data` |
|
||||||
|
|
||||||
|
### SEO Infrastructure
|
||||||
|
|
||||||
|
- `apps/web/scripts/prerender.mjs` — Pre-renders public pages to static HTML (landing, blog posts, pricing, etc.) for crawler/bot visibility
|
||||||
|
- `apps/web/public/robots.txt` — Crawl directives with sitemap reference
|
||||||
|
- `apps/web/public/sitemap.xml` — Static sitemap for public pages
|
||||||
|
- `apps/web/index.html` — Contains default OG/Twitter meta tags; `usePageMeta()` overrides at runtime per page
|
||||||
|
|
||||||
### Nginx (`docker/nginx/sites/`)
|
### Nginx (`docker/nginx/sites/`)
|
||||||
|
|
||||||
- `sase.tr.conf` — Frontend SPA + `/api` proxy + `/collect/` Faro telemetry CORS proxy + gzip (level 6) + 1-year asset cache + security headers
|
- `sase.tr.conf` — Frontend SPA + `/api` proxy + `/collect/` Faro telemetry CORS proxy + gzip (level 6) + 1-year asset cache + security headers
|
||||||
|
|||||||
BIN
docs/pl24-catalog/_brandmenu-screenshot.png
Normal file
|
After Width: | Height: | Size: 237 KiB |
58
docs/pl24-catalog/_summary.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# PL24 Katalog Keşif Özeti
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:32:39.082Z
|
||||||
|
|
||||||
|
## Sonuçlar
|
||||||
|
|
||||||
|
| Marka | Slug | Durum | API İstek Sayısı |
|
||||||
|
|-------|------|-------|-----------------|
|
||||||
|
| Alpine | alpine | tamamlandı | 18 |
|
||||||
|
| Audi | audi | tamamlandı | 17 |
|
||||||
|
| Bentley | bentley | tamamlandı | 7 |
|
||||||
|
| BMW | bmw | tamamlandı | 11 |
|
||||||
|
| BMW Classic | bmw-classic | tamamlandı | 10 |
|
||||||
|
| BMW Motorrad | bmw-motorrad | tamamlandı | 10 |
|
||||||
|
| BMW Motorrad Classic | bmw-motorrad-classic | tamamlandı | 10 |
|
||||||
|
| Citroën | citro-n | tamamlandı | 0 |
|
||||||
|
| Citroën DS | citro-n-ds | tamamlandı | 0 |
|
||||||
|
| Cupra | cupra | tamamlandı | 7 |
|
||||||
|
| Dacia | dacia | tamamlandı | 9 |
|
||||||
|
| Ford | ford | tamamlandı | 13 |
|
||||||
|
| Ford Commercial | ford-commercial | tamamlandı | 12 |
|
||||||
|
| Hyundai | hyundai | tamamlandı | 0 |
|
||||||
|
| Infiniti | infiniti | tamamlandı | 0 |
|
||||||
|
| Jaguar | jaguar | tamamlandı | 7 |
|
||||||
|
| Kia | kia | tamamlandı | 0 |
|
||||||
|
| Land Rover | land-rover | tamamlandı | 7 |
|
||||||
|
| Lexus | lexus | tamamlandı | 11 |
|
||||||
|
| MAN | man | tamamlandı | 6 |
|
||||||
|
| Mercedes-Benz | mercedes-benz | tamamlandı | 6 |
|
||||||
|
| Mercedes-Benz Classic | mercedes-benz-classic | tamamlandı | 7 |
|
||||||
|
| Mercedes-Benz Trucks | mercedes-benz-trucks | tamamlandı | 9 |
|
||||||
|
| Mercedes-Benz Unimog | mercedes-benz-unimog | tamamlandı | 6 |
|
||||||
|
| Mercedes-Benz Vans | mercedes-benz-vans | tamamlandı | 8 |
|
||||||
|
| MINI | mini | tamamlandı | 10 |
|
||||||
|
| MINI Classic | mini-classic | tamamlandı | 10 |
|
||||||
|
| Mitsubishi | mitsubishi | tamamlandı | 9 |
|
||||||
|
| Nissan | nissan | tamamlandı | 0 |
|
||||||
|
| Opel | opel | tamamlandı | 0 |
|
||||||
|
| Peugeot | peugeot | tamamlandı | 0 |
|
||||||
|
| Polestar | polestar | tamamlandı | 0 |
|
||||||
|
| Porsche | porsche | tamamlandı | 7 |
|
||||||
|
| Porsche Classic | porsche-classic | tamamlandı | 7 |
|
||||||
|
| Renault | renault | tamamlandı | 9 |
|
||||||
|
| SEAT | seat | tamamlandı | 7 |
|
||||||
|
| Škoda | koda | tamamlandı | 7 |
|
||||||
|
| smart | smart | tamamlandı | 8 |
|
||||||
|
| Suzuki | suzuki | tamamlandı | 8 |
|
||||||
|
| Toyota | toyota | tamamlandı | 11 |
|
||||||
|
| Vauxhall | vauxhall | tamamlandı | 0 |
|
||||||
|
| Volkswagen | volkswagen | tamamlandı | 7 |
|
||||||
|
| Volkswagen Classic | volkswagen-classic | tamamlandı | 7 |
|
||||||
|
| Volkswagen Commercial Vehicles | volkswagen-commercial-vehicles | tamamlandı | 7 |
|
||||||
|
| Volvo | volvo | tamamlandı | 0 |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
- Bu dosya otomatik olarak oluşturulmuştur
|
||||||
|
- Her marka için ayrıntı: `{slug}.md`
|
||||||
156
docs/pl24-catalog/alpine.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# Alpine — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:20:40.295Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /auth/ext/api/1.1/authorize
|
||||||
|
- **Method:** POST
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/auth/ext/api/1.1/authorize`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXphdGlvbiIsImFsZyI6IlJTMjU2In0.eyJpYXQiOjE3NzE5MzkyNDAsImV4cCI6MTc3MTkzOTg0MCwic2lkIjoiN2h4RHEyYmtVaWtHc3F1LURLeldxb25DX25xTHE5SXkiLCJhaWQiOjE0OTg1ODMsInVpZCI6MjE0NDA5NCwic2VydmljZXMiOlsicGwyNC10bHMtcGl`
|
||||||
|
- **Çağrı sayısı:** 3
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/TR/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/TR/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-manufacturer/ext/api/1.0/manufacturers/
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-manufacturer/ext/api/1.0/manufacturers/?lang=tr&country=TR&relativeLink=true`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"manufacturers":[{"imgSrc":"/carbrands/alpine/pl24_cat_logo_app.png","label":"Alpine","link":"/pl24-app/alpine_parts/0/0?lang=tr","serviceName":"alpine_parts","translation":"Alpine","architecture":"P5","catmetaUrl":"/p5renault/extern/catmeta?serviceName=alpine_parts&country=TR&lang=tr"},{"imgSrc":"`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /cart/ext/api/3.0
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/cart/ext/api/3.0?jwt=eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjo...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"_links":{"carts":{"href":"/cart/ext/api/2.0/carts?catalogService={catalogService}","templated":true},"templates":{"href":"/cart/ext/api/2.0/templates?catalog={catalog}","templated":true}}}`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /p5renault/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/catmeta?serviceName=alpine_parts&country=TR&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Alpine", "user24Brand" : "Alpine", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAAXNSR0IArs4c6QAAABtQTFRFR3BMAGu9AGq7AG26AG27AG66AG+6AG+6AG+6DNix8gAAAAh0Uk5TABA/b57E5PR1jDNtAAAFMUlEQVR42u2cTW/jNhRF9eFm7WKUzFYFaidLrcZe2qtq`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /lex-campaign/ext/api/1.0/DestinationContent
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/lex-campaign/ext/api/1.0/DestinationContent?destinationId=catalog_alpine_parts&countryCode=T...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"components":[]}`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-dealers/ext/api/2.0/catalogDealers
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-dealers/ext/api/2.0/catalogDealers?catalogService=alpine_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /cart/ext/api/2.0/contextCart
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 410
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=alpine_parts&uname=header&_=1771939241`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"type":"urn:pl24-ShoppingCart-v2:notFound","title":"Erişim hatası","detail":"Sepete erişim hatası: contextCart for catalog service: 'alpine_parts' is not available.","references":{},"context":{}}`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/catalogs
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=alpine_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Alpine", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=alpine_parts&upds=2025-12-02--14-31" } } ], "demo" : false, "data" : { "records" : [ { "id" : "XEF", "description" :`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-ordrimprt/ext/api/1.0/order
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-ordrimprt/ext/api/1.0/order?catalogService=alpine_parts&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{}`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| POST | `https://www.partslink24.com/auth/ext/api/1.1/authorize` | 200 | marka-ana-sayfa | `{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXp` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| POST | `https://www.partslink24.com/auth/ext/api/1.1/authorize` | 200 | marka-ana-sayfa | `{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXp` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-manufacturer/ext/api/1.0/manufacturers/?lang=tr...` | 200 | marka-ana-sayfa | `{"manufacturers":[{"imgSrc":"/carbrands/alpine/pl24_cat_logo_app.png","label":"Alpine","link":"/pl24` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/3.0?jwt=eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImt...` | 200 | marka-ana-sayfa | `{"_links":{"carts":{"href":"/cart/ext/api/2.0/carts?catalogService={catalogService}","templated":tru` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/catmeta?serviceName=alpine_parts&co...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Alpine", "user24Brand" : "Alpine", ` |
|
||||||
|
| POST | `https://www.partslink24.com/auth/ext/api/1.1/authorize` | 200 | marka-ana-sayfa | `{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXp` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-manufacturer/ext/api/1.0/manufacturers/?lang=tr...` | 200 | marka-ana-sayfa | `{"manufacturers":[{"imgSrc":"/carbrands/alpine/pl24_cat_logo_app.png","label":"Alpine","link":"/pl24` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/3.0?jwt=eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImt...` | 200 | marka-ana-sayfa | `{"_links":{"carts":{"href":"/cart/ext/api/2.0/carts?catalogService={catalogService}","templated":tru` |
|
||||||
|
| GET | `https://www.partslink24.com/lex-campaign/ext/api/1.0/DestinationContent?destinat...` | 200 | marka-ana-sayfa | `{"components":[]}` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-dealers/ext/api/2.0/catalogDealers?catalogServi...` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=alpine_p...` | 410 | marka-ana-sayfa | `{"type":"urn:pl24-ShoppingCart-v2:notFound","title":"Erişim hatası","detail":"Sepete erişim hatası: ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceNam...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Alpine", "link" : { "wid" : "catalogTable", "path" ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-ordrimprt/ext/api/1.0/order?catalogService=alpi...` | 200 | marka-ana-sayfa | `{}` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=alpine_p...` | 410 | marka-ana-sayfa | `{"type":"urn:pl24-ShoppingCart-v2:notFound","title":"Erişim hatası","detail":"Sepete erişim hatası: ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceNam...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Alpine", "link" : { "wid" : "catalogTable", "path" ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/alpine_parts/0/0?desktop=true&lang=tr
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
135
docs/pl24-catalog/audi.md
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# Audi — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:20:55.755Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/TR/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/TR/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=audi_parts&country=TR&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Audi", "user24Brand" : "Audi", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAACXBIWXMAAAsSAAALEgHS3X78AAAZdklEQVR4nO3dXVLcyJrG8fSE7jEx4Ws4C/DABPY19AqaswLwCppegfEKulhBFytoWEHDtSEONV7Aoa4dE3bdVwQnZL+yZblUpVfKr7fq/4sg6Db1lZXK`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /auth/ext/api/1.1/authorize
|
||||||
|
- **Method:** POST
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/auth/ext/api/1.1/authorize`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXphdGlvbiIsImFsZyI6IlJTMjU2In0.eyJpYXQiOjE3NzE5MzkyNTYsImV4cCI6MTc3MTkzOTg1Niwic2lkIjoiN2h4RHEyYmtVaWtHc3F1LURLeldxb25DX25xTHE5SXkiLCJhaWQiOjE0OTg1ODMsInVpZCI6MjE0NDA5NCwic2VydmljZXMiOlsicGwyNC10bHMtcGl`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /lex-campaign/ext/api/1.0/DestinationContent
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/lex-campaign/ext/api/1.0/DestinationContent?destinationId=catalog_audi_parts&countryCode=TR&...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"components":[]}`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-dealers/ext/api/2.0/catalogDealers
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-dealers/ext/api/2.0/catalogDealers?catalogService=audi_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /cart/ext/api/2.0/contextCart
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_parts&uname=header&_=1771939256`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-13T18:00:56.636Z","cartName":"Audi #2","customerReference":"Audi #2","catalogProperties":{"catalogService":"audi_parts","brandName":"Audi","brandNamePretty":"Audi","brandLogoPath":"/carbrands/audi/pl24`
|
||||||
|
- **Çağrı sayısı:** 7
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=audi_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Audi", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=audi_parts&upds=2026-02-13--00-01" } } ], "demo" : false, "data" : { "records" : [ { "id" : "91`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-ordrimprt/ext/api/1.0/order
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-ordrimprt/ext/api/1.0/order?catalogService=audi_parts&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{}`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=audi_parts&country...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Audi", "user24Brand" : "Audi", "l` |
|
||||||
|
| POST | `https://www.partslink24.com/auth/ext/api/1.1/authorize` | 200 | marka-ana-sayfa | `{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXp` |
|
||||||
|
| GET | `https://www.partslink24.com/lex-campaign/ext/api/1.0/DestinationContent?destinat...` | 200 | marka-ana-sayfa | `{"components":[]}` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-dealers/ext/api/2.0/catalogDealers?catalogServi...` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_par...` | 200 | marka-ana-sayfa | `{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-1` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_par...` | 200 | marka-ana-sayfa | `{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-1` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_par...` | 200 | marka-ana-sayfa | `{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-1` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Audi", "link" : { "wid" : "modelFamiliesTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-ordrimprt/ext/api/1.0/order?catalogService=audi...` | 200 | marka-ana-sayfa | `{}` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_par...` | 200 | marka-ana-sayfa | `{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-1` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Audi", "link" : { "wid" : "modelFamiliesTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_par...` | 200 | marka-ana-sayfa | `{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-1` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_par...` | 200 | marka-ana-sayfa | `{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-1` |
|
||||||
|
| GET | `https://www.partslink24.com/cart/ext/api/2.0/contextCart?catalogService=audi_par...` | 200 | marka-ana-sayfa | `{"cartId":13076569,"cartHref":null,"creationTime":"2025-03-13T18:00:56.636Z","updateTime":"2025-03-1` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/audi_parts/0/0?desktop=true&lang=tr
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
95
docs/pl24-catalog/bentley.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# Bentley — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:21:11.127Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=bentley_parts&country=TR&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Bentley", "user24Brand" : "Bentley", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAP1BMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///9lZWXo6Og1NTWUlJS9vb1JW7H1AAAADnRSTlMAzX`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /auth/ext/api/1.1/authorize
|
||||||
|
- **Method:** POST
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/auth/ext/api/1.1/authorize`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXphdGlvbiIsImFsZyI6IlJTMjU2In0.eyJpYXQiOjE3NzE5MzkyNzEsImV4cCI6MTc3MTkzOTg3MSwic2lkIjoiN2h4RHEyYmtVaWtHc3F1LURLeldxb25DX25xTHE5SXkiLCJzZXJ2aWNlcyI6W10sImFwcCI6InBhcnRzbGluazI0IiwidHlwZSI6InBsMjQtYXV0aG9`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/logout
|
||||||
|
- **Method:** POST
|
||||||
|
- **Status:** 204
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/logout`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /carbrands/ford/pl24_portal_logo_v2.png
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/carbrands/ford/pl24_portal_logo_v2.png`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=bentley_parts&coun...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Bentley", "user24Brand" : "Bentley", ` |
|
||||||
|
| POST | `https://www.partslink24.com/auth/ext/api/1.1/authorize` | 200 | marka-ana-sayfa | `{"access_token":"eyJhcHAiOiJwYXJ0c2xpbmsyNCIsImtpZCI6InByLXBsMjRqd2tzLWtpZDEiLCJ0eXBlIjoiYXV0aG9yaXp` |
|
||||||
|
| POST | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/logout` | 204 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/carbrands/ford/pl24_portal_logo_v2.png` | 200 | marka-ana-sayfa | `` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: partslink24
|
||||||
|
- URL: https://www.partslink24.com/partslink24/user/login.do
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
118
docs/pl24-catalog/bmw-classic.md
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
# BMW Classic — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:22:11.868Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmwclassic_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "BMW Classic", "user24Brand" : "BMW", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAACpQTFRFR3BMqbC4lpeYhIWGf4GEfYKHe31/fH1+e3t7eXl5dXV1PXe4b29vAGeylL5pygAAAAx0Uk5TABk0T2mBmbHJ3/PzKqfy3AAACtNJREFUeNrs2NuOsm`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwclassic_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwclassic_parts&upds=2026-02-10--14-21" } } ], "demo" : true, "data" : { "records" : [ { "id" : "8'", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/modeltypes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=Z4&serviceName=bmwclassic_parts&upds=2026-02-10-...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwclassic_parts&upds=2026-02-10--14-21", "id" : "Z4" } }, { "name" : "Z4", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=Z4&modelType=E85&serviceName=bmwclassic_parts...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwclassic_parts&upds=2026-02-10--14-21", "id" : "Z4" } }, { "name" : "Z4", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=Z4&modelType=E85&res1=Roa&serviceName=bmwclas...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwclassic_parts&upds=2026-02-10--14-21", "id" : "Z4" } }, { "name" : "Z4", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=Z4&modelType=E85&res1=Roa&res2=Z4+2.0i&servic...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwclassic_parts&upds=2026-02-10--14-21", "id" : "Z4" } }, { "name" : "Z4", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmwclassic_parts&co...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "BMW Classic", "user24Brand" : "BMW", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwc...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "pat` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwc...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "pat` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=Z4&servi...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "pat` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=Z4&mo...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "pat` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=Z4&mo...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "pat` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=Z4&mo...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Classic", "link" : { "wid" : "modelTable", "pat` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: BMW Classic, Z4, E85 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/bmwclassic_parts/0/eyJwYXRoIjoiL3A1Ym13L2V4dGVybi92ZWhpY2xlL3Jlc3RyaWN0aW9uczM%252FbGFuZz10ciZtZGw9WjQmbW9kZWxUeXBlPUU4NSZyZXMxPVJvYSZyZXMyPVo0KzIuMGkmc2VydmljZU5hbWU9Ym13Y2xhc3NpY19wYXJ0cyZ1cGRzPTIwMjYtMDItMTAtLTE0LTIxIiwid2lkIjoicmVzdHJpY3Rpb25UYWJsZTMiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
118
docs/pl24-catalog/bmw-motorrad-classic.md
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
# BMW Motorrad Classic — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:22:42.650Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmwmotorradclassic_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "BMW Motorrad Classic", "user24Brand" : "BMWMotorrad", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAAIdQTFRFR3BMPDw8NTU2VlZXHh4eX19fcXFxl5iZcnJzYWJjFhYWAQEBExMTJSUlQUFBPT09Tk5OZnaIRUVFSUlJLCwsBAQEMDAwMTExK`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorradclassic_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorradclassic_parts&upds=2026-02-10--14-21" } } ], "demo" : true, "data" : { "records" : [ { "id" : "1-Zyl.", `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/modeltypes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=R-Modelle+2V&serviceName=bmwmotorradclassic_part...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorradclassic_parts&upds=2026-02-10--14-21", "id" : "R-Modelle 2V" } }, { "name" : "R-Modeller 2V", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=R-Modelle+2V&modelType=2474&serviceName=bmwmo...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorradclassic_parts&upds=2026-02-10--14-21", "id" : "R-Modelle 2V" } }, { "name" : "R-Modeller 2V", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=R-Modelle+2V&modelType=2474&res1=ohne&service...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorradclassic_parts&upds=2026-02-10--14-21", "id" : "R-Modelle 2V" } }, { "name" : "R-Modeller 2V", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=R-Modelle+2V&modelType=2474&res1=ohne&res2=R+...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorradclassic_parts&upds=2026-02-10--14-21", "id" : "R-Modelle 2V" } }, { "name" : "R-Modeller 2V", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmwmotorradclassic_...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "BMW Motorrad Classic", "user24Brand" : ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwm...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwm...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=R-Modell...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=R-Mod...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=R-Mod...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=R-Mod...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad Classic", "link" : { "wid" : "modelTable", ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: BMW Motorrad Classic, R-Modeller 2V, 2474 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/bmwmotorradclassic_parts/0/eyJwYXRoIjoiL3A1Ym13L2V4dGVybi92ZWhpY2xlL3Jlc3RyaWN0aW9uczM%252FbGFuZz10ciZtZGw9Ui1Nb2RlbGxlKzJWJm1vZGVsVHlwZT0yNDc0JnJlczE9b2huZSZyZXMyPVIrMTAwKyUyRjcmc2VydmljZU5hbWU9Ym13bW90b3JyYWRjbGFzc2ljX3BhcnRzJnVwZHM9MjAyNi0wMi0xMC0tMTQtMjEiLCJ3aWQiOiJyZXN0cmljdGlvblRhYmxlMyIsImF1dG8iOnRydWV9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
118
docs/pl24-catalog/bmw-motorrad.md
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
# BMW Motorrad — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:22:27.217Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmwmotorrad_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "BMW Motorrad", "user24Brand" : "BMWMotorrad", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAADZQTFRFR3BMAB43AAIDAAcNAAAAAAAAAGexAAAAAAABAAAAAGWwAAAAAAAAAGaxAAAAAAAAAGaxAAAACaFyRgAAABB0Uk5TAAkSHzBCSlxzjJilw`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorrad_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorrad_parts&upds=2026-02-10--14-21" } } ], "demo" : true, "data" : { "records" : [ { "id" : "C-Modelle", "link" `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/modeltypes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=G-Modelle&serviceName=bmwmotorrad_parts&upds=202...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorrad_parts&upds=2026-02-10--14-21", "id" : "G-Modelle" } }, { "name" : "G-Modeller", "link" : { "wid" : "modelT`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=G-Modelle&modelType=R134&serviceName=bmwmotor...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorrad_parts&upds=2026-02-10--14-21", "id" : "G-Modelle" } }, { "name" : "G-Modeller", "link" : { "wid" : "modelT`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=G-Modelle&modelType=R134&res1=ohne&serviceNam...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorrad_parts&upds=2026-02-10--14-21", "id" : "G-Modelle" } }, { "name" : "G-Modeller", "link" : { "wid" : "modelT`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=G-Modelle&modelType=R134&res1=ohne&res2=G+650...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwmotorrad_parts&upds=2026-02-10--14-21", "id" : "G-Modelle" } }, { "name" : "G-Modeller", "link" : { "wid" : "modelT`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmwmotorrad_parts&c...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "BMW Motorrad", "user24Brand" : "BMWMoto` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwm...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmwm...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=G-Modell...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=G-Mod...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=G-Mod...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=G-Mod...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW Motorrad", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: BMW Motorrad, G-Modeller, R13 (G 650 GS Sertão) - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/bmwmotorrad_parts/0/eyJwYXRoIjoiL3A1Ym13L2V4dGVybi92ZWhpY2xlL3Jlc3RyaWN0aW9uczM%252FbGFuZz10ciZtZGw9Ry1Nb2RlbGxlJm1vZGVsVHlwZT1SMTM0JnJlczE9b2huZSZyZXMyPUcrNjUwK0dTK1NlcnQlQzMlQTNvKyUyODAxMzYlMkMrMDE0NiUyOSZzZXJ2aWNlTmFtZT1ibXdtb3RvcnJhZF9wYXJ0cyZ1cGRzPTIwMjYtMDItMTAtLTE0LTIxIiwid2lkIjoicmVzdHJpY3Rpb25UYWJsZTMiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
129
docs/pl24-catalog/bmw.md
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
# BMW — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:21:56.520Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-manufacturer/ext/api/1.0/manufacturers/
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-manufacturer/ext/api/1.0/manufacturers/?lang=tr&country=DE&relativeLink=true`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"manufacturers":[{"imgSrc":"/carbrands/abarth/pl24_cat_logo_app.png","label":"Abarth","link":"/fiatspa/pl24-entry.action?service=abarth_parts&lang=tr&vin=","serviceName":"abarth_parts","translation":"Abarth","architecture":"P4","catmetaUrl":null},{"imgSrc":"/carbrands/alfa/pl24_cat_logo_app.png","l`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmw_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "BMW", "user24Brand" : "BMW", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAADNQTFRFR3BMaG91bG91ZnB6cnJyB2avc3FxB2avcnFxcnFxB2av////2+Lrw8PDl5aWcnFxB2avO/gNwwAAAAt0Uk5TABU5WoCLpsHH6+qyqTnsAAAPfUlEQVR42u2d65`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_parts&upds=2026-02-10--14-21" } } ], "demo" : true, "data" : { "records" : [ { "id" : "1'", "link" : { "wid" : "mod`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/modeltypes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=X5&serviceName=bmw_parts&upds=2026-02-10--14-21`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_parts&upds=2026-02-10--14-21", "id" : "X5" } }, { "name" : "X5", "link" : { "wid" : "modelTypeTable", "path" : "/p5bm`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=X5&modelType=E53&serviceName=bmw_parts&upds=2...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_parts&upds=2026-02-10--14-21", "id" : "X5" } }, { "name" : "X5", "link" : { "wid" : "modelTypeTable", "path" : "/p5bm`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=X5&modelType=E53&res1=SAV&serviceName=bmw_par...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_parts&upds=2026-02-10--14-21", "id" : "X5" } }, { "name" : "X5", "link" : { "wid" : "modelTypeTable", "path" : "/p5bm`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=X5&modelType=E53&res1=SAV&res2=X5+4.8is&servi...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_parts&upds=2026-02-10--14-21", "id" : "X5" } }, { "name" : "X5", "link" : { "wid" : "modelTypeTable", "path" : "/p5bm`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-manufacturer/ext/api/1.0/manufacturers/?lang=tr...` | 200 | marka-ana-sayfa | `{"manufacturers":[{"imgSrc":"/carbrands/abarth/pl24_cat_logo_app.png","label":"Abarth","link":"/fiat` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=bmw_parts&country=D...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "BMW", "user24Brand" : "BMW", "log` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=bmw_...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=X5&servi...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=X5&mo...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=X5&mo...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=X5&mo...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "BMW", "link" : { "wid" : "modelTable", "path" : "/p` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: BMW, X5, E53 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/bmw_parts/0/eyJwYXRoIjoiL3A1Ym13L2V4dGVybi92ZWhpY2xlL3Jlc3RyaWN0aW9uczM%252FbGFuZz10ciZtZGw9WDUmbW9kZWxUeXBlPUU1MyZyZXMxPVNBViZyZXMyPVg1KzQuOGlzJnNlcnZpY2VOYW1lPWJtd19wYXJ0cyZ1cGRzPTIwMjYtMDItMTAtLTE0LTIxIiwid2lkIjoicmVzdHJpY3Rpb25UYWJsZTMiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/citro-n-ds.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Citroën DS — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:23:13.597Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Citroën DS - partslink24
|
||||||
|
- URL: https://www.partslink24.com/psa/citroenDs_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2024.02.13+09%3A27%3A21+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/citro-n.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Citroën — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:22:58.028Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Citroën BX - BX - partslink24
|
||||||
|
- URL: https://www.partslink24.com/psa/citroen_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2024.02.13+09%3A27%3A21+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/cupra.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Cupra — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:23:29.312Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=cupra_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Cupra", "user24Brand" : "Seat", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAABtQTFRFR3BMAAAAAAMDAAMDAQICAQEBAQICAQICAQIClsKUpgAAAAh0Uk5TABo9WX6gxOndduqxAAAGOElEQVR42u3c3VbjOgwFYMmyft7/ic86DG1Km1SxXUpS7+8`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=cupra_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Cupra", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=cupra_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records" : [ { "id" : "8`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=87370&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Cupra", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=cupra_parts&upds=2026-02-13--00-01", "id" : "87370_41_null" } }, { "name" : "Formentor (CUPRA)", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=cupra_parts&countr...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Cupra", "user24Brand" : "Seat", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Cupra", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Cupra", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=87370&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Cupra", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Cupra - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/cupra_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT04NzM3MCZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9NDEmc2VydmljZU5hbWU9Y3VwcmFfcGFydHMmdXBkcz0yMDI2LTAyLTEzLS0wMC0wMSIsIndpZCI6Im1vZGVsWWVhclRhYmxlIn0%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
107
docs/pl24-catalog/dacia.md
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# Dacia — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:23:44.798Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/catmeta?serviceName=dacia_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Dacia", "user24Brand" : "Dacia", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAAXNSR0IArs4c6QAAAA9QTFRFR3BMcHBjbHBkbXBlbXBlSUKgdQAAAAR0Uk5TABxOwSQ2rCMAAAImSURBVHja7dhRTupQFEbhg50AUQaA2gFQ6ASAPf8xmRBig+scd48Pxpj1vZlcN3+XTU`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/catalogs
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=dacia_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=dacia_parts&upds=2025-12-02--14-31" } } ], "demo" : true, "data" : { "records" : [ { "id" : "X75", "description" : "D`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/models?catalog=X41&lang=tr&serviceName=dacia_parts&upds=2025-12-02-...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=dacia_parts&upds=2025-12-02--14-31", "id" : "X41" } }, { "name" : "SUPERNOVA / SOLENZA", "link" : { "wid" : "modelTab`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/engines
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/engines?catalog=X41&lang=tr&model=B41&serviceName=dacia_parts&upds=...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=dacia_parts&upds=2025-12-02--14-31", "id" : "X41" } }, { "name" : "SUPERNOVA / SOLENZA", "link" : { "wid" : "modelTab`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/gearbox
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/gearbox?catalog=X41&engineFamily=EXX&engineIndex=262&engineLevel=MA...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=dacia_parts&upds=2025-12-02--14-31", "id" : "X41" } }, { "name" : "SUPERNOVA / SOLENZA", "link" : { "wid" : "modelTab`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/catmeta?serviceName=dacia_parts&cou...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Dacia", "user24Brand" : "Dacia", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceNam...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" :` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceNam...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" :` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/models?catalog=X41&lang=tr&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" :` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/engines?catalog=X41&lang=tr...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" :` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/gearbox?catalog=X41&engineF...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Dacia", "link" : { "wid" : "catalogTable", "path" :` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Dacia, SUPERNOVA / SOLENZA, 5 KAPILI SEDAN - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/dacia_parts/0/eyJwYXRoIjoiL3A1cmVuYXVsdC9leHRlcm4vdmVoaWNsZS9nZWFyYm94P2NhdGFsb2c9WDQxJmVuZ2luZUZhbWlseT1FWFgmZW5naW5lSW5kZXg9MjYyJmVuZ2luZUxldmVsPU1BJmVuZ2luZVR5cGU9RTdKJmxhbmc9dHImbW9kZWw9QjQxJnNlcnZpY2VOYW1lPWRhY2lhX3BhcnRzJnVwZHM9MjAyNS0xMi0wMi0tMTQtMzEiLCJ3aWQiOiJnZWFyYm94VGFibGUiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
110
docs/pl24-catalog/ford-commercial.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# Ford Commercial — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:24:15.811Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /ford/pl24-entry.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 302
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/pl24-entry.action?service=fordt_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /ford/fordt_parts/vehicle.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 302
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/fordt_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/web-common/css/css.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-common/css/css.action?idx=sg1p31-g1p32-g1p33-g1p34-g1p35-g1p36-g1p37-g1p38-g1p39-g1...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`/*! jQuery UI - v1.9.2 - 2013-03-20 * http://jqueryui.com * Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.tabs.css, jquery.ui.tooltip.css`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/web-custom/css/css.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-custom/css/css.action?idx=cg2p10-g2p11-g2p16&v=4.021.13.110`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`span.vinHit,span.vinMiss,span.vinUnknown{padding-left:13px;background-position:left center;background-repeat:no-repeat;cursor:help}span.vinHit,span.vinMiss{font-weight:normal}span.vinHit{background-image:url("images/vin-hit.png")}span.vinMiss{background-image:url("images/vin-miss.png")}span.vinUnkno`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/js/js.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/js/js.action?idx=jg1p1-g1p2-g1p3-g1p4-g1p5-g1p6-g1p7-g1p8-g1p9-g1p10-g1p11-g1p13-g1p14-...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`function $C(){}$C.prototype.construct=function(){};$C.extend=function(f){var b,e,c,a,d;b=function(){if(arguments[0]!==$C){this.construct.apply(this,arguments)}};e=new this($C);c=this.prototype;for(a in f){d=f[a];if(d instanceof Function){d.$=c}e[a]=d}b.prototype=e;b.extend=this.extend;return b}; var`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/web-common/css/layout/demo.png
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-common/css/layout/demo.png`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /ford/web-common/css/tablecontrol/tbl_header_bottom.gif
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-common/css/tablecontrol/tbl_header_bottom.gif`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /ford/fordt_parts/json-model-config.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/fordt_parts/json-model-config.action?catCode=EX&lang=tr&modelFamily=Explorer&startup=fa...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"engineData":[{"avsCode":"_all_","catCode":"","description":"Hepsi","selected":false,"url":"vehicle.action?catCode=EX&engineAvsCode=_all_&lang=tr&modelFamily=Explorer&startup=false&mode=K00U0DEXX&upds=2026.02.11+13%3A40%3A15+CET"},{"avsCode":"ENLT0","catCode":"EX","description":"4.0 V6 OHV 12V EFI"`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/ford/pl24-entry.action?service=fordt_parts` | 302 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/fordt_parts/vehicle.action?mode=K00U0DEXX&lang=...` | 302 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/fordt_parts/vehicle.action?mode=K00U0DEXX&lang=...` | 200 | marka-ana-sayfa | `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-str` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/css.action?idx=sg1p31-g1p32-g1p3...` | 200 | marka-ana-sayfa | `/*! jQuery UI - v1.9.2 - 2013-03-20 * http://jqueryui.com * Includes: jquery.ui.core.css, jquery.ui.` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-custom/css/css.action?idx=cg2p10-g2p11-g2p1...` | 200 | marka-ana-sayfa | `span.vinHit,span.vinMiss,span.vinUnknown{padding-left:13px;background-position:left center;backgroun` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/js/js.action?idx=jg1p1-g1p2-g1p3-g1p4-g1p5-g1p6...` | 200 | marka-ana-sayfa | `function $C(){}$C.prototype.construct=function(){};$C.extend=function(f){var b,e,c,a,d;b=function(){` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/js/js.action?idx=jg2p3&cmi=4.021.13.110` | 200 | marka-ana-sayfa | `function Vehicles(s){var q=null;var l=null;var p=null;var m=null;var h=null;var n=null;var d=null;va` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/css.action?idx=sg1p51&v=4.021.13...` | 200 | marka-ana-sayfa | `*{font-family:Arial,sans-serif}table{border-collapse:separate;border-spacing:0}th{text-align:left}di` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-custom/css/css.action?idx=cg2p15&v=4.021.13...` | 200 | marka-ana-sayfa | `.vinInfoTable .attrib,.vinInfoTable .caption{width:30%}table.partinfoTable{width:100%;table-layout:f` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/layout/demo.png` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/tablecontrol/tbl_header_bottom.g...` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/fordt_parts/json-model-config.action?catCode=EX...` | 200 | marka-ana-sayfa | `{"engineData":[{"avsCode":"_all_","catCode":"","description":"Hepsi","selected":false,"url":"vehicle` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Ford Nutzfahrzeuge Explorer - EX (1992, 2000) - partslink24
|
||||||
|
- URL: https://www.partslink24.com/ford/fordt_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.11+13%3A40%3A15+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
121
docs/pl24-catalog/ford.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Ford — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:24:00.168Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /ford/pl24-entry.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 302
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/pl24-entry.action?service=fordp_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /ford/fordp_parts/vehicle.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 302
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/fordp_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/web-common/css/css.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-common/css/css.action?idx=sg1p31-g1p32-g1p33-g1p34-g1p35-g1p36-g1p37-g1p38-g1p39-g1...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`/*! jQuery UI - v1.9.2 - 2013-03-20 * http://jqueryui.com * Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.tabs.css, jquery.ui.tooltip.css`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/web-custom/css/css.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-custom/css/css.action?idx=cg2p10-g2p11-g2p16&v=4.021.13.110`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`span.vinHit,span.vinMiss,span.vinUnknown{padding-left:13px;background-position:left center;background-repeat:no-repeat;cursor:help}span.vinHit,span.vinMiss{font-weight:normal}span.vinHit{background-image:url("images/vin-hit.png")}span.vinMiss{background-image:url("images/vin-miss.png")}span.vinUnkno`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/js/js.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/js/js.action?idx=jg1p1-g1p2-g1p3-g1p4-g1p5-g1p6-g1p7-g1p8-g1p9-g1p10-g1p11-g1p13-g1p14-...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`function $C(){}$C.prototype.construct=function(){};$C.extend=function(f){var b,e,c,a,d;b=function(){if(arguments[0]!==$C){this.construct.apply(this,arguments)}};e=new this($C);c=this.prototype;for(a in f){d=f[a];if(d instanceof Function){d.$=c}e[a]=d}b.prototype=e;b.extend=this.extend;return b}; var`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /ford/web-common/css/layout/demo.png
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-common/css/layout/demo.png`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /carbrands/ford/pl24_cat_logo_v2.png
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/carbrands/ford/pl24_cat_logo_v2.png`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /ford/web-common/css/tablecontrol/tbl_header_bottom.gif
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/web-common/css/tablecontrol/tbl_header_bottom.gif`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /ford/fordp_parts/json-model-config.action
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/ford/fordp_parts/json-model-config.action?catCode=FA&lang=tr&modelFamily=Escort&startup=fals...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"engineData":[{"avsCode":"_all_","catCode":"","description":"Hepsi","selected":false,"url":"vehicle.action?catCode=FA&engineAvsCode=_all_&lang=tr&modelFamily=Escort&startup=false&mode=K00U0DEXX&upds=2026.02.11+13%3A40%3A15+CET"},{"avsCode":"ENJK0","catCode":"FA","description":"1.3L HCS EFI(60PS)","`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/ford/pl24-entry.action?service=fordp_parts` | 302 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/fordp_parts/vehicle.action?mode=K00U0DEXX&lang=...` | 302 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/fordp_parts/vehicle.action?mode=K00U0DEXX&lang=...` | 200 | marka-ana-sayfa | `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-str` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/css.action?idx=sg1p31-g1p32-g1p3...` | 200 | marka-ana-sayfa | `/*! jQuery UI - v1.9.2 - 2013-03-20 * http://jqueryui.com * Includes: jquery.ui.core.css, jquery.ui.` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-custom/css/css.action?idx=cg2p10-g2p11-g2p1...` | 200 | marka-ana-sayfa | `span.vinHit,span.vinMiss,span.vinUnknown{padding-left:13px;background-position:left center;backgroun` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/js/js.action?idx=jg1p1-g1p2-g1p3-g1p4-g1p5-g1p6...` | 200 | marka-ana-sayfa | `function $C(){}$C.prototype.construct=function(){};$C.extend=function(f){var b,e,c,a,d;b=function(){` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/js/js.action?idx=jg2p3&cmi=4.021.13.110` | 200 | marka-ana-sayfa | `function Vehicles(s){var q=null;var l=null;var p=null;var m=null;var h=null;var n=null;var d=null;va` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/css.action?idx=sg1p51&v=4.021.13...` | 200 | marka-ana-sayfa | `*{font-family:Arial,sans-serif}table{border-collapse:separate;border-spacing:0}th{text-align:left}di` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-custom/css/css.action?idx=cg2p15&v=4.021.13...` | 200 | marka-ana-sayfa | `.vinInfoTable .attrib,.vinInfoTable .caption{width:30%}table.partinfoTable{width:100%;table-layout:f` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/layout/demo.png` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/carbrands/ford/pl24_cat_logo_v2.png` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/web-common/css/tablecontrol/tbl_header_bottom.g...` | 200 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/ford/fordp_parts/json-model-config.action?catCode=FA...` | 200 | marka-ana-sayfa | `{"engineData":[{"avsCode":"_all_","catCode":"","description":"Hepsi","selected":false,"url":"vehicle` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Ford Escort - FA (1995, 2001) - partslink24
|
||||||
|
- URL: https://www.partslink24.com/ford/fordp_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.11+13%3A40%3A15+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/hyundai.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Hyundai — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:24:31.548Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Hyundai EXCEL / PONY 89 - EUR2409200 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/hyundai-kia-automotive-group/hyundai_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.05+02%3A10%3A59+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/infiniti.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Infiniti — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:24:47.354Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Infiniti S50 - FX45/35 (EL) - partslink24
|
||||||
|
- URL: https://www.partslink24.com/nissan/infiniti_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.03+15%3A59%3A51+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/jaguar.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Jaguar — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:25:03.100Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5jlr/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5jlr/extern/catmeta?serviceName=jaguar_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Jaguar", "user24Brand" : "Jaguar", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3dpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVT`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5jlr/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5jlr/extern/vehicle/models?lang=tr&serviceName=jaguar_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Jaguar", "link" : { "wid" : "modelTable", "path" : "/p5jlr/extern/vehicle/models?lang=tr&serviceName=jaguar_parts&upds=2026-02-02--08-56" } } ], "demo" : true, "data" : { "records" : [ { "id" : "893", "link" : { "wid"`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5jlr/extern/vehicle/engines
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5jlr/extern/vehicle/engines?lang=tr&mdl=250&serviceName=jaguar_parts&upds=2026-02-02--08-56`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Jaguar", "link" : { "wid" : "modelTable", "path" : "/p5jlr/extern/vehicle/models?lang=tr&serviceName=jaguar_parts&upds=2026-02-02--08-56", "id" : "250" } }, { "name" : "XF 2009 - 2015 (X250)", "link" : { "wid" : "engineTable"`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/catmeta?serviceName=jaguar_parts&countr...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Jaguar", "user24Brand" : "Jaguar", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/vehicle/models?lang=tr&serviceName=jagu...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Jaguar", "link" : { "wid" : "modelTable", "path" : ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/vehicle/models?lang=tr&serviceName=jagu...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Jaguar", "link" : { "wid" : "modelTable", "path" : ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/vehicle/engines?lang=tr&mdl=250&service...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Jaguar", "link" : { "wid" : "modelTable", "path" : ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Jaguar - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/jaguar_parts/0/eyJwYXRoIjoiL3A1amxyL2V4dGVybi92ZWhpY2xlL2VuZ2luZXM%252FbGFuZz10ciZtZGw9MjUwJnNlcnZpY2VOYW1lPWphZ3Vhcl9wYXJ0cyZ1cGRzPTIwMjYtMDItMDItLTA4LTU2Iiwid2lkIjoiZW5naW5lVGFibGUifQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/kia.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Kia — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:25:18.710Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Kia RETONA 99 - GECKFK000A - partslink24
|
||||||
|
- URL: https://www.partslink24.com/hyundai-kia-automotive-group/kia_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.05+02%3A10%3A59+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/koda.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Škoda — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:30:29.799Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=skoda_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Škoda", "user24Brand" : "Skoda", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAG1BMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABp4cHsAAAACHRSTlMAIENjh6bG8KJiM+YAAANkSURBVHja7drbbuowEEDRGd9m/v+Lz5EoATo2Q9Qa+rCX+lRZhOw4iRMhAAAAAA`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=skoda_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Škoda", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=skoda_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records" : [ { "id" : "9`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=65232&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Škoda", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=skoda_parts&upds=2026-02-13--00-01", "id" : "65232_5_null" } }, { "name" : "Kamiq", "link" : {`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=skoda_parts&countr...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Škoda", "user24Brand" : "Skoda", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Škoda", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Škoda", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=65232&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Škoda", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Škoda - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/skoda_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT02NTIzMiZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9NSZzZXJ2aWNlTmFtZT1za29kYV9wYXJ0cyZ1cGRzPTIwMjYtMDItMTMtLTAwLTAxIiwid2lkIjoibW9kZWxZZWFyVGFibGUifQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/land-rover.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Land Rover — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:25:34.471Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5jlr/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5jlr/extern/catmeta?serviceName=landrover_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Land Rover", "user24Brand" : "LandRover", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAKlBMVEVHcEwIHiwIHiwIHiwIHiwIHiwIHiwIHiwIHiwIHiwIHiwIHiwIHiwIHiwQ3LidAAAADXRSTlMADiA1SmF1j6a70OPz4w6I1AAADn9JREFUeNrs1U9v0mAcB/AfbC+gK`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5jlr/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5jlr/extern/vehicle/models?lang=tr&serviceName=landrover_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Land Rover", "link" : { "wid" : "modelTable", "path" : "/p5jlr/extern/vehicle/models?lang=tr&serviceName=landrover_parts&upds=2026-02-02--08-56" } } ], "demo" : true, "data" : { "records" : [ { "id" : "17", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5jlr/extern/vehicle/engines
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5jlr/extern/vehicle/engines?lang=tr&mdl=24&serviceName=landrover_parts&upds=2026-02-02--08-...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Land Rover", "link" : { "wid" : "modelTable", "path" : "/p5jlr/extern/vehicle/models?lang=tr&serviceName=landrover_parts&upds=2026-02-02--08-56", "id" : "24" } }, { "name" : "RANGE ROVER EVOQUE 2012 - 2018 (L538)", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/catmeta?serviceName=landrover_parts&cou...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Land Rover", "user24Brand" : "LandRover` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/vehicle/models?lang=tr&serviceName=land...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Land Rover", "link" : { "wid" : "modelTable", "path` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/vehicle/models?lang=tr&serviceName=land...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Land Rover", "link" : { "wid" : "modelTable", "path` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5jlr/extern/vehicle/engines?lang=tr&mdl=24&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Land Rover", "link" : { "wid" : "modelTable", "path` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Land Rover - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/landrover_parts/0/eyJwYXRoIjoiL3A1amxyL2V4dGVybi92ZWhpY2xlL2VuZ2luZXM%252FbGFuZz10ciZtZGw9MjQmc2VydmljZU5hbWU9bGFuZHJvdmVyX3BhcnRzJnVwZHM9MjAyNi0wMi0wMi0tMDgtNTYiLCJ3aWQiOiJlbmdpbmVUYWJsZSJ9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
129
docs/pl24-catalog/lexus.md
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
# Lexus — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:25:49.873Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/catmeta?serviceName=lexus_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Lexus", "user24Brand" : "Lexus", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAHlBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaVcReAAAACXRSTlMAESNLeJO01eypTF87AAAFb0lEQVR42u3c23KjOhCFYakPkvr9X3hnZ6YMBiwDcjwp83+TuUiCXWSl1R`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/modelFamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/modelFamilies?lang=tr&serviceName=lexus_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=lexus_parts&upds=2026-01-30--08-41" } } ], "demo" : true, "data" : { "records" : [ { "id" : "64"`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/models?allMarkets=false&family=76&lang=tr&serviceName=lexus_parts&up...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=lexus_parts&upds=2026-01-30--08-41", "id" : "76" } }, { "name" : "LEXUS NX", "link" : { "w`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/restr1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/restr1?allMarkets=false&family=76&lang=tr&mainModelCode=527220&servi...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=lexus_parts&upds=2026-01-30--08-41", "id" : "76" } }, { "name" : "LEXUS NX", "link" : { "w`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/restr2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/restr2?allMarkets=false&family=76&lang=tr&mainModelCode=527220&restr...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=lexus_parts&upds=2026-01-30--08-41", "id" : "76" } }, { "name" : "LEXUS NX", "link" : { "w`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/restr3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/restr3?allMarkets=false&family=76&lang=tr&mainModelCode=527220&restr...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=lexus_parts&upds=2026-01-30--08-41", "id" : "76" } }, { "name" : "LEXUS NX", "link" : { "w`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/modelCodes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/modelCodes?allMarkets=false&family=76&lang=tr&mainModelCode=527220&r...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=lexus_parts&upds=2026-01-30--08-41", "id" : "76" } }, { "name" : "LEXUS NX", "link" : { "w`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/catmeta?serviceName=lexus_parts&coun...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Lexus", "user24Brand" : "Lexus", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/modelFamilies?lang=tr&servic...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/modelFamilies?allMarkets=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/models?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/restr1?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/restr2?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/restr3?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/modelCodes?allMarkets=false&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Lexus", "link" : { "wid" : "modelFamiliesTable", "p` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Lexus, LEXUS NX, LEXUS NX200/250/260/350/3... - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/lexus_parts/0/eyJwYXRoIjoiL3A1dG95b3RhL2V4dGVybi92ZWhpY2xlL21vZGVsQ29kZXM%252FYWxsTWFya2V0cz1mYWxzZSZmYW1pbHk9NzYmbGFuZz10ciZtYWluTW9kZWxDb2RlPTUyNzIyMCZyZXN0cjE9X2FyYml0cmFyeV8mcmVzdHIyPV9hcmJpdHJhcnlfJnJlc3RyMz1fYXJiaXRyYXJ5XyZzZXJ2aWNlTmFtZT1sZXh1c19wYXJ0cyZ1cGRzPTIwMjYtMDEtMzAtLTA4LTQxIiwid2lkIjoibW9kZWxDb2Rlc1RhYmxlIiwiYXV0byI6dHJ1ZX0%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
84
docs/pl24-catalog/man.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# MAN — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:26:05.331Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5man/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5man/extern/catmeta?serviceName=man_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "MAN", "user24Brand" : "MAN", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAGFBMVEVHcEwdHRsdHRsdHRsdHRsdHRsdHRsdHRsMQBB6AAAAB3RSTlMAFjxmj7viWSteHAAABqBJREFUeNrs17132jAQAPCzDZn9SIAVkias5IOyQpNUK5RQryVt7Ll8SP9+t+S9XrBkSXcs91`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5man/extern/model/categories
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5man/extern/model/categories?lang=tr&serviceName=man_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MAN", "link" : { "wid" : "categoriesTable", "path" : "/p5man/extern/model/categories?lang=tr&serviceName=man_parts" } } ], "demo" : true, "data" : { "records" : [ { "id" : "l", "link" : { "wid" : "categoryTypesTable",`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5man/extern/model/categoryTypes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5man/extern/model/categoryTypes?category=l&lang=tr&serviceName=man_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MAN", "link" : { "wid" : "categoriesTable", "path" : "/p5man/extern/model/categories?lang=tr&serviceName=man_parts", "id" : "l" } }, { "name" : "Kamyon", "link" : { "wid" : "categoryTypesTable", "path" : "/p5man/extern/`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5man/extern/catmeta?serviceName=man_parts&country=D...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "MAN", "user24Brand" : "MAN", "log` |
|
||||||
|
| GET | `https://www.partslink24.com/p5man/extern/model/categories?lang=tr&serviceName=ma...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MAN", "link" : { "wid" : "categoriesTable", "path" ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5man/extern/model/categoryTypes?category=l&lang=tr&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MAN", "link" : { "wid" : "categoriesTable", "path" ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: MAN - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/man_parts/0/eyJwYXRoIjoiL3A1bWFuL2V4dGVybi9tb2RlbC9jYXRlZ29yeVR5cGVzP2NhdGVnb3J5PWwmbGFuZz10ciZzZXJ2aWNlTmFtZT1tYW5fcGFydHMiLCJ3aWQiOiJjYXRlZ29yeVR5cGVzVGFibGUifQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
95
docs/pl24-catalog/mercedes-benz-classic.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# Mercedes-Benz Classic — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:26:36.147Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /p5daimler/extern/entry
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 302
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/entry?richParams=mercedesclassic_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`(yanıt yok)`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/jquery/1.0.17/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/jquery/1.0.17/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/jquery/1.0.17/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/jquery/1.0.17/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/catmeta?lang=de&serviceName=mercedesclassic_parts&_=1771939596441`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Classic", "user24Brand" : "Mercedes", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAJ1BMVEVHcEwJCAcLCQgMCwkMCwkLCggLCggLCggKCQgKCQgKCQgXFA8DAwSI8k3qAAAAC3RSTlMAEChDXXSMpsHY7eEdM+0AAAvXSURBVHja7NntiqwwDAbgfLR`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/scope
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=de&serviceName=mercedesclassic_parts&_=1771939596442`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Classic", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=de&serviceName=mercedesclassic_parts&upds=ND" } } ], "demo" : true, "data" : { "records" : [`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/modeltype
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggregatesVisible=false&blockPresel=false&lan...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Classic", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=de&serviceName=mercedesclassic_parts&upds=ND", "id" : "P-F" } }, { "name" : "PKW", "li`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/model
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregatesVisible=false&blockPresel=false&lang=de...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Classic", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=de&serviceName=mercedesclassic_parts&upds=ND", "id" : "P-F" } }, { "name" : "PKW", "li`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/entry?richParams=mercedesclassic_pa...` | 302 | marka-ana-sayfa | `` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/jquery/1.0.17/assets/locales/t...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/jquery/1.0.17/assets/locales/e...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/catmeta?lang=de&serviceName=mercede...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Classic", "user24Brand" :` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=de&serviceName=m...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Classic", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggre...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Classic", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregate...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Classic", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Mercedes-Benz Classic, PKW, C107 – partslink24
|
||||||
|
- URL: https://www.partslink24.com/p5/latest/p5.html#%2Fp5daimler~mercedesclassic_parts~de~~~~~eyJwIjoidmVoaWNsZXMiLCJiIjoiL3A1ZGFpbWxlci9leHRlcm4vdmVoaWNsZS8iLCJlcCI6WyJsYW5nPWRlIiwic2VydmljZU5hbWU9bWVyY2VkZXNjbGFzc2ljX3BhcnRzIiwiYWdnVHlwZUlkPUYiLCJhZ2dyZWdhdGVzVmlzaWJsZT1mYWxzZSIsImJsb2NrUHJlc2VsPWZhbHNlIiwicHJvZHVjdENsYXNzSWQ9UCIsInVwZHM9TkQiLCJtb2RlbFR5cGU9QzEwNyJdLCJ3cyI6W3sid2lkIjoic2NvcGVUYWJsZSIsInBhdGgiOiJzY29wZSIsImlkIjoiUC1GIiwiZXAiOlswLDFdfSx7IndpZCI6Im1vZGVsVHlwZVRhYmxlIiwicGF0aCI6Im1vZGVsdHlwZSIsImlkIjoiQzEwNyIsImVwIjpbMiwzLDQsMCw1LDEsNl19LHsid2lkIjoibW9kZWxUYWJsZSIsInBhdGgiOiJtb2RlbCIsImVwIjpbMiwzLDQsMCw3LDUsMSw2XX1dfQ%3D%3D
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
107
docs/pl24-catalog/mercedes-benz-trucks.md
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# Mercedes-Benz Trucks — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:26:51.705Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedestrucks_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Trucks", "user24Brand" : "MercedesTrucks", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAA51BMVEVHcEz4+fk5Ozv///8nKyv///8fISCdoqT///8dHhz///+fo6X6+/shIyIeHh3w8fGgpaceIB/e4OAeHx4eIB/P0tOboKIeHx6xtbfIyswdHRuMkp`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/scope
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=mercedestrucks_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedestrucks_parts&upds=ND" } } ], "demo" : true, "data" : { "records" : [ {`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/modeltype
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggregatesVisible=false&blockPresel=true&lang...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedestrucks_parts&upds=ND", "id" : "L-F" } }, { "name" : "Ağır vasıta", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/model
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregatesVisible=false&blockPresel=true&lang=tr&...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedestrucks_parts&upds=ND", "id" : "L-F" } }, { "name" : "Ağır vasıta", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/modelcatalog
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/modelcatalog?aggTypeId=F&aggregatesVisible=false&blockPresel=true&l...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedestrucks_parts&upds=ND", "id" : "L-F" } }, { "name" : "Ağır vasıta", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedestrucks_...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Trucks", "user24Brand" : ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=m...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?aggregatesVisible=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggre...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregate...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/modelcatalog?aggTypeId=F&ag...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Trucks", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Mercedes-Benz Trucks, Ağır vasıta, C938 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/mercedestrucks_parts/0/eyJwYXRoIjoiL3A1ZGFpbWxlci9leHRlcm4vdmVoaWNsZS9tb2RlbGNhdGFsb2c%252FYWdnVHlwZUlkPUYmYWdncmVnYXRlc1Zpc2libGU9ZmFsc2UmYmxvY2tQcmVzZWw9dHJ1ZSZsYW5nPXRyJm1vZGVsQ29kZT1DOTM4MTQyJm1vZGVsVHlwZT1DOTM4JnByb2R1Y3RDbGFzc0lkPUwmc2VydmljZU5hbWU9bWVyY2VkZXN0cnVja3NfcGFydHMmdXBkcz1ORCIsIndpZCI6Im1vZGVsQ2F0YWxvZ1RhYmxlIiwiYXV0byI6dHJ1ZX0%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
74
docs/pl24-catalog/mercedes-benz-unimog.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Mercedes-Benz Unimog — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:27:07.433Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedesunimog_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Unimog", "user24Brand" : "MercedesUnimog", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/scope
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=mercedesunimog_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Unimog", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedesunimog_parts&upds=ND" } } ], "demo" : true, "data" : { "records" : [ {`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedesunimog_...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Unimog", "user24Brand" : ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=m...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Unimog", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?aggregatesVisible=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Unimog", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/mercedesunimog_parts/0/0?desktop=true&lang=tr
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
96
docs/pl24-catalog/mercedes-benz-vans.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# Mercedes-Benz Vans — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:27:23.044Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedesvans_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Vans", "user24Brand" : "MercedesVans", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAJFBMVEVHcEwKCQcJCAcKCQgLCggGBgUIBwcJCAcJCAcIBwYDAwQXFA+M6EceAAAACnRSTlMAmRG5Q+t4W9QnSJ6llQAACoxJREFUeNrs2NuSnEAIBmAODTS8/w`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/scope
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=mercedesvans_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Vans", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedesvans_parts&upds=ND" } } ], "demo" : true, "data" : { "records" : [ { `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/modeltype
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggregatesVisible=false&blockPresel=true&lang...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Vans", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedesvans_parts&upds=ND", "id" : "T-F" } }, { "name" : "Panelvan", "lin`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/model
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregatesVisible=false&blockPresel=true&lang=tr&...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz Vans", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedesvans_parts&upds=ND", "id" : "T-F" } }, { "name" : "Panelvan", "lin`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedesvans_pa...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz Vans", "user24Brand" : "M` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=m...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Vans", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?aggregatesVisible=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Vans", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggre...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Vans", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregate...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz Vans", "link" : { "wid" : "scopeTable", ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Mercedes-Benz Vans, Panelvan - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/mercedesvans_parts/0/eyJwYXRoIjoiL3A1ZGFpbWxlci9leHRlcm4vdmVoaWNsZS9tb2RlbD9hZ2dUeXBlSWQ9RiZhZ2dyZWdhdGVzVmlzaWJsZT1mYWxzZSZibG9ja1ByZXNlbD10cnVlJmxhbmc9dHImbW9kZWxUeXBlPUM0MTUmcHJvZHVjdENsYXNzSWQ9VCZzZXJ2aWNlTmFtZT1tZXJjZWRlc3ZhbnNfcGFydHMmdXBkcz1ORCIsIndpZCI6Im1vZGVsVGFibGUiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
74
docs/pl24-catalog/mercedes-benz.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Mercedes-Benz — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:26:20.762Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedes_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz", "user24Brand" : "Mercedes", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAIVBMVEVHcEwDAwQDAwQDAwQDAwQDAwQDAwQDAwQDAwQDAwQDAwQ7c86cAAAACnRSTlMADh82UG6RstHsDX9HfAAADAFJREFUeNrsmMtv00AQxiePPk+RUCniZAmJR08RolL`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/scope
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=mercedes_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mercedes-Benz", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=mercedes_parts&upds=ND" } } ], "demo" : true, "data" : { "records" : [ { "id" :`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=mercedes_parts&...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Mercedes-Benz", "user24Brand" : "Merced` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=m...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz", "link" : { "wid" : "scopeTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?aggregatesVisible=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mercedes-Benz", "link" : { "wid" : "scopeTable", "p` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/mercedes_parts/0/0?desktop=true&lang=tr
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
118
docs/pl24-catalog/mini-classic.md
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
# MINI Classic — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:27:53.951Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=miniclassic_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "MINI Classic", "user24Brand" : "Mini", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAAXNSR0IArs4c6QAAACdQTFRFR3BMISEfISEhIiIhIiIgISEgIiIhIiIgIiIhIiIhIiIgIiIhIiIhbtAtwAAAAAx0Uk5TABQxSFZxiKK6zd7v5iEg/gAACjtJREFUeNrt282PG+UB`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=miniclassic_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=miniclassic_parts&upds=2026-02-10--14-21" } } ], "demo" : true, "data" : { "records" : [ { "id" : "MINI", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/modeltypes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=MINI&serviceName=miniclassic_parts&upds=2026-02-...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=miniclassic_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=MINI&modelType=R50&serviceName=miniclassic_pa...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=miniclassic_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=MINI&modelType=R50&res1=HC&serviceName=minicl...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=miniclassic_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=MINI&modelType=R50&res1=HC&res2=Cooper&servic...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=miniclassic_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=miniclassic_parts&c...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "MINI Classic", "user24Brand" : "Mini", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=MINI&ser...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=MINI&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=MINI&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=MINI&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI Classic", "link" : { "wid" : "modelTable", "pa` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: MINI Classic, MINI, R50 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/miniclassic_parts/0/eyJwYXRoIjoiL3A1Ym13L2V4dGVybi92ZWhpY2xlL3Jlc3RyaWN0aW9uczM%252FbGFuZz10ciZtZGw9TUlOSSZtb2RlbFR5cGU9UjUwJnJlczE9SEMmcmVzMj1Db29wZXImc2VydmljZU5hbWU9bWluaWNsYXNzaWNfcGFydHMmdXBkcz0yMDI2LTAyLTEwLS0xNC0yMSIsIndpZCI6InJlc3RyaWN0aW9uVGFibGUzIiwiYXV0byI6dHJ1ZX0%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
118
docs/pl24-catalog/mini.md
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
# MINI — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:27:38.616Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=mini_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "MINI", "user24Brand" : "Mini", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAAXNSR0IArs4c6QAAAB5QTFRFR3BMICAgIyAgJCAgIiAgJCAgIx4gIx8gIx8gIx8gU7wfegAAAAl0Uk5TABAqQGeBpsPsgSO3OwAABR1JREFUeNrt3Ltv21YYBfBPr9jeBKSNnY2A0zbaVD/a`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini_parts&upds=2026-02-10--14-21" } } ], "demo" : true, "data" : { "records" : [ { "id" : "MINI", "link" : { "wid" : `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/modeltypes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=MINI&serviceName=mini_parts&upds=2026-02-10--14-...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", "path" : `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=MINI&modelType=R50&serviceName=mini_parts&upd...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", "path" : `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=MINI&modelType=R50&res1=HC&serviceName=mini_p...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", "path" : `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5bmw/extern/vehicle/restrictions3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=MINI&modelType=R50&res1=HC&res2=Cooper&servic...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini_parts&upds=2026-02-10--14-21", "id" : "MINI" } }, { "name" : "MINI", "link" : { "wid" : "modelTypeTable", "path" : `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/catmeta?serviceName=mini_parts&country=...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "MINI", "user24Brand" : "Mini", "l` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/models?lang=tr&serviceName=mini...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/modeltypes?lang=tr&mdl=MINI&ser...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions1?lang=tr&mdl=MINI&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions2?lang=tr&mdl=MINI&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/` |
|
||||||
|
| GET | `https://www.partslink24.com/p5bmw/extern/vehicle/restrictions3?lang=tr&mdl=MINI&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "MINI", "link" : { "wid" : "modelTable", "path" : "/` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: MINI, MINI, R50 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/mini_parts/0/eyJwYXRoIjoiL3A1Ym13L2V4dGVybi92ZWhpY2xlL3Jlc3RyaWN0aW9uczM%252FbGFuZz10ciZtZGw9TUlOSSZtb2RlbFR5cGU9UjUwJnJlczE9SEMmcmVzMj1Db29wZXImc2VydmljZU5hbWU9bWluaV9wYXJ0cyZ1cGRzPTIwMjYtMDItMTAtLTE0LTIxIiwid2lkIjoicmVzdHJpY3Rpb25UYWJsZTMiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
107
docs/pl24-catalog/mitsubishi.md
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# Mitsubishi — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:28:09.554Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5mitsubishi/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5mitsubishi/extern/catmeta?serviceName=mmc_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Mitsubishi", "user24Brand" : "Mitsubishi", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAOVBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAbAAAAAAAAAABDAADtAADtAABcAADtAADtAADtAADtAAAAAAC2aW4/AAAAEXRSTlMAv1Cl8Ic9JddoFOFwCEOXv/bxoKgAAA1L`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5mitsubishi/extern/vehicles/vehiclesOverview
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5mitsubishi/extern/vehicles/vehiclesOverview?lang=tr&serviceName=mmc_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", "path" : "/p5mitsubishi/extern/vehicles/vehiclesOverview?lang=tr&serviceName=mmc_parts&upds=SYSPROPS_UPDS" } } ], "demo" : true, "data" : { "records" : [ { "id" : "43", `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5mitsubishi/extern/vehicles/vehicles
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5mitsubishi/extern/vehicles/vehicles?lang=tr&serviceName=mmc_parts&upds=SYSPROPS_UPDS&vehic...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", "path" : "/p5mitsubishi/extern/vehicles/vehiclesOverview?lang=tr&serviceName=mmc_parts&upds=SYSPROPS_UPDS", "id" : "55" } }, { "name" : "COLT<CABRIOLET>(EUR/PF)", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5mitsubishi/extern/vehicles/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5mitsubishi/extern/vehicles/models?lang=tr&serviceName=mmc_parts&upds=SYSPROPS_UPDS&vehicle...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", "path" : "/p5mitsubishi/extern/vehicles/vehiclesOverview?lang=tr&serviceName=mmc_parts&upds=SYSPROPS_UPDS", "id" : "55" } }, { "name" : "COLT<CABRIOLET>(EUR/PF)", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5mitsubishi/extern/vehicles/classifications
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5mitsubishi/extern/vehicles/classifications?lang=tr&modelId=Z37A&serviceName=mmc_parts&upds...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", "path" : "/p5mitsubishi/extern/vehicles/vehiclesOverview?lang=tr&serviceName=mmc_parts&upds=SYSPROPS_UPDS", "id" : "55" } }, { "name" : "COLT<CABRIOLET>(EUR/PF)", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5mitsubishi/extern/catmeta?serviceName=mmc_parts&co...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Mitsubishi", "user24Brand" : "Mitsubish` |
|
||||||
|
| GET | `https://www.partslink24.com/p5mitsubishi/extern/vehicles/vehiclesOverview?lang=t...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5mitsubishi/extern/vehicles/vehiclesOverview?lang=t...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5mitsubishi/extern/vehicles/vehicles?lang=tr&servic...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5mitsubishi/extern/vehicles/models?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5mitsubishi/extern/vehicles/classifications?lang=tr...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Mitsubishi", "link" : { "wid" : "vehiclesOverviewTable", ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Mitsubishi, COLT<CABRIOLET>(EUR/PF), Z30# - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/mmc_parts/0/eyJwYXRoIjoiL3A1bWl0c3ViaXNoaS9leHRlcm4vdmVoaWNsZXMvY2xhc3NpZmljYXRpb25zP2xhbmc9dHImbW9kZWxJZD1aMzdBJnNlcnZpY2VOYW1lPW1tY19wYXJ0cyZ1cGRzPVNZU1BST1BTX1VQRFMmdmVoaWNsZT1DNjAxSDYwOEQmdmVoaWNsZU92ZXJ2aWV3PTU1Iiwid2lkIjoiY2xhc3NpZmljYXRpb25zVGFibGUiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/nissan.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Nissan — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:28:24.924Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Nissan TK3 - ATLEON (EL) - partslink24
|
||||||
|
- URL: https://www.partslink24.com/nissan/nissan_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.03+15%3A59%3A51+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/opel.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Opel — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:28:40.611Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Opel - partslink24
|
||||||
|
- URL: https://www.partslink24.com/opel/opel_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.21+07%3A11%3A24+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/peugeot.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Peugeot — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:28:56.262Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Peugeot 405 - partslink24
|
||||||
|
- URL: https://www.partslink24.com/psa/peugeot_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2024.02.13+09%3A27%3A21+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/polestar.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Polestar — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:29:12.071Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Polestar - partslink24
|
||||||
|
- URL: https://www.partslink24.com/volvo/polestar_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.19+14%3A46%3A42
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/porsche-classic.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Porsche Classic — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:29:43.212Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=porscheclassic_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Porsche Classic", "user24Brand" : "PorscheClassic", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAABDlBMVEUAAAA0MjMDAwQrKCc4My4nIh4DAwQDAwQDAwQDAwQDAwQ0MjMDAwRxYEU1MjIoJic0MjM1MjI0MjMsKCbJp2U0MjM0MjPJo1g0MjPyz4XRs3I0MjM0MjP`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=porscheclassic_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Porsche Classic", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=porscheclassic_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records" : `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=64449&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Porsche Classic", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=porscheclassic_parts&upds=2026-02-13--00-01", "id" : "64449_61_null" } }, { "name" : "Po`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=porscheclassic_par...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Porsche Classic", "user24Brand" : "Pors` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Porsche Classic", "link" : { "wid" : "modelFamiliesTable"` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Porsche Classic", "link" : { "wid" : "modelFamiliesTable"` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=64449&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Porsche Classic", "link" : { "wid" : "modelFamiliesTable"` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Porsche Classic - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/porscheclassic_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT02NDQ0OSZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9NjEmc2VydmljZU5hbWU9cG9yc2NoZWNsYXNzaWNfcGFydHMmdXBkcz0yMDI2LTAyLTEzLS0wMC0wMSIsIndpZCI6Im1vZGVsWWVhclRhYmxlIn0%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/porsche.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Porsche — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:29:27.739Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=porsche_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Porsche", "user24Brand" : "Porsche", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAAv1QTFRFAAAAAAAAAAAAAAAANygOAAAAEw4IAAAAAAAAAAAA+Pj49vb2+Pj48vLv8O3n9PT08Orc7eXM9+6k592e2c2a5eTgysjFwcHAzMvM7Ozs8/Hk2sqizr`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=porsche_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Porsche", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=porsche_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records" : [ { "id" `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=85399&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Porsche", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=porsche_parts&upds=2026-02-13--00-01", "id" : "85399_6_null" } }, { "name" : "Porsche 992 GT3/RS`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=porsche_parts&coun...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Porsche", "user24Brand" : "Porsche", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Porsche", "link" : { "wid" : "modelFamiliesTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Porsche", "link" : { "wid" : "modelFamiliesTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=85399&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Porsche", "link" : { "wid" : "modelFamiliesTable", ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Porsche - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/porsche_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT04NTM5OSZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9NiZzZXJ2aWNlTmFtZT1wb3JzY2hlX3BhcnRzJnVwZHM9MjAyNi0wMi0xMy0tMDAtMDEiLCJ3aWQiOiJtb2RlbFllYXJUYWJsZSJ9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
107
docs/pl24-catalog/renault.md
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
# Renault — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:29:58.625Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/catmeta?serviceName=renault_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Renault", "user24Brand" : "Renault", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAABtQTFRFR3BMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaeHB7AAAAAh0Uk5TABdAYoKgwOl1MHDiAAAGVElEQVR42u2d0W6jMBREYzDY///FK62iVbslyZ0mI6`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/catalogs
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=renault_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=renault_parts&upds=2025-12-02--14-31" } } ], "demo" : true, "data" : { "records" : [ { "id" : "X55", "description" `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/models?catalog=X53&lang=tr&serviceName=renault_parts&upds=2025-12-0...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=renault_parts&upds=2025-12-02--14-31", "id" : "X53" } }, { "name" : "RENAULT 19", "link" : { "wid" : "modelTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/engines
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/engines?catalog=X53&lang=tr&model=B53&serviceName=renault_parts&upd...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=renault_parts&upds=2025-12-02--14-31", "id" : "X53" } }, { "name" : "RENAULT 19", "link" : { "wid" : "modelTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5renault/extern/vehicle/gearbox
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5renault/extern/vehicle/gearbox?catalog=X53&engineFamily=CXX&engineIndex=730&engineLevel=M0...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path" : "/p5renault/extern/vehicle/catalogs?lang=tr&serviceName=renault_parts&upds=2025-12-02--14-31", "id" : "X53" } }, { "name" : "RENAULT 19", "link" : { "wid" : "modelTable", `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/catmeta?serviceName=renault_parts&c...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Renault", "user24Brand" : "Renault", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceNam...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path"` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/catalogs?lang=tr&serviceNam...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path"` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/models?catalog=X53&lang=tr&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path"` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/engines?catalog=X53&lang=tr...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path"` |
|
||||||
|
| GET | `https://www.partslink24.com/p5renault/extern/vehicle/gearbox?catalog=X53&engineF...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Renault", "link" : { "wid" : "catalogTable", "path"` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Renault, RENAULT 19, 5 KAPILI SEDAN - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/renault_parts/0/eyJwYXRoIjoiL3A1cmVuYXVsdC9leHRlcm4vdmVoaWNsZS9nZWFyYm94P2NhdGFsb2c9WDUzJmVuZ2luZUZhbWlseT1DWFgmZW5naW5lSW5kZXg9NzMwJmVuZ2luZUxldmVsPU0wJmVuZ2luZVR5cGU9QzFHJmxhbmc9dHImbW9kZWw9QjUzJnNlcnZpY2VOYW1lPXJlbmF1bHRfcGFydHMmdXBkcz0yMDI1LTEyLTAyLS0xNC0zMSIsIndpZCI6ImdlYXJib3hUYWJsZSIsImF1dG8iOnRydWV9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/seat.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# SEAT — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:30:14.062Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=seat_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "SEAT", "user24Brand" : "Seat", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAAXNSR0IArs4c6QAAABtQTFRFR3BMAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAA3Ag5fQAAAAh0Uk5TABdAfJmwwuB6NPDJAAAE50lEQVR42u3cQU8iSRTA8dfNDPHYYTcTj01x4Wi6kOHoDsnE`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=seat_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "SEAT", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=seat_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records" : [ { "id" : "873`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=87368&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "SEAT", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=seat_parts&upds=2026-02-13--00-01", "id" : "87368_4_null" } }, { "name" : "Cordoba (SEAT)", "li`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=seat_parts&country...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "SEAT", "user24Brand" : "Seat", "l` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "SEAT", "link" : { "wid" : "modelFamiliesTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "SEAT", "link" : { "wid" : "modelFamiliesTable", "pa` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=87368&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "SEAT", "link" : { "wid" : "modelFamiliesTable", "pa` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: SEAT - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/seat_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT04NzM2OCZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9NCZzZXJ2aWNlTmFtZT1zZWF0X3BhcnRzJnVwZHM9MjAyNi0wMi0xMy0tMDAtMDEiLCJ3aWQiOiJtb2RlbFllYXJUYWJsZSJ9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
96
docs/pl24-catalog/smart.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# smart — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:30:45.180Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=smart_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "smart", "user24Brand" : "Smart", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAABaFBMVEVHcEyzsrKSkZGzsrLAv8DAv7/Gv7HdoQ3u7/Hy8vPh4ePp6evNzM2zsrK1tLSzsrKzs7OVlJSmpaW0s7PVmgHCwsP3ugT765vkqwyzsrKzsrPz8/Senp6Li4v09PTy8vPR0dLpui`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/scope
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=smart_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "smart", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=smart_parts&upds=ND" } } ], "demo" : true, "data" : { "records" : [ { "id" : "F-F", `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/modeltype
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggregatesVisible=false&blockPresel=true&lang...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "smart", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=smart_parts&upds=ND", "id" : "F-F" } }, { "name" : "Smart", "link" : { "wid" : "m`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5daimler/extern/vehicle/model
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregatesVisible=false&blockPresel=true&lang=tr&...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "smart", "link" : { "wid" : "scopeTable", "path" : "/p5daimler/extern/vehicle/scope?aggregatesVisible=false&blockPresel=true&lang=tr&serviceName=smart_parts&upds=ND", "id" : "F-F" } }, { "name" : "Smart", "link" : { "wid" : "m`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/catmeta?serviceName=smart_parts&cou...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "smart", "user24Brand" : "Smart", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?lang=tr&serviceName=s...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "smart", "link" : { "wid" : "scopeTable", "path" : "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/scope?aggregatesVisible=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "smart", "link" : { "wid" : "scopeTable", "path" : "` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/modeltype?aggTypeId=F&aggre...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "smart", "link" : { "wid" : "scopeTable", "path" : "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5daimler/extern/vehicle/model?aggTypeId=F&aggregate...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "smart", "link" : { "wid" : "scopeTable", "path" : "` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: smart, Smart - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/smart_parts/0/eyJwYXRoIjoiL3A1ZGFpbWxlci9leHRlcm4vdmVoaWNsZS9tb2RlbD9hZ2dUeXBlSWQ9RiZhZ2dyZWdhdGVzVmlzaWJsZT1mYWxzZSZibG9ja1ByZXNlbD10cnVlJmxhbmc9dHImbW9kZWxUeXBlPUM0NTImcHJvZHVjdENsYXNzSWQ9RiZzZXJ2aWNlTmFtZT1zbWFydF9wYXJ0cyZ1cGRzPU5EIiwid2lkIjoibW9kZWxUYWJsZSIsImF1dG8iOnRydWV9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
96
docs/pl24-catalog/suzuki.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# Suzuki — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:31:00.743Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5suzuki/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5suzuki/extern/catmeta?serviceName=suzuki_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Suzuki", "user24Brand" : "Suzuki", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVT`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5suzuki/extern/vehicle/modelFamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5suzuki/extern/vehicle/modelFamilies?lang=tr&serviceName=suzuki_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Suzuki", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5suzuki/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=suzuki_parts&upds=2026-02-18--14-38" } } ], "demo" : true, "data" : { "records" : [ { "id" : "A`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5suzuki/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5suzuki/extern/vehicle/models?allMarkets=false&family=SWIFT&lang=tr&serviceName=suzuki_part...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Suzuki", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5suzuki/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=suzuki_parts&upds=2026-02-18--14-38", "id" : "SWIFT" } }, { "name" : "SWIFT", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5suzuki/extern/vehicle/restr1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5suzuki/extern/vehicle/restr1?allMarkets=false&dateFrom=200404&dateTo=200811&family=SWIFT&l...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Suzuki", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5suzuki/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=suzuki_parts&upds=2026-02-18--14-38", "id" : "SWIFT" } }, { "name" : "SWIFT", "link" : { `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5suzuki/extern/catmeta?serviceName=suzuki_parts&cou...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Suzuki", "user24Brand" : "Suzuki", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5suzuki/extern/vehicle/modelFamilies?lang=tr&servic...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Suzuki", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5suzuki/extern/vehicle/modelFamilies?allMarkets=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Suzuki", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5suzuki/extern/vehicle/models?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Suzuki", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5suzuki/extern/vehicle/restr1?allMarkets=false&date...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Suzuki", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Suzuki, SWIFT - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/suzuki_parts/0/eyJwYXRoIjoiL3A1c3V6dWtpL2V4dGVybi92ZWhpY2xlL3Jlc3RyMT9hbGxNYXJrZXRzPWZhbHNlJmRhdGVGcm9tPTIwMDQwNCZkYXRlVG89MjAwODExJmZhbWlseT1TV0lGVCZsYW5nPXRyJm1haW5Nb2RlbENvZGU9UlM0MTNfUDIyJnNlcnZpY2VOYW1lPXN1enVraV9wYXJ0cyZ1cGRzPTIwMjYtMDItMTgtLTE0LTM4Iiwid2lkIjoiY2hhcmFjdGVyaXN0aWMxVGFibGUiLCJhdXRvIjp0cnVlfQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
129
docs/pl24-catalog/toyota.md
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
# Toyota — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:31:16.362Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/catmeta?serviceName=toyota_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Toyota", "user24Brand" : "Toyota", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAHlBMVEVHcEwjIywjIywjIywjIywjIywjIywjIywjIywjIyyuO+lqAAAACXRSTlMAGztefZq61u5F891tAAAIf0lEQVR42u2cS1PbSBDHx5gNzk1AdhPfBGQ34aYQqA03VxKy8c0mWQg3`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/modelFamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/modelFamilies?lang=tr&serviceName=toyota_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=toyota_parts&upds=2026-01-30--08-41" } } ], "demo" : true, "data" : { "records" : [ { "id" : "1`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/models
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/models?allMarkets=false&family=31&lang=tr&serviceName=toyota_parts&u...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=toyota_parts&upds=2026-01-30--08-41", "id" : "31" } }, { "name" : "COROLLA", "link" : { "`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/restr1
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/restr1?allMarkets=false&family=31&lang=tr&mainModelCode=553210&servi...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=toyota_parts&upds=2026-01-30--08-41", "id" : "31" } }, { "name" : "COROLLA", "link" : { "`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/restr2
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/restr2?allMarkets=false&family=31&lang=tr&mainModelCode=553210&restr...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=toyota_parts&upds=2026-01-30--08-41", "id" : "31" } }, { "name" : "COROLLA", "link" : { "`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/restr3
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/restr3?allMarkets=false&family=31&lang=tr&mainModelCode=553210&restr...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=toyota_parts&upds=2026-01-30--08-41", "id" : "31" } }, { "name" : "COROLLA", "link" : { "`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5toyota/extern/vehicle/modelCodes
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5toyota/extern/vehicle/modelCodes?allMarkets=false&family=31&lang=tr&mainModelCode=553210&r...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5toyota/extern/vehicle/modelFamilies?allMarkets=false&lang=tr&serviceName=toyota_parts&upds=2026-01-30--08-41", "id" : "31" } }, { "name" : "COROLLA", "link" : { "`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/catmeta?serviceName=toyota_parts&cou...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Toyota", "user24Brand" : "Toyota", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/modelFamilies?lang=tr&servic...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/modelFamilies?allMarkets=fal...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/models?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/restr1?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/restr2?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/restr3?allMarkets=false&fami...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
| GET | `https://www.partslink24.com/p5toyota/extern/vehicle/modelCodes?allMarkets=false&...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Toyota", "link" : { "wid" : "modelFamiliesTable", "` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Toyota, COROLLA, COROLLA CROSS (JPP) (Basl... - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/toyota_parts/0/eyJwYXRoIjoiL3A1dG95b3RhL2V4dGVybi92ZWhpY2xlL21vZGVsQ29kZXM%252FYWxsTWFya2V0cz1mYWxzZSZmYW1pbHk9MzEmbGFuZz10ciZtYWluTW9kZWxDb2RlPTU1MzIxMCZyZXN0cjE9X2FyYml0cmFyeV8mcmVzdHIyPV9hcmJpdHJhcnlfJnJlc3RyMz1fYXJiaXRyYXJ5XyZzZXJ2aWNlTmFtZT10b3lvdGFfcGFydHMmdXBkcz0yMDI2LTAxLTMwLS0wOC00MSIsIndpZCI6Im1vZGVsQ29kZXNUYWJsZSIsImF1dG8iOnRydWV9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/vauxhall.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Vauxhall — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:31:31.730Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Vauxhall - partslink24
|
||||||
|
- URL: https://www.partslink24.com/opel/vauxhall_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.21+07%3A11%3A24+CET
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/volkswagen-classic.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Volkswagen Classic — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:32:02.771Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=vwclassic_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Volkswagen Classic", "user24Brand" : "VW", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAAD9QTFRFR3BMADJeABdJP2uKADxm////ACNSAjxmfZqu+fv7Ll6AB0FpzNjfkKm68fX1HE9zvMvUpbnG3eXpVHuVaYyjLQdeSgAAAAp0Uk5TAP//////`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=vwclassic_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Volkswagen Classic", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=vwclassic_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records" : [ `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=90059&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Volkswagen Classic", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=vwclassic_parts&upds=2026-02-13--00-01", "id" : "90059_11_null" } }, { "name" : "VW-I`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=vwclassic_parts&co...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Volkswagen Classic", "user24Brand" : "V` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen Classic", "link" : { "wid" : "modelFamiliesTab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen Classic", "link" : { "wid" : "modelFamiliesTab` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=90059&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen Classic", "link" : { "wid" : "modelFamiliesTab` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Volkswagen Classic - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/vwclassic_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT05MDA1OSZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9MTEmc2VydmljZU5hbWU9dndjbGFzc2ljX3BhcnRzJnVwZHM9MjAyNi0wMi0xMy0tMDAtMDEiLCJ3aWQiOiJtb2RlbFllYXJUYWJsZSJ9/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/volkswagen-commercial-vehicles.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Volkswagen Commercial Vehicles — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:32:18.174Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=vn_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Volkswagen Commercial Vehicles", "user24Brand" : "VW", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAMAAABOo35HAAAAAXNSR0IArs4c6QAAACdQTFRFR3BMAB1RAB5QAB5QAB1QAB1QAB5QAB5QAB5QAB1QAB5QAB5QAB5QOuADRgAAAAx0Uk5TAA4gNk5lgJ23zuDx4n4xwwAADfdJ`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=vn_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Volkswagen Commercial Vehicles", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=vn_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records"`
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=90079&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Volkswagen Commercial Vehicles", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=vn_parts&upds=2026-02-13--00-01", "id" : "90079_3_12" } }, { "name" : "Ca`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=vn_parts&country=D...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Volkswagen Commercial Vehicles", "user2` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen Commercial Vehicles", "link" : { "wid" : "mode` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen Commercial Vehicles", "link" : { "wid" : "mode` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=90079&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen Commercial Vehicles", "link" : { "wid" : "mode` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Volkswagen Commercial Veh... - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/vn_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT05MDA3OSZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9MyZvcmRpbmFsTnVtYmVyMj0xMiZzZXJ2aWNlTmFtZT12bl9wYXJ0cyZ1cGRzPTIwMjYtMDItMTMtLTAwLTAxIiwid2lkIjoibW9kZWxZZWFyVGFibGUifQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
85
docs/pl24-catalog/volkswagen.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Volkswagen — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:31:47.327Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
### /pl24-appgtw/ext/api/1.0/legal/tr
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-privacy/tr/tr/partslink24-privacy.html"},{"name":"partslink24-tos","url":"https://www.lexcom.de/legal/partslink24-tos/tr/tr/partslink24-tos.html"},{"name":"general-dataprocessing","url":"https://www.lexco`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/catmeta
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=vw_parts&country=DE&lang=tr`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "data" : { "carbrand" : { "brandName" : "Volkswagen", "user24Brand" : "VW", "logo" : "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsBAMAAACLU5NGAAAAAXNSR0IArs4c6QAAACRQTFRFR3BMADFeADBeADBfADBfADBfATBfATBfATBfATBfATBfATBf/cnSjQAAAAt0Uk5TAAsbMEpkgqK/2u8YmuyPAAAO5ElEQVR42uyYTU8TURSG73RKFVcT`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelfamilies
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceName=vw_parts`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Volkswagen", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=vw_parts&upds=2026-02-13--00-01" } } ], "demo" : true, "data" : { "records" : [ { "id" : `
|
||||||
|
- **Çağrı sayısı:** 2
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", "btn_label_check_parts_for_vin": "Validate parts", "btn_label_create_cart": "Create shopping cart", "btn_label_create_new_cart": "Create new shopping cart", "btn_label_create_template": "Create `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.json`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_label_check_parts_for_vin": "Parçaları doğrula", "btn_label_create_cart": "Ürün sepeti oluştur", "btn_label_create_new_cart": "Yeni ürün sepeti oluştur", "btn_label_create_template": "Şablon oluştu`
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
### /p5vwag/extern/vehicle/modelyears
|
||||||
|
- **Method:** GET
|
||||||
|
- **Status:** 200
|
||||||
|
- **Faz:** marka-ana-sayfa
|
||||||
|
- **Örnek URL:**
|
||||||
|
`https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=84071&lang=tr&localMarketOnly=true&modelInfo=true...`
|
||||||
|
- **Yanıt özeti:**
|
||||||
|
`{ "crumbs" : [ { "name" : "Volkswagen", "link" : { "wid" : "modelFamiliesTable", "path" : "/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMarketOnly=true&serviceName=vw_parts&upds=2026-02-13--00-01", "id" : "84071_1_null" } }, { "name" : "ID.4", "link" : `
|
||||||
|
- **Çağrı sayısı:** 1
|
||||||
|
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| GET | `https://www.partslink24.com/pl24-appgtw/ext/api/1.0/legal/tr` | 200 | marka-ana-sayfa | `{"legalDocuments":[{"name":"partslink24-privacy","url":"https://www.lexcom.de/legal/partslink24-priv` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/catmeta?serviceName=vw_parts&country=D...` | 200 | marka-ana-sayfa | `{ "data" : { "carbrand" : { "brandName" : "Volkswagen", "user24Brand" : "VW", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&serviceN...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen", "link" : { "wid" : "modelFamiliesTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelfamilies?lang=tr&localMar...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen", "link" : { "wid" : "modelFamiliesTable", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/en.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "To shopping cart selection", "back_to_template_list": "To templates", ` |
|
||||||
|
| GET | `https://www.partslink24.com/pl24-cart-embedded-ui/mf/2.0.14/assets/locales/tr.js...` | 200 | marka-ana-sayfa | `{ "back_to_cart_list": "ürün sepeti seçimine", "back_to_template_list": "şablonlara", "btn_lab` |
|
||||||
|
| GET | `https://www.partslink24.com/p5vwag/extern/vehicle/modelyears?familyKey=84071&lan...` | 200 | marka-ana-sayfa | `{ "crumbs" : [ { "name" : "Volkswagen", "link" : { "wid" : "modelFamiliesTable", ` |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Volkswagen - partslink24
|
||||||
|
- URL: https://www.partslink24.com/pl24-app/vw_parts/0/eyJwYXRoIjoiL3A1dndhZy9leHRlcm4vdmVoaWNsZS9tb2RlbHllYXJzP2ZhbWlseUtleT04NDA3MSZsYW5nPXRyJmxvY2FsTWFya2V0T25seT10cnVlJm1vZGVsSW5mbz10cnVlJm9yZGluYWxOdW1iZXI9MSZzZXJ2aWNlTmFtZT12d19wYXJ0cyZ1cGRzPTIwMjYtMDItMTMtLTAwLTAxIiwid2lkIjoibW9kZWxZZWFyVGFibGUifQ%253D%253D/
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
20
docs/pl24-catalog/volvo.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Volvo — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
2026-02-24T13:32:33.632Z
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
_Hiç API isteği yakalanmadı._
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
| — | — | — | — | — |
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
- Sayfa başlığı: Volvo - partslink24
|
||||||
|
- URL: https://www.partslink24.com/volvo/volvo_parts/vehicle.action?mode=K00U0DEXX&lang=tr&startup=true&upds=2026.02.19+14%3A46%3A42
|
||||||
|
- İlk model tıklanamadı — selector bulunamadı
|
||||||
@@ -3,11 +3,11 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: "sase-api",
|
name: "sase-api",
|
||||||
cwd: "./apps/api",
|
cwd: "./apps/api",
|
||||||
script: "pnpm",
|
script: "node",
|
||||||
args: "dev",
|
args: "--enable-source-maps dist/main.js",
|
||||||
exec_mode: "fork",
|
exec_mode: "fork",
|
||||||
env: {
|
env: {
|
||||||
NODE_ENV: "development",
|
NODE_ENV: "production",
|
||||||
PORT: 4000,
|
PORT: 4000,
|
||||||
OTEL_ENABLED: "true",
|
OTEL_ENABLED: "true",
|
||||||
OTEL_SERVICE_NAME: "sase-api",
|
OTEL_SERVICE_NAME: "sase-api",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 112 KiB |
122
scripts/migration-shared-vehicles.sql
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
-- Migration: Shared Vehicle Config (car-config-centric architecture)
|
||||||
|
-- Converts per-user vehicle records to shared vehicle configs with junction table.
|
||||||
|
-- IMPORTANT: Take a DB backup before running. Execute inside a transaction.
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- 1. Create user_vehicles junction table
|
||||||
|
CREATE TABLE user_vehicles (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
vehicle_id UUID NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
last_accessed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 2. For each VIN, pick the canonical record (most recently updated)
|
||||||
|
-- and migrate all userId-vehicleId pairs into the junction table
|
||||||
|
INSERT INTO user_vehicles (user_id, vehicle_id, created_at, last_accessed_at)
|
||||||
|
SELECT
|
||||||
|
v.user_id,
|
||||||
|
canonical.id,
|
||||||
|
v.created_at,
|
||||||
|
v.updated_at
|
||||||
|
FROM vehicles v
|
||||||
|
JOIN (
|
||||||
|
SELECT DISTINCT ON (vin) id, vin
|
||||||
|
FROM vehicles
|
||||||
|
ORDER BY vin, updated_at DESC NULLS LAST
|
||||||
|
) canonical ON canonical.vin = v.vin;
|
||||||
|
|
||||||
|
-- 3. Delete categories on NON-canonical vehicles that already exist on the
|
||||||
|
-- canonical vehicle (same name+source), so the UPDATE in step 4 won't
|
||||||
|
-- hit the unique constraint.
|
||||||
|
WITH canonical AS (
|
||||||
|
SELECT DISTINCT ON (vin) id AS cid, vin
|
||||||
|
FROM vehicles ORDER BY vin, updated_at DESC NULLS LAST
|
||||||
|
)
|
||||||
|
DELETE FROM categories
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT c_dup.id
|
||||||
|
FROM categories c_dup
|
||||||
|
JOIN vehicles v ON c_dup.vehicle_id = v.id
|
||||||
|
JOIN canonical can ON can.vin = v.vin
|
||||||
|
WHERE v.id != can.cid
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1 FROM categories c_can
|
||||||
|
WHERE c_can.vehicle_id = can.cid
|
||||||
|
AND c_can.name = c_dup.name
|
||||||
|
AND c_can.source = c_dup.source
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 4. Move remaining categories from non-canonical vehicles to canonical
|
||||||
|
WITH canonical AS (
|
||||||
|
SELECT DISTINCT ON (vin) id AS cid, vin
|
||||||
|
FROM vehicles ORDER BY vin, updated_at DESC NULLS LAST
|
||||||
|
)
|
||||||
|
UPDATE categories c
|
||||||
|
SET vehicle_id = can.cid
|
||||||
|
FROM vehicles v JOIN canonical can ON can.vin = v.vin
|
||||||
|
WHERE c.vehicle_id = v.id AND v.id != can.cid;
|
||||||
|
|
||||||
|
-- 5. Delete parts on non-canonical vehicles that would conflict after move
|
||||||
|
-- (parts don't have a unique constraint, but let's keep data clean by
|
||||||
|
-- removing duplicates — same oemCode+categoryId on canonical vehicle)
|
||||||
|
WITH canonical AS (
|
||||||
|
SELECT DISTINCT ON (vin) id AS cid, vin
|
||||||
|
FROM vehicles ORDER BY vin, updated_at DESC NULLS LAST
|
||||||
|
)
|
||||||
|
DELETE FROM parts
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT p_dup.id
|
||||||
|
FROM parts p_dup
|
||||||
|
JOIN vehicles v ON p_dup.vehicle_id = v.id
|
||||||
|
JOIN canonical can ON can.vin = v.vin
|
||||||
|
WHERE v.id != can.cid
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1 FROM parts p_can
|
||||||
|
WHERE p_can.vehicle_id = can.cid
|
||||||
|
AND p_can.category_id = p_dup.category_id
|
||||||
|
AND p_can.oem_code = p_dup.oem_code
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 6. Move remaining parts from non-canonical vehicles to canonical
|
||||||
|
WITH canonical AS (
|
||||||
|
SELECT DISTINCT ON (vin) id AS cid, vin
|
||||||
|
FROM vehicles ORDER BY vin, updated_at DESC NULLS LAST
|
||||||
|
)
|
||||||
|
UPDATE parts p
|
||||||
|
SET vehicle_id = can.cid
|
||||||
|
FROM vehicles v JOIN canonical can ON can.vin = v.vin
|
||||||
|
WHERE p.vehicle_id = v.id AND v.id != can.cid;
|
||||||
|
|
||||||
|
-- 7. Delete non-canonical vehicle records (duplicates)
|
||||||
|
DELETE FROM vehicles WHERE id NOT IN (
|
||||||
|
SELECT DISTINCT ON (vin) id FROM vehicles
|
||||||
|
ORDER BY vin, updated_at DESC NULLS LAST
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 8. Drop old user-specific indexes and column
|
||||||
|
DROP INDEX IF EXISTS vehicles_user_vin_idx;
|
||||||
|
DROP INDEX IF EXISTS vehicles_user_id_idx;
|
||||||
|
ALTER TABLE vehicles DROP COLUMN user_id;
|
||||||
|
|
||||||
|
-- 9. Add unique index on VIN (one record per VIN globally)
|
||||||
|
CREATE UNIQUE INDEX vehicles_vin_unique_idx ON vehicles (vin);
|
||||||
|
|
||||||
|
-- 10. Add FK and indexes on junction table
|
||||||
|
ALTER TABLE user_vehicles
|
||||||
|
ADD CONSTRAINT user_vehicles_vehicle_id_fkey
|
||||||
|
FOREIGN KEY (vehicle_id) REFERENCES vehicles(id) ON DELETE CASCADE;
|
||||||
|
CREATE UNIQUE INDEX user_vehicles_user_vehicle_idx ON user_vehicles (user_id, vehicle_id);
|
||||||
|
CREATE INDEX user_vehicles_user_id_idx ON user_vehicles (user_id);
|
||||||
|
|
||||||
|
-- 11. Drop unused vehicle_categories table
|
||||||
|
DROP TABLE IF EXISTS vehicle_categories;
|
||||||
|
|
||||||
|
-- Also drop the old vin-only index if it exists (replaced by unique)
|
||||||
|
DROP INDEX IF EXISTS vehicles_vin_idx;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
742
scripts/pl24-catalog-explorer.js
Normal file
@@ -0,0 +1,742 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* PL24 Katalog Yapısı Keşif Script'i
|
||||||
|
*
|
||||||
|
* PL24 web arayüzüne (brandMenu.do) Playwright ile bağlanır,
|
||||||
|
* sol sidebar'daki her markayı tıklar ve arka planda yapılan
|
||||||
|
* XHR/fetch isteklerini intercept ederek API endpoint yapısını keşfeder.
|
||||||
|
* Her marka için docs/pl24-catalog/{brandSlug}.md oluşturur.
|
||||||
|
*
|
||||||
|
* Kullanım:
|
||||||
|
* node scripts/pl24-catalog-explorer.js # tüm markalar
|
||||||
|
* node scripts/pl24-catalog-explorer.js --brand VW # tek marka
|
||||||
|
* node scripts/pl24-catalog-explorer.js --headed # tarayıcı görünür
|
||||||
|
* node scripts/pl24-catalog-explorer.js --force # mevcut dosyaları yenile
|
||||||
|
* node scripts/pl24-catalog-explorer.js --delay 10000
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { chromium } = require("playwright");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
// PL24 .env'den kimlik bilgilerini yükle (dotenv bağımlılığı olmadan)
|
||||||
|
(function loadEnv() {
|
||||||
|
const envPath = path.join(__dirname, "../apps/api/.env");
|
||||||
|
if (!fs.existsSync(envPath)) return;
|
||||||
|
const lines = fs.readFileSync(envPath, "utf-8").split("\n");
|
||||||
|
for (const line of lines) {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
||||||
|
const eqIdx = trimmed.indexOf("=");
|
||||||
|
if (eqIdx < 1) continue;
|
||||||
|
const key = trimmed.substring(0, eqIdx).trim();
|
||||||
|
const val = trimmed.substring(eqIdx + 1).trim().replace(/^["']|["']$/g, "");
|
||||||
|
if (!process.env[key]) process.env[key] = val;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// ── Config ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const CONFIG = {
|
||||||
|
pl24BaseUrl: process.env.PL24_BASE_URL || "https://www.partslink24.com",
|
||||||
|
companyCode: process.env.PL24_COMPANY_CODE || "",
|
||||||
|
username: process.env.PL24_USERNAME || "",
|
||||||
|
password: process.env.PL24_PASSWORD || "",
|
||||||
|
brandMenuUrl: "/partslink24/user/brandMenu.do",
|
||||||
|
headless: true,
|
||||||
|
delayBetweenBrands: 8000, // ms — rate limit koruması
|
||||||
|
delayBetweenClicks: 3000, // ms — marka içi tıklamalar arası
|
||||||
|
navigationTimeout: 60000,
|
||||||
|
actionTimeout: 30000,
|
||||||
|
networkIdleTimeout: 5000, // API isteklerinin gelmesi için bekleme
|
||||||
|
outputDir: path.join(__dirname, "../docs/pl24-catalog"),
|
||||||
|
force: false,
|
||||||
|
filterBrand: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── CLI Args ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function parseArgs() {
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const opts = { ...CONFIG };
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
if (args[i] === "--headed") opts.headless = false;
|
||||||
|
if (args[i] === "--headless") opts.headless = true;
|
||||||
|
if (args[i] === "--force") opts.force = true;
|
||||||
|
if (args[i] === "--brand" && args[i + 1]) opts.filterBrand = args[++i].toUpperCase();
|
||||||
|
if (args[i] === "--delay" && args[i + 1]) opts.delayBetweenBrands = parseInt(args[++i], 10);
|
||||||
|
}
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||||
|
|
||||||
|
function ts() {
|
||||||
|
return new Date().toISOString().replace("T", " ").substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(msg) {
|
||||||
|
console.log(`[${ts()}] ${msg}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logSection(title) {
|
||||||
|
console.log(`\n${"═".repeat(70)}\n ${title}\n${"═".repeat(70)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function slugify(name) {
|
||||||
|
return name
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9]+/g, "-")
|
||||||
|
.replace(/^-|-$/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isApiRequest(url) {
|
||||||
|
// Sadece JSON API isteklerini filtrele
|
||||||
|
const u = url.toLowerCase();
|
||||||
|
return (
|
||||||
|
u.includes("/extern/") ||
|
||||||
|
u.includes("/p5vwag/") ||
|
||||||
|
u.includes("/p5bmw/") ||
|
||||||
|
u.includes("/p5daimler/") ||
|
||||||
|
u.includes("/p5toyota/") ||
|
||||||
|
u.includes("/p5jlr/") ||
|
||||||
|
u.includes("/p5renault/") ||
|
||||||
|
u.includes("/p5stellantis/") ||
|
||||||
|
u.includes("/p5hyundai/") ||
|
||||||
|
u.includes("/p5nissan/") ||
|
||||||
|
u.includes("/p5volvo/") ||
|
||||||
|
u.includes("/p5opel/") ||
|
||||||
|
u.includes("/ford/") ||
|
||||||
|
u.includes("/pl24-appgtw/") ||
|
||||||
|
u.includes("/pl24-manufacturer/") ||
|
||||||
|
u.includes("/auth/ext/") ||
|
||||||
|
(u.includes("partslink24.com") && (u.includes(".json") || u.includes("/api/")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Keşif Notları Yardımcısı ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
class BrandExplorer {
|
||||||
|
constructor(brandName) {
|
||||||
|
this.brandName = brandName;
|
||||||
|
this.requests = [];
|
||||||
|
this.notes = [];
|
||||||
|
this.startedAt = new Date().toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
|
addRequest({ method, url, status, responseBody, phase }) {
|
||||||
|
this.requests.push({ method, url, status, responseBody, phase });
|
||||||
|
}
|
||||||
|
|
||||||
|
addNote(note) {
|
||||||
|
this.notes.push(note);
|
||||||
|
log(` NOTE: ${note}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateMd() {
|
||||||
|
// Unique URL'leri grupla
|
||||||
|
const byPath = {};
|
||||||
|
for (const r of this.requests) {
|
||||||
|
try {
|
||||||
|
const u = new URL(r.url);
|
||||||
|
const pathKey = u.pathname;
|
||||||
|
if (!byPath[pathKey]) byPath[pathKey] = { ...r, count: 0, params: [] };
|
||||||
|
byPath[pathKey].count++;
|
||||||
|
if (u.search) byPath[pathKey].params.push(u.search);
|
||||||
|
} catch {
|
||||||
|
// geçersiz URL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const endpointList = Object.entries(byPath)
|
||||||
|
.map(([p, r]) => {
|
||||||
|
const exampleUrl = r.url.length > 120 ? r.url.substring(0, 120) + "..." : r.url;
|
||||||
|
const bodyPreview = r.responseBody
|
||||||
|
? r.responseBody.substring(0, 300).replace(/\n/g, " ")
|
||||||
|
: "(yanıt yok)";
|
||||||
|
return `### ${p}\n- **Method:** ${r.method}\n- **Status:** ${r.status || "?"}\n- **Faz:** ${r.phase}\n- **Örnek URL:**\n \`${exampleUrl}\`\n- **Yanıt özeti:**\n \`${bodyPreview}\`\n- **Çağrı sayısı:** ${r.count}\n`;
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
const requestTable = this.requests
|
||||||
|
.map((r) => {
|
||||||
|
const shortUrl = r.url.length > 80 ? r.url.substring(0, 80) + "..." : r.url;
|
||||||
|
const body = r.responseBody
|
||||||
|
? r.responseBody.substring(0, 100).replace(/\|/g, "\\|").replace(/\n/g, " ")
|
||||||
|
: "";
|
||||||
|
return `| ${r.method} | \`${shortUrl}\` | ${r.status || "?"} | ${r.phase} | \`${body}\` |`;
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
const notesList = this.notes.map((n) => `- ${n}`).join("\n") || "- Özel not yok";
|
||||||
|
|
||||||
|
return `# ${this.brandName} — PL24 Katalog Yapısı
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
${this.startedAt}
|
||||||
|
|
||||||
|
## Tespit Edilen Endpoint'ler (Unique Path'ler)
|
||||||
|
|
||||||
|
${endpointList || "_Hiç API isteği yakalanmadı._"}
|
||||||
|
|
||||||
|
## Ham Yakalanan İstekler
|
||||||
|
|
||||||
|
| Method | URL | Status | Faz | Response (ilk 100 char) |
|
||||||
|
|--------|-----|--------|-----|------------------------|
|
||||||
|
${requestTable || "| — | — | — | — | — |"}
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
|
||||||
|
${notesList}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Login ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PL24 REST API üzerinden login olup session cookie'yi Playwright context'e enjekte eder.
|
||||||
|
* Web formu yerine doğrudan /pl24-appgtw/ext/api/1.0/login endpoint'i kullanılır.
|
||||||
|
*/
|
||||||
|
async function loginToPL24(page, opts) {
|
||||||
|
log("PL24 REST API login başlıyor...");
|
||||||
|
|
||||||
|
// 1. REST API ile login — web form bypass
|
||||||
|
const loginBody = {
|
||||||
|
authentication: {
|
||||||
|
account: opts.companyCode,
|
||||||
|
user: opts.username,
|
||||||
|
pwd: opts.password,
|
||||||
|
},
|
||||||
|
device: {
|
||||||
|
id: "0",
|
||||||
|
os: "Windows 10",
|
||||||
|
offset: "0",
|
||||||
|
lang: "en-US",
|
||||||
|
"os-version": "0",
|
||||||
|
},
|
||||||
|
"app-version": "",
|
||||||
|
squeezeOut: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const loginResp = await fetch(
|
||||||
|
`${opts.pl24BaseUrl}/pl24-appgtw/ext/api/1.0/login`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(loginBody),
|
||||||
|
signal: AbortSignal.timeout(opts.actionTimeout),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!loginResp.ok) {
|
||||||
|
throw new Error(`REST login HTTP ${loginResp.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loginData = await loginResp.json();
|
||||||
|
if (!loginData.token?.access_token) {
|
||||||
|
throw new Error(`REST login başarısız: ${loginData.status} — ${loginData.message || "token yok"}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessToken = loginData.token.access_token;
|
||||||
|
log(`REST login başarılı. Token: ${accessToken.substring(0, 30)}...`);
|
||||||
|
|
||||||
|
// Session cookie
|
||||||
|
const setCookie = loginResp.headers.get("set-cookie") || "";
|
||||||
|
const pl24TokenMatch = setCookie.match(/PL24TOKEN=([^;]+)/);
|
||||||
|
const jsessionMatch = setCookie.match(/JSESSIONID=([^;]+)/);
|
||||||
|
const pl24Token = pl24TokenMatch ? `PL24TOKEN=${pl24TokenMatch[1]}` : "";
|
||||||
|
const jsession = jsessionMatch ? `JSESSIONID=${jsessionMatch[1]}` : "";
|
||||||
|
log(`Cookie: ${pl24Token || jsession || "(yok)"}`);
|
||||||
|
|
||||||
|
// 2. Cookie'leri Playwright context'e enjekte et
|
||||||
|
const context = page.context();
|
||||||
|
const cookiesToSet = [];
|
||||||
|
|
||||||
|
if (pl24TokenMatch) {
|
||||||
|
cookiesToSet.push({ name: "PL24TOKEN", value: pl24TokenMatch[1], domain: "www.partslink24.com", path: "/" });
|
||||||
|
}
|
||||||
|
if (jsessionMatch) {
|
||||||
|
cookiesToSet.push({ name: "JSESSIONID", value: jsessionMatch[1], domain: "www.partslink24.com", path: "/" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cookiesToSet.length > 0) {
|
||||||
|
await context.addCookies(cookiesToSet);
|
||||||
|
log(`${cookiesToSet.length} cookie enjekte edildi`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Önce ana sayfayı ziyaret et (session kurmak için)
|
||||||
|
log("Ana sayfa ziyaret ediliyor...");
|
||||||
|
await page.goto(`${opts.pl24BaseUrl}/`, {
|
||||||
|
waitUntil: "networkidle",
|
||||||
|
timeout: opts.navigationTimeout,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. Formu JWT token ile doldurarak login yap
|
||||||
|
const currentUrl = page.url();
|
||||||
|
log(`URL: ${currentUrl}`);
|
||||||
|
|
||||||
|
if (currentUrl.includes("brandMenu")) {
|
||||||
|
log("Giriş yapılmış (cookie çalıştı)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUrl.includes("login")) {
|
||||||
|
// Form görünüyor — doldur ve submit et
|
||||||
|
log("Login formu dolduruluyor...");
|
||||||
|
await page.fill("#login-id", opts.companyCode);
|
||||||
|
await page.fill("#login-name", opts.username);
|
||||||
|
await page.fill("#inputPassword", opts.password);
|
||||||
|
|
||||||
|
// JavaScript ile doLoginAjax çağır
|
||||||
|
log("doLoginAjax çağrılıyor...");
|
||||||
|
await page.evaluate(() => {
|
||||||
|
if (typeof doLoginAjax === "function") {
|
||||||
|
doLoginAjax(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Redirect bekle
|
||||||
|
try {
|
||||||
|
await page.waitForURL(/brandMenu|portal|welcome/, { timeout: 30000 });
|
||||||
|
log("Login başarılı — redirect oldu");
|
||||||
|
} catch {
|
||||||
|
await sleep(3000);
|
||||||
|
const url2 = page.url();
|
||||||
|
log(`Login sonrası URL: ${url2}`);
|
||||||
|
if (url2.includes("login")) {
|
||||||
|
// HTML hata mesajını kaydet
|
||||||
|
const html = await page.content();
|
||||||
|
require("fs").writeFileSync("/tmp/pl24-login-error.html", html);
|
||||||
|
throw new Error(`Login başarısız: ${url2} (HTML → /tmp/pl24-login-error.html)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. brandMenu.do'ya git
|
||||||
|
log("brandMenu.do'ya gidiliyor...");
|
||||||
|
await page.goto(`${opts.pl24BaseUrl}/partslink24/user/brandMenu.do`, {
|
||||||
|
waitUntil: "networkidle",
|
||||||
|
timeout: opts.navigationTimeout,
|
||||||
|
});
|
||||||
|
|
||||||
|
const finalUrl = page.url();
|
||||||
|
log(`brandMenu URL: ${finalUrl}`);
|
||||||
|
|
||||||
|
if (finalUrl.includes("login")) {
|
||||||
|
throw new Error(`brandMenu'ya erişilemedi, login gerekiyor: ${finalUrl}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
log("PL24'e başarıyla giriş yapıldı!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Marka Listesi ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
async function getBrandList(page) {
|
||||||
|
log("Marka listesi okunuyor...");
|
||||||
|
|
||||||
|
// brandMenu.do'da markalar: <a class="brand-logo" href="/partslink24/launchCatalog.do?service=vw_parts&t=..." title="Volkswagen">
|
||||||
|
try {
|
||||||
|
const count = await page.locator("a.brand-logo").count();
|
||||||
|
if (count > 0) {
|
||||||
|
log(` a.brand-logo selector: ${count} marka bulundu`);
|
||||||
|
const brands = await page.$$eval("a.brand-logo", (els) =>
|
||||||
|
els.map((el) => {
|
||||||
|
const href = el.getAttribute("href") || "";
|
||||||
|
// service adını URL'den çıkar: ?service=vw_parts&...
|
||||||
|
const serviceMatch = href.match(/[?&]service=([^&]+)/);
|
||||||
|
return {
|
||||||
|
name: el.getAttribute("title") || el.textContent?.trim() || "",
|
||||||
|
href,
|
||||||
|
service: serviceMatch ? serviceMatch[1] : "",
|
||||||
|
onclick: el.getAttribute("onclick") || "",
|
||||||
|
};
|
||||||
|
}).filter((b) => b.name.length > 0)
|
||||||
|
);
|
||||||
|
// Servis adına göre deduplicate (brandMenu.do her markayı 2 kez gösteriyor)
|
||||||
|
const seen = new Set();
|
||||||
|
const unique = brands.filter((b) => {
|
||||||
|
if (!b.service || seen.has(b.service)) return false;
|
||||||
|
seen.add(b.service);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
log(` ${unique.length} marka listelendi (${brands.length - unique.length} duplicate atlandı):`);
|
||||||
|
for (const b of unique) {
|
||||||
|
log(` ${b.name} (${b.service}) → ${b.href.substring(0, 60)}`);
|
||||||
|
}
|
||||||
|
return unique;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
log(` a.brand-logo selector hatası: ${err.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: launchCatalog.do içeren linkleri ara
|
||||||
|
log(" Fallback: launchCatalog.do linkleri aranıyor...");
|
||||||
|
try {
|
||||||
|
const brands = await page.$$eval("a[href*='launchCatalog']", (els) =>
|
||||||
|
els.map((el) => {
|
||||||
|
const href = el.getAttribute("href") || "";
|
||||||
|
const serviceMatch = href.match(/[?&]service=([^&]+)/);
|
||||||
|
const title = el.getAttribute("title") || el.textContent?.trim() || "";
|
||||||
|
return {
|
||||||
|
name: title,
|
||||||
|
href,
|
||||||
|
service: serviceMatch ? serviceMatch[1] : "",
|
||||||
|
onclick: el.getAttribute("onclick") || "",
|
||||||
|
};
|
||||||
|
}).filter((b) => b.name.length > 0)
|
||||||
|
);
|
||||||
|
if (brands.length > 0) {
|
||||||
|
log(` ${brands.length} marka (launchCatalog fallback):`);
|
||||||
|
for (const b of brands) {
|
||||||
|
log(` ${b.name} (${b.service})`);
|
||||||
|
}
|
||||||
|
return brands;
|
||||||
|
}
|
||||||
|
} catch { /* devam */ }
|
||||||
|
|
||||||
|
// Son çare: sayfa kaynağını kaydet ve hata ver
|
||||||
|
log(" UYARI: Marka listesi bulunamadı, sayfa HTML kaydediliyor...");
|
||||||
|
const bodyHtml = await page.evaluate(() => document.body?.innerHTML?.substring(0, 5000) || "");
|
||||||
|
log(" Sayfa HTML (ilk 5000 char):");
|
||||||
|
console.log(bodyHtml);
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Tek Marka Keşfi ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
async function exploreBrand(page, brand, opts) {
|
||||||
|
const explorer = new BrandExplorer(brand.name);
|
||||||
|
log(`\nKeşif başlıyor: ${brand.name}`);
|
||||||
|
|
||||||
|
// Network intercept'i başlat
|
||||||
|
const requestLog = [];
|
||||||
|
|
||||||
|
const onRequest = (req) => {
|
||||||
|
const url = req.url();
|
||||||
|
if (isApiRequest(url)) {
|
||||||
|
requestLog.push({ method: req.method(), url, phase: "request", status: null, responseBody: null });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onResponse = async (res) => {
|
||||||
|
const url = res.url();
|
||||||
|
if (!isApiRequest(url)) return;
|
||||||
|
const status = res.status();
|
||||||
|
let responseBody = null;
|
||||||
|
try {
|
||||||
|
const ct = res.headers()["content-type"] || "";
|
||||||
|
if (ct.includes("json") || ct.includes("text")) {
|
||||||
|
const text = await res.text();
|
||||||
|
responseBody = text.substring(0, 1000);
|
||||||
|
}
|
||||||
|
} catch { /* body alınamadı */ }
|
||||||
|
|
||||||
|
// Mevcut request'i güncelle veya yeni ekle
|
||||||
|
const existing = requestLog.find((r) => r.url === url && r.status === null);
|
||||||
|
if (existing) {
|
||||||
|
existing.status = status;
|
||||||
|
existing.responseBody = responseBody;
|
||||||
|
} else {
|
||||||
|
requestLog.push({ method: res.request().method(), url, phase: "response", status, responseBody });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
page.on("request", onRequest);
|
||||||
|
page.on("response", onResponse);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// ── Faz 1: Markayı tıkla ──────────────────────────────────────────────
|
||||||
|
log(` Faz 1: Marka tıklanıyor — ${brand.name}`);
|
||||||
|
|
||||||
|
if (brand.href && brand.href !== "#" && brand.href !== "") {
|
||||||
|
const fullUrl = brand.href.startsWith("http")
|
||||||
|
? brand.href
|
||||||
|
: `${opts.pl24BaseUrl}${brand.href}`;
|
||||||
|
await page.goto(fullUrl, { waitUntil: "domcontentloaded", timeout: opts.navigationTimeout });
|
||||||
|
} else if (brand.onclick) {
|
||||||
|
await page.evaluate((onclick) => eval(onclick), brand.onclick);
|
||||||
|
} else {
|
||||||
|
// Metin ile bul ve tıkla
|
||||||
|
const el = page.locator(`a:has-text("${brand.name}")`).first();
|
||||||
|
await el.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// API isteklerinin gelmesi için bekle
|
||||||
|
await sleep(opts.networkIdleTimeout);
|
||||||
|
|
||||||
|
// Sayfanın yapısını incele
|
||||||
|
const pageTitle = await page.title().catch(() => "");
|
||||||
|
log(` Sayfa başlığı: ${pageTitle}`);
|
||||||
|
explorer.addNote(`Sayfa başlığı: ${pageTitle}`);
|
||||||
|
explorer.addNote(`URL: ${page.url()}`);
|
||||||
|
|
||||||
|
// Faz 1 isteklerini kaydet
|
||||||
|
const phase1Requests = [...requestLog];
|
||||||
|
for (const r of phase1Requests) {
|
||||||
|
explorer.addRequest({ ...r, phase: "marka-ana-sayfa" });
|
||||||
|
}
|
||||||
|
requestLog.length = 0;
|
||||||
|
|
||||||
|
log(` Faz 1: ${phase1Requests.length} API isteği yakalandı`);
|
||||||
|
|
||||||
|
// ── Faz 2: İlk model/araç'ı tıkla ──────────────────────────────────────
|
||||||
|
log(" Faz 2: İlk model aranıyor...");
|
||||||
|
|
||||||
|
const modelSelectors = [
|
||||||
|
".model-list li:first-child a",
|
||||||
|
".vehicleList li:first-child a",
|
||||||
|
".modelSeries li:first-child a",
|
||||||
|
"table.models tr:nth-child(2) td:first-child a",
|
||||||
|
".content a:first-child",
|
||||||
|
"ul li a:first-child",
|
||||||
|
];
|
||||||
|
|
||||||
|
let modelClicked = false;
|
||||||
|
for (const sel of modelSelectors) {
|
||||||
|
try {
|
||||||
|
const el = page.locator(sel).first();
|
||||||
|
if (await el.isVisible({ timeout: 2000 })) {
|
||||||
|
const modelName = await el.textContent();
|
||||||
|
log(` İlk model tıklanıyor: "${modelName?.trim()}" (${sel})`);
|
||||||
|
await el.click();
|
||||||
|
await sleep(opts.delayBetweenClicks);
|
||||||
|
modelClicked = true;
|
||||||
|
explorer.addNote(`İlk model tıklandı: "${modelName?.trim()}"`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch { /* devam */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!modelClicked) {
|
||||||
|
explorer.addNote("İlk model tıklanamadı — selector bulunamadı");
|
||||||
|
log(" Faz 2: Model selector bulunamadı, atlanıyor");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Faz 2 isteklerini kaydet
|
||||||
|
const phase2Requests = [...requestLog];
|
||||||
|
for (const r of phase2Requests) {
|
||||||
|
explorer.addRequest({ ...r, phase: "model-secim" });
|
||||||
|
}
|
||||||
|
requestLog.length = 0;
|
||||||
|
|
||||||
|
log(` Faz 2: ${phase2Requests.length} ek API isteği yakalandı`);
|
||||||
|
|
||||||
|
// ── Faz 3: Kategoriler ───────────────────────────────────────────────────
|
||||||
|
log(" Faz 3: Kategori yapısı inceleniyor...");
|
||||||
|
|
||||||
|
const categorySelectors = [
|
||||||
|
".mainGroup li:first-child a",
|
||||||
|
".categoryList li:first-child a",
|
||||||
|
".groups li:first-child a",
|
||||||
|
"ul.mainGroups li:first-child a",
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const sel of categorySelectors) {
|
||||||
|
try {
|
||||||
|
const el = page.locator(sel).first();
|
||||||
|
if (await el.isVisible({ timeout: 2000 })) {
|
||||||
|
const catName = await el.textContent();
|
||||||
|
log(` İlk kategori tıklanıyor: "${catName?.trim()}" (${sel})`);
|
||||||
|
await el.click();
|
||||||
|
await sleep(opts.delayBetweenClicks);
|
||||||
|
explorer.addNote(`İlk kategori tıklandı: "${catName?.trim()}"`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch { /* devam */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
const phase3Requests = [...requestLog];
|
||||||
|
for (const r of phase3Requests) {
|
||||||
|
explorer.addRequest({ ...r, phase: "kategori" });
|
||||||
|
}
|
||||||
|
requestLog.length = 0;
|
||||||
|
|
||||||
|
log(` Faz 3: ${phase3Requests.length} ek API isteği yakalandı`);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
explorer.addNote(`HATA: ${err.message}`);
|
||||||
|
log(` HATA: ${err.message}`);
|
||||||
|
} finally {
|
||||||
|
page.off("request", onRequest);
|
||||||
|
page.off("response", onResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return explorer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ana Akış ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const opts = parseArgs();
|
||||||
|
|
||||||
|
if (!opts.companyCode || !opts.username || !opts.password) {
|
||||||
|
console.error("HATA: PL24 kimlik bilgileri eksik. apps/api/.env dosyasını kontrol edin.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Çıktı dizinini oluştur
|
||||||
|
if (!fs.existsSync(opts.outputDir)) {
|
||||||
|
fs.mkdirSync(opts.outputDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
logSection("PL24 KATALOG KEŞİF ARACI");
|
||||||
|
log(`PL24 URL: ${opts.pl24BaseUrl}`);
|
||||||
|
log(`Headless: ${opts.headless}, Delay: ${opts.delayBetweenBrands}ms, Force: ${opts.force}`);
|
||||||
|
if (opts.filterBrand) log(`Marka filtresi: ${opts.filterBrand}`);
|
||||||
|
|
||||||
|
// Tarayıcı başlat
|
||||||
|
const browser = await chromium.launch({
|
||||||
|
headless: opts.headless,
|
||||||
|
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const context = await browser.newContext({
|
||||||
|
viewport: { width: 1440, height: 900 },
|
||||||
|
ignoreHTTPSErrors: true,
|
||||||
|
userAgent:
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||||
|
});
|
||||||
|
|
||||||
|
context.setDefaultTimeout(opts.actionTimeout);
|
||||||
|
context.setDefaultNavigationTimeout(opts.navigationTimeout);
|
||||||
|
|
||||||
|
const page = await context.newPage();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Login
|
||||||
|
logSection("LOGIN");
|
||||||
|
await loginToPL24(page, opts);
|
||||||
|
|
||||||
|
// Screenshot: brandMenu
|
||||||
|
await page.screenshot({
|
||||||
|
path: path.join(opts.outputDir, "_brandmenu-screenshot.png"),
|
||||||
|
});
|
||||||
|
log("brandMenu.do ekran görüntüsü kaydedildi");
|
||||||
|
|
||||||
|
// Marka listesi
|
||||||
|
logSection("MARKA LİSTESİ");
|
||||||
|
let brands = await getBrandList(page);
|
||||||
|
|
||||||
|
if (brands.length === 0) {
|
||||||
|
log("UYARI: Marka listesi boş — sayfa yapısı analiz ediliyor...");
|
||||||
|
// Sayfa kaynağını kaydet
|
||||||
|
const html = await page.content();
|
||||||
|
fs.writeFileSync(path.join(opts.outputDir, "_brandmenu-source.html"), html);
|
||||||
|
log("Sayfa kaynağı _brandmenu-source.html olarak kaydedildi");
|
||||||
|
}
|
||||||
|
|
||||||
|
log(`Toplam ${brands.length} marka bulundu`);
|
||||||
|
|
||||||
|
// Filtrele (hem marka adına hem service adına bak)
|
||||||
|
if (opts.filterBrand) {
|
||||||
|
brands = brands.filter((b) =>
|
||||||
|
b.name.toUpperCase().includes(opts.filterBrand) ||
|
||||||
|
(b.service || "").toUpperCase().includes(opts.filterBrand)
|
||||||
|
);
|
||||||
|
log(`Filtre sonrası: ${brands.length} marka`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (brands.length === 0) {
|
||||||
|
log("İşlenecek marka yok. Çıkılıyor.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Özet için marka bilgilerini tut
|
||||||
|
const summaryData = [];
|
||||||
|
|
||||||
|
// ── Her Marka ─────────────────────────────────────────────────────────
|
||||||
|
for (let i = 0; i < brands.length; i++) {
|
||||||
|
const brand = brands[i];
|
||||||
|
const slug = slugify(brand.name);
|
||||||
|
const outFile = path.join(opts.outputDir, `${slug}.md`);
|
||||||
|
|
||||||
|
logSection(`[${i + 1}/${brands.length}] ${brand.name}`);
|
||||||
|
|
||||||
|
// Resume: zaten keşfedildiyse atla
|
||||||
|
if (!opts.force && fs.existsSync(outFile)) {
|
||||||
|
log(`Atlanıyor (zaten mevcut): ${outFile}`);
|
||||||
|
summaryData.push({ name: brand.name, slug, status: "atlandı (mevcut)" });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// brandMenu.do'ya dön (her marka keşfinden önce)
|
||||||
|
if (i > 0) {
|
||||||
|
try {
|
||||||
|
await page.goto(`${opts.pl24BaseUrl}${opts.brandMenuUrl}`, {
|
||||||
|
waitUntil: "domcontentloaded",
|
||||||
|
timeout: opts.navigationTimeout,
|
||||||
|
});
|
||||||
|
await sleep(2000);
|
||||||
|
} catch (err) {
|
||||||
|
log(`brandMenu.do'ya dönülemedi: ${err.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keşfet
|
||||||
|
const explorer = await exploreBrand(page, brand, opts);
|
||||||
|
const md = explorer.generateMd();
|
||||||
|
|
||||||
|
// Kaydet
|
||||||
|
fs.writeFileSync(outFile, md, "utf-8");
|
||||||
|
log(`Kaydedildi: ${outFile}`);
|
||||||
|
|
||||||
|
summaryData.push({
|
||||||
|
name: brand.name,
|
||||||
|
slug,
|
||||||
|
status: "tamamlandı",
|
||||||
|
requestCount: explorer.requests.length,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Rate limit
|
||||||
|
if (i < brands.length - 1) {
|
||||||
|
log(`Bekleniyor: ${opts.delayBetweenBrands}ms...`);
|
||||||
|
await sleep(opts.delayBetweenBrands);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Özet Dosyası ──────────────────────────────────────────────────────
|
||||||
|
logSection("ÖZET");
|
||||||
|
const summaryLines = summaryData.map((s) =>
|
||||||
|
`| ${s.name} | ${s.slug} | ${s.status} | ${s.requestCount ?? "-"} |`
|
||||||
|
).join("\n");
|
||||||
|
|
||||||
|
const summaryMd = `# PL24 Katalog Keşif Özeti
|
||||||
|
|
||||||
|
## Keşif Tarihi
|
||||||
|
${new Date().toISOString()}
|
||||||
|
|
||||||
|
## Sonuçlar
|
||||||
|
|
||||||
|
| Marka | Slug | Durum | API İstek Sayısı |
|
||||||
|
|-------|------|-------|-----------------|
|
||||||
|
${summaryLines}
|
||||||
|
|
||||||
|
## Notlar
|
||||||
|
- Bu dosya otomatik olarak oluşturulmuştur
|
||||||
|
- Her marka için ayrıntı: \`{slug}.md\`
|
||||||
|
`;
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(opts.outputDir, "_summary.md"), summaryMd, "utf-8");
|
||||||
|
log(`Özet kaydedildi: ${path.join(opts.outputDir, "_summary.md")}`);
|
||||||
|
|
||||||
|
log(`\nKeşif tamamlandı. ${summaryData.length} marka işlendi.`);
|
||||||
|
log(`Çıktı dizini: ${opts.outputDir}`);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((err) => {
|
||||||
|
console.error(`FATAL: ${err.message}`);
|
||||||
|
console.error(err.stack);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
280
scripts/posthog-dashboards.sh
Executable file
@@ -0,0 +1,280 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
API_KEY="${POSTHOG_API_KEY:?Set POSTHOG_API_KEY env var}"
|
||||||
|
BASE="https://eu.posthog.com/api/projects/127747"
|
||||||
|
HEADERS=(-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json")
|
||||||
|
|
||||||
|
create_insight() {
|
||||||
|
local payload="$1"
|
||||||
|
local response
|
||||||
|
response=$(curl -s -X POST "$BASE/insights/" "${HEADERS[@]}" -d "$payload")
|
||||||
|
local id
|
||||||
|
id=$(echo "$response" | jq -r '.id')
|
||||||
|
if [[ "$id" == "null" || -z "$id" ]]; then
|
||||||
|
echo "ERROR creating insight: $response" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$id"
|
||||||
|
}
|
||||||
|
|
||||||
|
add_to_dashboard() {
|
||||||
|
local insight_id="$1"
|
||||||
|
local dashboard_id="$2"
|
||||||
|
curl -s -X PATCH "$BASE/insights/$insight_id/" "${HEADERS[@]}" \
|
||||||
|
-d "{\"dashboards\":[$dashboard_id]}" | jq -r '.id' > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
create_dashboard() {
|
||||||
|
local name="$1"
|
||||||
|
local response
|
||||||
|
response=$(curl -s -X POST "$BASE/dashboards/" "${HEADERS[@]}" \
|
||||||
|
-d "{\"name\":\"$name\"}")
|
||||||
|
local id
|
||||||
|
id=$(echo "$response" | jq -r '.id')
|
||||||
|
if [[ "$id" == "null" || -z "$id" ]]; then
|
||||||
|
echo "ERROR creating dashboard: $response" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$id"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "=== PostHog Dashboard Oluşturucu ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# ─── Insight'lar ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
echo "--- Insight'lar oluşturuluyor ---"
|
||||||
|
|
||||||
|
I1=$(create_insight '{
|
||||||
|
"name": "Günlük Aktif Kullanıcılar",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "TrendsQuery",
|
||||||
|
"series": [{"kind":"EventsNode","event":"$pageview","math":"dau","name":"DAU"}],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"interval": "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [1/11] Günlük Aktif Kullanıcılar → $I1"
|
||||||
|
|
||||||
|
I2=$(create_insight '{
|
||||||
|
"name": "Kayıt Trendi",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "TrendsQuery",
|
||||||
|
"series": [{"kind":"EventsNode","event":"user_signed_up","math":"total","name":"Kayıt"}],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"interval": "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [2/11] Kayıt Trendi → $I2"
|
||||||
|
|
||||||
|
I3=$(create_insight '{
|
||||||
|
"name": "Giriş / Çıkış",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "TrendsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"user_logged_in","math":"total","name":"Giriş"},
|
||||||
|
{"kind":"EventsNode","event":"user_logged_out","math":"total","name":"Çıkış"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"interval": "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [3/11] Giriş / Çıkış → $I3"
|
||||||
|
|
||||||
|
I4=$(create_insight '{
|
||||||
|
"name": "VIN Arama Hacmi",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "TrendsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"vin_decoded","math":"total","name":"Arama"},
|
||||||
|
{"kind":"EventsNode","event":"vin_decode_success","math":"total","name":"Başarılı"},
|
||||||
|
{"kind":"EventsNode","event":"vin_decode_error","math":"total","name":"Hata"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"interval": "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [4/11] VIN Arama Hacmi → $I4"
|
||||||
|
|
||||||
|
I5=$(create_insight '{
|
||||||
|
"name": "Onboarding Funnel",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "FunnelsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"user_signed_up","name":"Kayıt"},
|
||||||
|
{"kind":"EventsNode","event":"trial_started","name":"Trial"},
|
||||||
|
{"kind":"EventsNode","event":"vin_decoded","name":"VIN Arama"},
|
||||||
|
{"kind":"EventsNode","event":"vin_decode_success","name":"Başarılı Sonuç"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"funnelsFilter": {"funnelWindowInterval": 14, "funnelWindowIntervalUnit": "day"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [5/11] Onboarding Funnel → $I5"
|
||||||
|
|
||||||
|
I6=$(create_insight '{
|
||||||
|
"name": "Monetization Funnel",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "FunnelsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"vin_decoded","name":"VIN Arama"},
|
||||||
|
{"kind":"EventsNode","event":"plan_selected","name":"Plan Seçimi"},
|
||||||
|
{"kind":"EventsNode","event":"checkout_started","name":"Checkout"},
|
||||||
|
{"kind":"EventsNode","event":"payment_initiated","name":"Ödeme"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"funnelsFilter": {"funnelWindowInterval": 14, "funnelWindowIntervalUnit": "day"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [6/11] Monetization Funnel → $I6"
|
||||||
|
|
||||||
|
I7=$(create_insight '{
|
||||||
|
"name": "Core Value Funnel",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "FunnelsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"user_logged_in","name":"Giriş"},
|
||||||
|
{"kind":"EventsNode","event":"vin_decoded","name":"VIN Arama"},
|
||||||
|
{"kind":"EventsNode","event":"vin_decode_success","name":"Başarılı Sonuç"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"funnelsFilter": {"funnelWindowInterval": 7, "funnelWindowIntervalUnit": "day"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [7/11] Core Value Funnel → $I7"
|
||||||
|
|
||||||
|
I8=$(create_insight '{
|
||||||
|
"name": "Ödeme Trendi",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "TrendsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"payment_initiated","math":"total","name":"Ödeme Başlatıldı"},
|
||||||
|
{"kind":"EventsNode","event":"receipt_uploaded","math":"total","name":"Dekont Yüklendi"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"interval": "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [8/11] Ödeme Trendi → $I8"
|
||||||
|
|
||||||
|
I9=$(create_insight '{
|
||||||
|
"name": "Trial Başlatma Trendi",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "TrendsQuery",
|
||||||
|
"series": [{"kind":"EventsNode","event":"trial_started","math":"total","name":"Trial"}],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"interval": "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [9/11] Trial Başlatma Trendi → $I9"
|
||||||
|
|
||||||
|
I10=$(create_insight '{
|
||||||
|
"name": "İptal / Devam",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "TrendsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"subscription_cancelled","math":"total","name":"İptal"},
|
||||||
|
{"kind":"EventsNode","event":"subscription_resumed","math":"total","name":"Devam"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"interval": "day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [10/11] İptal / Devam → $I10"
|
||||||
|
|
||||||
|
I11=$(create_insight '{
|
||||||
|
"name": "Ödeme Funnel",
|
||||||
|
"query": {
|
||||||
|
"kind": "InsightVizNode",
|
||||||
|
"source": {
|
||||||
|
"kind": "FunnelsQuery",
|
||||||
|
"series": [
|
||||||
|
{"kind":"EventsNode","event":"plan_selected","name":"Plan Seçimi"},
|
||||||
|
{"kind":"EventsNode","event":"checkout_started","name":"Checkout"},
|
||||||
|
{"kind":"EventsNode","event":"payment_initiated","name":"Ödeme"},
|
||||||
|
{"kind":"EventsNode","event":"receipt_uploaded","name":"Dekont"}
|
||||||
|
],
|
||||||
|
"dateRange": {"date_from": "-30d"},
|
||||||
|
"funnelsFilter": {"funnelWindowInterval": 7, "funnelWindowIntervalUnit": "day"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}')
|
||||||
|
echo " [11/11] Ödeme Funnel → $I11"
|
||||||
|
|
||||||
|
# ─── Dashboard'lar ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--- Dashboard'lar oluşturuluyor ---"
|
||||||
|
|
||||||
|
D1=$(create_dashboard "SASE — Genel Bakış")
|
||||||
|
echo " Dashboard 1: SASE — Genel Bakış → $D1"
|
||||||
|
|
||||||
|
D2=$(create_dashboard "SASE — Funnel'lar")
|
||||||
|
echo " Dashboard 2: SASE — Funnel'lar → $D2"
|
||||||
|
|
||||||
|
D3=$(create_dashboard "SASE — Abonelik")
|
||||||
|
echo " Dashboard 3: SASE — Abonelik → $D3"
|
||||||
|
|
||||||
|
# ─── Insight → Dashboard bağlantıları ────────────────────────────────
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--- Insight'lar dashboard'lara bağlanıyor ---"
|
||||||
|
|
||||||
|
# Dashboard 1: Genel Bakış
|
||||||
|
for id in "$I1" "$I2" "$I3" "$I4"; do
|
||||||
|
add_to_dashboard "$id" "$D1"
|
||||||
|
done
|
||||||
|
echo " Genel Bakış: 4 insight bağlandı"
|
||||||
|
|
||||||
|
# Dashboard 2: Funnel'lar
|
||||||
|
for id in "$I5" "$I6" "$I7" "$I8"; do
|
||||||
|
add_to_dashboard "$id" "$D2"
|
||||||
|
done
|
||||||
|
echo " Funnel'lar: 4 insight bağlandı"
|
||||||
|
|
||||||
|
# Dashboard 3: Abonelik
|
||||||
|
for id in "$I9" "$I10" "$I11"; do
|
||||||
|
add_to_dashboard "$id" "$D3"
|
||||||
|
done
|
||||||
|
echo " Abonelik: 3 insight bağlandı"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Tamamlandı ==="
|
||||||
|
echo ""
|
||||||
|
echo "Dashboard URL'leri:"
|
||||||
|
echo " https://eu.posthog.com/project/127747/dashboard/$D1 (Genel Bakış)"
|
||||||
|
echo " https://eu.posthog.com/project/127747/dashboard/$D2 (Funnel'lar)"
|
||||||
|
echo " https://eu.posthog.com/project/127747/dashboard/$D3 (Abonelik)"
|
||||||
|
echo ""
|
||||||
|
echo "Toplam: 11 insight + 3 dashboard oluşturuldu."
|
||||||
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 584 KiB |
10
skills-lock.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"skills": {
|
||||||
|
"seo-audit": {
|
||||||
|
"source": "coreyhaines31/marketingskills",
|
||||||
|
"sourceType": "github",
|
||||||
|
"computedHash": "6bd4cde58bb701b5dc90a0fae2f0ea3efc7c3e6fd2ae754083fa659930e7d39f"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||