# Collector integration (PC auto-update) How the shopfloor PC fleet pushes inventory into shopdb-flask, replacing the classic ASP `api.asp?action=updateCompleteAsset` path. ## Endpoint `POST /api/collector/computers` Auth: API key header `X-API-Key: `, resolved as `COLLECTOR_API_KEY_COMPUTERS` then the shared `COLLECTOR_API_KEY` (ADR-006). Idempotent upsert keyed on `hostname`. > **Breaking change:** the API key must be sent in the `X-API-Key` header. The > old `?api_key=` querystring fallback has been removed, on every collector > endpoint (`/api/collector/`, `/pc`, `/apps`, `/heartbeat`, `/bulk`, > `/status`). Querystring keys leak into access logs and proxy history. Update > any caller still passing `api_key` in the URL to use the header instead. ## Payload (project naming convention: lowercase concatenated) | Field | Meaning | Flask target | |-------|---------|--------------| | `hostname` (required) | identity | `Computer.hostname` | | `machinenumber` | machine number | `Asset.assetnumber` (skips `9999` placeholder, falls back to hostname) | | `pctype` | imaging pc-type | `Computer.computertypeid` via the configurable mapping | | `pcsubtype` | finer class | accepted, not yet stored (warning) | | `serialnumber` | BIOS serial | `Asset.serialnumber` | | `loggedinuser` | current user | `Computer.loggedinuser` | | `lastboottime` | ISO datetime | `Computer.lastboottime` | | `lastcheckin` | ISO datetime | accepted (heartbeat) | | `ipaddress` | primary IP | primary `Communication` | | `vendorname` | manufacturer | `Computer.vendorid` (created if missing) | | `modelnumber` | model | `Computer.modelnumberid` (created if missing) | | `osname` | OS caption | `Computer.osid` (looked up; warned if unknown) | | `installedsoftware` | `[{name, version}]` | `ComputerInstalledApp` (known apps only) | Response: `{status, action: created|updated, assetid, identityvalue, warnings[]}`. ## Source of truth on the PC (current method, may change) The data already exists at image time and at runtime: - **machine number**: registry `HKLM\SOFTWARE\[WOW6432Node\]GE Aircraft Engines\Dnc\General\MachineNo` FIRST (authoritative post Update-MachineNumber; ignore the `9999` placeholder), then `C:\Enrollment\machine-number.txt` as fallback. This is exactly what GE-Enforce.ps1 already does. - **pc-type / pc-subtype**: `C:\Enrollment\pc-type.txt` / `pc-subtype.txt` (the `gea-shopfloor-*` taxonomy). - **serial / vendor / model / os / user / boot**: live WMI on the PC. GE-Enforce currently writes a status JSON to the SFLD share rather than POSTing. Whatever transport is used (a relay reading those status files, or a direct POST later), map its field names to the table above. ## pc-type mapping (configurable) `pctype` (e.g. `gea-shopfloor-cmm`) is mapped to a flask Computer Type through `pctypemap_` settings (Settings > System > "Collector PC Type Mapping"). Defaults live in `plugins/computers/pctypemap.py` and are seeded on plugin install; edit per site in the UI. Unmapped pc-types are recorded as a warning, not an error. ## Classic api.asp field mapping (for migrating the PowerShell scripts) | Classic `updateCompleteAsset` form field | Collector field | |---|---| | `hostname` | `hostname` | | `machineNo` | `machinenumber` | | `pcType` | `pctype` | | `serialNumber` | `serialnumber` | | `loggedInUser` | `loggedinuser` | | `lastBootUpTime` / `lastBootTime` | `lastboottime` | | `manufacturer` | `vendorname` | | `model` | `modelnumber` | | `osVersion` | `osname` | | `installedApps` | `installedsoftware` | Not carried over (no current home): warranty fields, DNC config, multi-NIC detail beyond the primary IP, VNC/WinRM flags.