docs: add domain research (stack, features, architecture, pitfalls, summary)
This commit is contained in:
@@ -0,0 +1,139 @@
|
|||||||
|
# Project Research Summary
|
||||||
|
|
||||||
|
**Project:** ImpTune
|
||||||
|
**Domain:** IT admin tooling — printer deployment package generator
|
||||||
|
**Researched:** 2026-04-10
|
||||||
|
**Confidence:** HIGH (with targeted MEDIUM on .intunewin format compliance)
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
ImpTune is a self-hosted, single-container web application that automates the creation of printer deployment packages for IT admins and MSPs. The core workflow is: upload a printer driver ZIP, configure printer parameters (name, IP, print settings), and export either a `.intunewin` package (Intune Win32 app) or a plain ZIP (NinjaRMM script-based deployment).
|
||||||
|
|
||||||
|
The recommended stack is Python 3.12 + FastAPI 0.115.x + Jinja2 + HTMX + SQLite — no Node.js build pipeline, no SPA framework, no external database. The entire application ships as a single `python:3.12-slim-bookworm` container with a named volume for driver files and the SQLite database.
|
||||||
|
|
||||||
|
The most important architectural decision is `.intunewin` generation. `IntuneWinAppUtil.exe` is a Windows PE binary that cannot run in a Linux container. The format is fully documented through reverse engineering (svrooij.io, SvRooij.ContentPrep NuGet library) and must be reimplemented in Python using `zipfile`, `pycryptodome` (AES-256-CBC + HMAC-SHA256), and `xml.etree.ElementTree`. The top risks are concentrated in generated PowerShell scripts and driver management — scripts must handle Intune's 32-bit WOW64 execution context, correctly distinguish SYSTEM from elevated-admin identity, and use the mandatory two-step `pnputil` + `Add-PrinterDriver` sequence.
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
### Recommended Stack
|
||||||
|
|
||||||
|
Python 3.12 + FastAPI for the backend, Jinja2 + HTMX for server-rendered UI with no build step, SQLite for lightweight persistence, and pycryptodome for .intunewin encryption. Single Docker container on `python:3.12-slim-bookworm` (never Alpine — breaks C-extension wheels).
|
||||||
|
|
||||||
|
**Core technologies:**
|
||||||
|
- **FastAPI 0.115.x + Uvicorn 0.30.x**: HTTP framework + file upload handling + StreamingResponse — async-capable, minimal boilerplate
|
||||||
|
- **Jinja2 3.1.x + HTMX 2.0.x + Alpine.js 3.x**: Server-side rendering, zero build step, ideal for internal CRUD tools
|
||||||
|
- **SQLite (stdlib) + peewee 3.17.x**: Zero-config single-writer persistence, no external DB needed
|
||||||
|
- **pycryptodome 3.20.x**: AES-256-CBC + HMAC-SHA256 for `.intunewin` encryption layer
|
||||||
|
- **Tailwind CSS v4 CDN**: Styling without a Node.js dependency
|
||||||
|
|
||||||
|
### Expected Features
|
||||||
|
|
||||||
|
**Must have (table stakes):**
|
||||||
|
- Driver ZIP upload with INF parsing and `DriverDesc` dropdown (not free-text input)
|
||||||
|
- Printer config form: name, IP, port name, duplex, color/BW, paper size, default tray
|
||||||
|
- PowerShell install + uninstall + detection script generation
|
||||||
|
- SYSTEM detection, 64-bit WOW64 guard, pnputil two-step, idempotency in generated scripts
|
||||||
|
- `.intunewin` export (Python-native AES-256 encrypted ZIP-in-ZIP with detection.xml)
|
||||||
|
- NinjaRMM ZIP export (script + driver folder)
|
||||||
|
- Client/tenant label per printer
|
||||||
|
|
||||||
|
**Should have (v1.x):**
|
||||||
|
- Custom icon upload for Intune app display
|
||||||
|
- Driver file optimization hints
|
||||||
|
- One-click package regeneration
|
||||||
|
- Intune command preview panel
|
||||||
|
|
||||||
|
**Defer (v2+):**
|
||||||
|
- Direct Intune/NinjaRMM API push (requires OAuth, multi-tenant app registration)
|
||||||
|
- Real-time chat/notifications
|
||||||
|
- Mobile app
|
||||||
|
|
||||||
|
### Architecture Approach
|
||||||
|
|
||||||
|
Layered single-process: thin API handlers → service classes → generator modules. Package generation is synchronous on the request thread (under 10s for typical driver bundles). Content-addressed driver storage (SHA256 keys) on a Docker volume. PS scripts always from Jinja2 templates, never string concatenation.
|
||||||
|
|
||||||
|
**Major components:**
|
||||||
|
1. **API Layer** (FastAPI routes) — HTTP endpoints for uploads, config CRUD, package export
|
||||||
|
2. **Service Layer** (domain logic) — INF parsing, printer config validation, client organization
|
||||||
|
3. **Generator Layer** (format-specific builders) — PS script templating, ZIP builder, .intunewin builder
|
||||||
|
4. **Storage Layer** (SQLite + volume) — driver file persistence, printer/client metadata
|
||||||
|
|
||||||
|
### Critical Pitfalls
|
||||||
|
|
||||||
|
1. **IntuneWinAppUtil.exe cannot run in Linux Docker** — reimplement .intunewin format natively in Python; validate against real Intune upload early
|
||||||
|
2. **pnputil two-step is mandatory** — `Add-PrinterDriver` fails 100% on clean endpoints without `pnputil /add-driver` staging first; embed in script template unconditionally
|
||||||
|
3. **Intune launches scripts in 32-bit PowerShell** — WOW64 silently redirects System32/registry; every script needs `PROCESSOR_ARCHITEW6432` relaunch guard
|
||||||
|
4. **SYSTEM vs elevated-admin confusion** — `IsInRole(Administrator)` returns true for both; check `WindowsIdentity.Name -eq "NT AUTHORITY\SYSTEM"` explicitly
|
||||||
|
5. **Driver name mismatch** — parse `DriverDesc` from INF at upload time, never trust user text; free-text driver names cause near-100% failure on clean endpoints
|
||||||
|
|
||||||
|
## Implications for Roadmap
|
||||||
|
|
||||||
|
### Phase 1: Foundation & .intunewin Validation
|
||||||
|
**Rationale:** The .intunewin Python reimplementation is the highest-risk technical decision — validate it first before building everything on top
|
||||||
|
**Delivers:** Docker scaffold, SQLite schema, data models, .intunewin format spike tested against real Intune
|
||||||
|
**Avoids:** Building export features on an unvalidated format assumption
|
||||||
|
|
||||||
|
### Phase 2: Driver Management
|
||||||
|
**Rationale:** Everything downstream depends on having drivers uploaded and INF-parsed correctly
|
||||||
|
**Delivers:** Upload, INF parsing (DriverDesc extraction), SHA256-keyed volume storage, unsigned driver warning
|
||||||
|
**Avoids:** Free-text driver name pitfall by enforcing INF-derived names from day one
|
||||||
|
|
||||||
|
### Phase 3: Printer Config & Script Generation
|
||||||
|
**Rationale:** Core deliverable — the PS install script with all correctness requirements baked in
|
||||||
|
**Delivers:** Printer CRUD form, Jinja2 PS template with 64-bit guard, SYSTEM detection, pnputil two-step, idempotency, injection prevention
|
||||||
|
**Avoids:** WOW64/SYSTEM/elevation pitfalls by building them into the template from the start
|
||||||
|
|
||||||
|
### Phase 4: Package Export (NinjaRMM + Intune)
|
||||||
|
**Rationale:** NinjaRMM ZIP is simpler — validates script orchestration before tackling .intunewin complexity
|
||||||
|
**Delivers:** NinjaRMM ZIP builder, then Intune .intunewin builder reusing Phase 1 validation; StreamingResponse download with cleanup
|
||||||
|
**Uses:** zipfile (stdlib), pycryptodome, Phase 1 .intunewin builder
|
||||||
|
|
||||||
|
### Phase 5: Web UI & Client Organization
|
||||||
|
**Rationale:** Build UI over validated API routes — all backend functionality is testable before UI work begins
|
||||||
|
**Delivers:** HTMX + Jinja2 UI, driver library browser, client/tenant organization, Intune command preview
|
||||||
|
**Implements:** Full HTMX interactive UI layer over existing FastAPI endpoints
|
||||||
|
|
||||||
|
### Phase 6: Polish & v1.x Enhancements
|
||||||
|
**Rationale:** Defer until real MSP usage validates demand
|
||||||
|
**Delivers:** Icon upload, driver size hints, one-click regeneration, UX refinements
|
||||||
|
|
||||||
|
### Phase Ordering Rationale
|
||||||
|
|
||||||
|
- .intunewin validation first because it's the riskiest unknown — if the format can't be reimplemented, the Intune export strategy changes entirely
|
||||||
|
- Driver management before printer config because the printer form's driver dropdown depends on parsed INF data
|
||||||
|
- Script generation before export because both export formats wrap the same generated script
|
||||||
|
- NinjaRMM export before Intune because it's simpler and validates the packaging pipeline
|
||||||
|
- UI last because all API routes should be stable and testable before wiring up the frontend
|
||||||
|
|
||||||
|
### Research Flags
|
||||||
|
|
||||||
|
Phases likely needing deeper research during planning:
|
||||||
|
- **Phase 1:** .intunewin format — MEDIUM confidence; must spike against real Intune upload
|
||||||
|
- **Phase 3:** PS script correctness — WOW64/SYSTEM/pnputil interaction effects require testing against a real Intune-managed device
|
||||||
|
|
||||||
|
Phases with standard patterns (skip research-phase):
|
||||||
|
- **Phase 2:** Driver upload + INF parsing — standard file upload + regex text parsing
|
||||||
|
- **Phase 4:** ZIP builder — Python `zipfile` stdlib, well-documented
|
||||||
|
- **Phase 5:** HTMX + FastAPI UI — well-documented pattern
|
||||||
|
|
||||||
|
## Confidence Assessment
|
||||||
|
|
||||||
|
| Area | Confidence | Notes |
|
||||||
|
|------|------------|-------|
|
||||||
|
| Stack | HIGH | Verified against official docs + 2025-2026 community consensus; no version conflicts |
|
||||||
|
| Features | HIGH | Verified against Microsoft Intune docs, MSP community guides, reference implementations |
|
||||||
|
| Architecture | HIGH | Layered single-container pattern well-established; IntuneWin builder internals MEDIUM |
|
||||||
|
| Pitfalls | HIGH | All critical pitfalls confirmed via official Microsoft docs + high-reputation community sources |
|
||||||
|
|
||||||
|
**Overall confidence:** HIGH
|
||||||
|
|
||||||
|
### Gaps to Address
|
||||||
|
|
||||||
|
- **.intunewin byte-level format compliance**: Validate Python-generated packages against a real Intune tenant in Phase 1 spike
|
||||||
|
- **Multi-model INF parsing**: HP/Ricoh drivers may have multiple `DriverDesc` entries per INF — validate in Phase 2
|
||||||
|
- **pnputil + $PSScriptRoot under SYSTEM context**: Validate path resolution behavior in Phase 3 testing
|
||||||
|
- **ARM64 driver variants**: Determine if ImpTune needs to handle ARM64 for Surface/Copilot+ devices
|
||||||
|
|
||||||
|
---
|
||||||
|
*Research completed: 2026-04-10*
|
||||||
|
*Ready for roadmap: yes*
|
||||||
Reference in New Issue
Block a user