feat: MercadoLibre integration + inventory bulk publish + WhatsApp bridge fixes

- Add MercadoLibre OAuth, listings, orders, webhooks and category search
- New marketplace_external_bp.py, meli_service.py, marketplace_external_service.py
- New marketplace_external.html/js with ML management UI
- Inventory: bulk publish to ML with category autocomplete, listing type and shipping selectors
- Inventory: new .btn--meli styles, select/label CSS fixes
- WhatsApp bridge: rate limiting, 440/515/408 error handling, stale watchdog
- DB migration v3.4_meli_integration.sql for marketplace_listings, orders, sync_queue
- Add Celery tasks for ML sync and webhook processing
- Sidebar: MercadoLibre navigation link
This commit is contained in:
2026-05-26 04:24:07 +00:00
parent 50c0dbe7d4
commit a236187f3a
66 changed files with 7335 additions and 498 deletions

View File

@@ -732,6 +732,20 @@
font-size: var(--text-caption);
}
.btn--meli {
background: #FFE600;
color: #2D3277;
border-color: transparent;
font-weight: 700;
}
.btn--meli:hover {
background: #e6cf00;
color: #1a1f5c;
}
.btn--meli svg {
stroke: currentColor;
}
/* =========================================================================
DATA TABLE
========================================================================= */
@@ -1261,7 +1275,7 @@
.inv-field label {
font-size: var(--text-caption);
font-weight: var(--font-weight-semibold);
color: var(--color-text-muted);
color: var(--color-text-secondary);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
}
@@ -1282,6 +1296,23 @@
box-shadow: 0 0 0 2px var(--color-primary-muted);
}
.inv-field select {
padding: var(--space-2) var(--space-3);
background: var(--color-surface-1);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
width: 100%;
}
.inv-field select:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 2px var(--color-primary-muted);
}
.count-row {
display: flex;
gap: var(--space-2);
@@ -1301,3 +1332,48 @@
/* History table inside modal */
.inv-modal .data-table { width: 100%; }
/* ─── MercadoLibre Category Autocomplete ─────────────────────────────── */
.meli-cat-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 200;
background: var(--color-surface-1);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
max-height: 240px;
overflow-y: auto;
margin-top: 4px;
}
.meli-cat-item {
padding: 10px 14px;
cursor: pointer;
font-size: var(--text-body-sm);
color: var(--color-text-primary);
border-bottom: 1px solid var(--color-border);
transition: background var(--transition-fast);
display: flex;
justify-content: space-between;
align-items: center;
}
.meli-cat-item:last-child { border-bottom: none; }
.meli-cat-item:hover,
.meli-cat-item.is-active {
background: var(--color-surface-2);
}
.meli-cat-item .cat-id {
font-size: var(--text-caption);
color: var(--color-text-muted);
margin-left: 8px;
font-family: var(--font-mono);
}
.meli-cat-loading,
.meli-cat-empty {
padding: 12px 14px;
font-size: var(--text-caption);
color: var(--color-text-muted);
text-align: center;
}

View File

@@ -18,14 +18,22 @@ body {
SIDEBAR — Glass treatment
========================================================================== */
/* Prevent flash/stun while sidebar.js replaces static sidebar markup */
.sidebar,
.pos-sidebar {
opacity: 0;
transition: opacity 0.15s ease;
background: var(--glass-bg-strong) !important;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-right: 1px solid var(--glass-border) !important;
}
body.sidebar-ready .sidebar,
body.sidebar-ready .pos-sidebar {
opacity: 1;
}
.sidebar__logo {
position: relative;
}