Warranty phase 2: real Dell provider + settings UI + PC hero badge

- DellProvider: real Dell TechDirect lookup. OAuth2 via HTTP Basic auth,
  asset-entitlements under /PROD/sbil/eapi/v5 (the device.warranty path 404s
  for this account), map latest dated entitlement to service level + dates.
  Cache the token process-wide; Dell rate-limits the token endpoint and a
  fresh request per refresh trips a 401 cooldown. Verified against live Dell.
- Lenovo/HP stay config-shaped stubs.
- Settings: warranty_dell_* keys (category integrations); Dell Warranty Lookup
  block in System Settings > Integrations (enable + client id/secret masked +
  optional token/API URL overrides).
- WarrantyPanel takes optional pre-fetched items; PCDetail fetches once and
  feeds both the panel and a new hero warranty-status/end-date badge.
- tools/mock_dell.py for offline testing of the provider flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-09 16:05:26 -04:00
parent 78a0ee8d83
commit 7e9650a62b
8 changed files with 370 additions and 30 deletions

View File

@@ -33,6 +33,9 @@ const props = defineProps({
assetid: { type: [Number, String], default: null },
// When true, render the card even with no warranties (shows an "Add one" link).
showEmpty: { type: Boolean, default: false },
// Optional pre-fetched warranties. When provided, the panel uses them instead
// of fetching (lets a parent share one fetch with e.g. a hero badge).
items: { type: Array, default: null },
})
const warranties = ref([])
@@ -47,6 +50,8 @@ function formatDate(d) {
}
async function load() {
// Parent-supplied data wins - skip the fetch.
if (props.items !== null) { warranties.value = props.items; return }
if (!props.assetid) { warranties.value = []; return }
try {
const response = await warrantyApi.forAsset(props.assetid)
@@ -59,6 +64,7 @@ async function load() {
onMounted(load)
watch(() => props.assetid, load)
watch(() => props.items, load)
</script>
<style scoped>