DIS Integration Plan for CROP Admin Panel
Date: 2026-01-06 Status: Draft for Review
DIS Integration Plan for CROP Admin Panel
Date: 2026-01-06 Status: Draft for Review
Data Architecture Analysis
Current State
| Source | Purpose | Data |
|---|---|---|
| MongoDB (crop_prod) | Catalog/Content | title, description, specs, images, vendor price, scraped stock |
| MongoDB (crop_stage) | Photo Pipeline | partNumber, images, pipelineStatus, discovery |
| DIS Quantum | Dealer Inventory | real-time stock, dealer pricing, availability |
Key Insight
MongoDB stores CATALOG data (what the part is), DIS stores INVENTORY data (what dealer has).
MongoDB parts_nhl:
- price: {value: 111.60, currency: "USD"} <- Vendor suggested price
- stock: 5 <- Scraped/stale data
- availability: "In Stock" <- From vendor website
DIS partsInquiry:
- Price: 89.99 <- Dealer actual price
- QtyOnHand: 12 <- Real inventory count
- Available: true <- Real-time statusBusiness Value of DIS Integration
- Price Comparison: Vendor price (MongoDB) vs Dealer price (DIS)
- Stock Accuracy: Scraped availability vs Real dealer inventory
- Margin Analysis: (Vendor price - Dealer cost) / Vendor price
Recommended Integration Architecture
Option A: Real-time Overlay (Recommended)
┌─────────────────┐ ┌─────────────────┐
│ MongoDB │ │ DIS API │
│ (Catalog) │ │ (Inventory) │
└────────┬────────┘ └────────┬────────┘
│ │
└───────────┬───────────┘
│
┌──────┴──────┐
│ Admin API │
│ (Merge) │
└──────┬──────┘
│
┌──────┴──────┐
│ Frontend │
└─────────────┘How it works:
- Load part from MongoDB (catalog data)
- On-demand query DIS for inventory (with 5-min cache)
- Merge and display both datasets
- No sync needed - always fresh
Option B: Scheduled Sync (Alternative)
Cron (every 4h) → Batch DIS query → Update MongoDB → Admin displays merged dataTradeoff: Less real-time, but faster page loads
Implementation Plan
Phase 1: DIS API Client (Day 1-2)
File: crop-front-admin/lib/api/dis-service.ts
// Server-only DIS API client
interface DISInventoryResult {
partNumber: string;
manufacturerCode: string;
price: number;
available: boolean;
qtyOnHand: number;
checkedAt: Date;
}
class DISService {
private cache: Map<string, {data: DISInventoryResult, expires: Date}>;
async getInventory(vendorCode: string, partNumber: string): Promise<DISInventoryResult | null>;
async getInventoryBatch(parts: {vendorCode: string, partNumber: string}[]): Promise<DISInventoryResult[]>;
}Vendor Code Mapping:
| CROP Code | DIS Code | Verified |
|---|---|---|
| KUH | KUH | Yes |
| NHL | NHL | Yes |
| KIN | KIN | Yes |
| MCH | MCH | Yes |
| HAR | HAR | No (not found) |
Phase 2: Dashboard Widget (Day 3)
Location: /dashboard - New DISStatusWidget component
┌─────────────────────────────────────┐
│ Dealer Inventory (DIS) │
├─────────────────────────────────────┤
│ Connection: cl2342.disprism.com │
│ Status: ● Connected │
│ │
│ Sample Check (100 parts): │
│ ├─ In Stock: 72 (72%) │
│ ├─ Out of Stock: 23 (23%) │
│ └─ Not in DIS: 5 (5%) │
│ │
│ Price Variances: │
│ ├─ DIS Lower: 45 parts │
│ ├─ DIS Higher: 12 parts │
│ └─ Match (±5%): 43 parts │
│ │
│ [Refresh] [View Details →] │
└─────────────────────────────────────┘Phase 3: Parts Table Enhancement (Day 4-5)
Location: /dashboard/parts - Add columns to DataTable
| Column | Source | Display |
|---|---|---|
| DIS Stock | API | Badge: "In Stock (12)" / "Out of Stock" / "N/A" |
| DIS Price | API | $89.99 (with diff indicator if ≠ catalog price) |
| Margin | Calculated | 19.3% (if DIS price < catalog price) |
Implementation:
- Add "Check DIS" button to refresh single part
- Lazy-load DIS data when scrolling into view
- Cache results for 5 minutes
- Show loading spinner while fetching
Phase 4: Comparison Analytics (Day 6-7)
Location: /dashboard/dis - New dedicated page
Sections:
-
Overview Cards
- Total parts checked
- In stock %
- Average price variance
- Last full sync time
-
Price Comparison Chart
- X-axis: Part categories
- Y-axis: Avg price difference (DIS vs Catalog)
- Highlight significant variances
-
Inventory Discrepancy Table
- Parts where MongoDB says "In Stock" but DIS says "Out"
- Parts where DIS has stock but MongoDB says "Out"
- Sortable, filterable, exportable
-
Vendor Breakdown
- Per-vendor statistics
- DIS coverage by vendor
API Routes to Create
/api/dis/status GET - Connection status + sample check
/api/dis/inventory POST - Batch inventory lookup
/api/dis/part/[slug] GET - Single part DIS data
/api/dis/comparison GET - Full comparison report
/api/dis/sync POST - Trigger manual sync (admin only)Environment Variables
# DIS API Configuration
DIS_API_URL=https://cl2342.disprism.com
DIS_API_KEY=<stored-securely>
DIS_DEALER_ID=C
DIS_CACHE_TTL_SECONDS=300Critical Considerations
DO
- Cache DIS responses (5-min TTL)
- Map vendor codes explicitly
- Show "Last checked" timestamps
- Handle "not found" gracefully
- Log all DIS API calls for debugging
DON'T
- Don't call DIS on every page load
- Don't assume all parts exist in DIS
- Don't use pushOrder in production yet (tax bug)
- Don't expose API key in client code
Known DIS Issues (From Testing)
| Issue | Status | Workaround |
|---|---|---|
| Oregon tax returns $238 (should be $0) | Open | Don't use taxLookup for no-tax states |
| TaxExemptions causes HTTP 500 | Open | Don't include TaxExemptions |
| Parts not found silently omitted | By Design | Check response length vs request |
| DBSCustId ignored (always CASHC) | Open | Cannot link to customers yet |
Success Metrics
| Metric | Target |
|---|---|
| DIS coverage | >80% of catalog parts found in DIS |
| Price accuracy | <5% variance on 90% of parts |
| Page load time | <2s with DIS data |
| Cache hit rate | >70% |
Timeline
| Phase | Days | Deliverable |
|---|---|---|
| 1. API Client | 2 | dis-service.ts with caching |
| 2. Dashboard Widget | 1 | Status widget on main dashboard |
| 3. Parts Table | 2 | DIS columns in parts DataTable |
| 4. Analytics Page | 2 | /dashboard/dis with full comparison |
| Total | 7 | Complete DIS integration |
Questions for Team
- Should DIS price override MongoDB price for customer display?
- How often should we sync inventory for customer-facing site?
- Do we need historical price tracking from DIS?
- Which vendors are definitely in DIS vs not?
Next Steps
- Review and approve this plan
- Store DIS API key in environment variables
- Create
dis-service.tsclient - Implement dashboard widget
- Iterate based on feedback
DIS Parts Store API - Test Report
Date: 2026-01-06 Environment: cl2342.disprism.com (Production) API Key: REDACTED - stored in environment variables
Form builder and submission handling component library for CROP applications
Form builder and submission handling component library for CROP applications.