Set the requirements
Chose the features and shaped the application around IT asset management workflows.
PROJECT / 02 · AI-ASSISTED DEVELOPMENT
A self-hosted IT asset management application that brings device inventory, software information and security posture into one dashboard.
Understanding an IT estate means knowing which devices are present, what software they run, when they last reported and which systems need attention. Asset Register brings that information together to support day-to-day inventory review and troubleshooting.
A 22-second visual tour of the fleet overview and device inventory.
I decided the features, guided AI-assisted development, tested workflows, troubleshot issues and deployed the application. AI tools generated the application code; my contribution centred on requirements, directing iterations and assessing how the result worked in practice.
Chose the features and shaped the application around IT asset management workflows.
Directed AI-generated implementation and worked through issues as the application developed.
Tested workflows, troubleshot problems and deployed the resulting application.
Hardware · software · network · security posture
Inventory ingestion · history · API
Fleet visibility · search · reporting
Nginx provides the reverse-proxy deployment layer. The application supports SQLite and a configurable PostgreSQL connection.
Selected examples from the local application source, showing how inventory is collected, processed and displayed. The application code was generated with AI assistance; I defined requirements, guided iterations, tested workflows, troubleshot issues and deployed it.
Collects interface names, MAC addresses and non-loopback IPv4 addresses for the inventory payload. The code is shown as a complete function; its psutil dependency is imported elsewhere.
Source: agent/agent_core.py
def collect_network_interfaces():
items = []
for iface, addrs in psutil.net_if_addrs().items():
mac = None
ips = []
for a in addrs:
if getattr(a.family, "name", "") in ("AF_LINK", "AF_PACKET"):
mac = a.address
if getattr(a.family, "name", "") == "AF_INET" and not a.address.startswith("127."):
ips.append(a.address)
if mac or ips:
items.append({"name": iface, "mac": mac, "ips": ips})
return itemsExcerpt from the inventory endpoint after device authentication and identity checks. Merges the incoming report with the previous payload and retains software or network inventory when that section was not successfully collected.
Source: server/app/api/agents.py
previous = latest_payloads(db, [device.device_id]).get(device.device_id, {})
incoming = body.model_dump(mode="json", exclude_unset=True, exclude_none=True)
payload = dict(previous)
payload.update(incoming)
preserved = []
for section in ("software", "network"):
if not body.section_succeeded(section):
preserved.append(section)
if section in previous:
payload[section] = previous[section]
else:
payload.pop(section, None)Excerpt from list_devices. Applies the search term across hostname, device ID, serial number, model, operating system, IP and manufacturer fields. The surrounding function provides the database query and pagination.
Source: server/app/api/devices.py
if query:
like = f"%{query}%"
q = q.filter(or_(
models.Device.hostname.like(like),
models.Device.device_id.like(like),
models.Device.serial_number.like(like),
models.Device.model.like(like),
models.Device.os_family.ilike(like), models.Device.os_version.ilike(like),
models.Device.last_ip.ilike(like), models.Device.manufacturer.ilike(like),
))Maps time since the last report to Unknown, Online, Warning or Stale labels. This indicates reporting recency rather than a live connectivity test; minutesSince is defined elsewhere in the same file.
Source: web/src/pages/DevicesPage.jsx
function getStatus(lastSeenAt) {
const mins = minutesSince(lastSeenAt);
if (mins === null) return { label: "Unknown", severity: "default" };
if (mins <= 60) return { label: "Online", severity: "success" };
if (mins <= 24 * 60) return { label: "Warning", severity: "warning" };
return { label: "Stale", severity: "error" };
}These examples document the implementation. They are excerpts for explanation, not standalone programs.
Overview charts, device status, disk usage and health indicators. Searchable device listings and device details covering hardware, network, security, users, software and history.
Fleet-wide software and user search, device notes and tags, CSV/JSON export, duplicate-hostname detection and an administrator-controlled merge workflow.
Patch reporting, software licence seat limits and vulnerability rules that match configured application names and versions against inventory. These are operational indicators and rule-based matches.
Python collectors for Windows and Linux, agent configuration controls, inventory snapshots and administrator/read-only dashboard roles.
I tested application workflows and troubleshot issues during development before deploying it. The repository also contains automated backend tests and deployment tooling for a self-hosted Ubuntu environment using Nginx and systemd, with release, migration and rollback procedures.
The feature descriptions above were checked against the local source code. This case study does not claim an independent security audit or production reliability assessment. The video uses simulated demo inventory; specific workflow test examples remain to be documented.
This project demonstrates how I translate an IT operations need into requirements, use AI tools to develop a working application, and take responsibility for testing, troubleshooting and deployment. It complements my network lab with practical inventory and endpoint visibility workflows.
Interested in the project or my infrastructure experience?