add Entra device identity to computers and Azure/Thor import sources

PC records now carry Entra/Azure device identity so imported machines keep a durable link back to their directory object instead of matching on hostname alone. Adds azuredeviceid, azureobjectid, and azuredevicecategory to the Computer model with matching migrations, surfaces them read-only in PCDetail as an Entra Device Info card, and lets PCForm edit the device id directly. The computers plugin registers a machineassetnumber import hook that reconciles PC-to-machine links during bulk import and warns on unresolved or conflicting relationships.

Adds importsources adapters that normalize Azure device-group and Thor PC inventory exports into canonical ShopDB CSVs via hostname alignment, exposes register_import_hook and RowWarning on the shopdb.api contract surface (contract 0.21.0), and refreshes the Import Site Assets page with clearer source instructions. Includes reconcile_locations maintenance script and coverage for the new import paths.
This commit is contained in:
benjamin.baker
2026-08-25 16:46:00 -04:00
parent f4d8868463
commit bdef21da50
21 changed files with 2064 additions and 86 deletions

View File

@@ -1027,14 +1027,26 @@ export const settingsApi = {
// Generated CSV template (header + example row) for one table
return api.get(`/settings/asset-import/templates/${encodeURIComponent(tablename)}`, { responseType: 'blob' })
},
importAssetCsvs(files, commit = false) {
importAssetCsvs(files, commit = false, options = {}) {
// Multipart upload of one or more CSVs. commit=false is a dry-run preview
// that writes nothing; commit=true applies the whole set in one transaction.
// options.source picks a foreign adapter (azure, thor); default native means
// the files are already canonical per-table CSVs. options.computertype is
// stamped onto every imported computer when a source assigns a PC type.
const form = new FormData()
for (const file of files) {
form.append('files', file)
}
form.append('commit', commit ? 'true' : 'false')
if (options.source) {
form.append('source', options.source)
}
if (options.computertype) {
form.append('computertype', options.computertype)
}
if (options.category) {
form.append('category', options.category)
}
return api.post('/settings/asset-import/import', form, {
headers: { 'Content-Type': 'multipart/form-data' }
})