Commit Graph
167 Commits
Author SHA1 Message Date
kawa 2723cc8974 test(06-01): add failing test for icon inclusion in .intunewin export
- test_intunewin_includes_icon: uploads PNG icon, asserts icon.png in staged files
- test_intunewin_without_icon_succeeds: baseline no-icon export passes (already green)
2026-04-10 16:21:04 +02:00
kawaandClaude Opus 4.6 9f3d35b72f docs(06): create phase plan for wiring icon into intunewin export
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:41:05 +02:00
kawa 9912378563 docs(06): add research and validation strategy 2026-04-10 15:39:22 +02:00
kawaandClaude Sonnet 4.6 ba106eecbe docs(06): research phase — wire icon into .intunewin export
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 15:38:22 +02:00
kawaandClaude Opus 4.6 a6d8e15210 docs(roadmap): add gap closure phases 6-7
Phase 6 wires icon into .intunewin export (closes PKG-04).
Phase 7 fixes dashboard empty state and /packages 404 nav link.
PKG-04 reset to Pending in REQUIREMENTS.md traceability table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:32:52 +02:00
kawaandClaude Opus 4.6 624b3f0090 docs(phase-05): complete phase execution and verification
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:11:11 +02:00
kawa fba03b5241 docs(05-02): complete icon upload and export UI plan
- Create 05-02-SUMMARY.md with full execution details
- Update STATE.md progress to 100%, add 4 key decisions, record metrics
- Update ROADMAP.md phase 5 status to Complete
- Mark requirements PKG-04 and PKG-05 complete
2026-04-10 15:08:02 +02:00
kawa f96ea6fec9 feat(05-02): printer detail page with export buttons and command preview
- Update printer_detail() to pass install_cmd, uninstall_cmd, has_driver, has_icon to template
- Rewrite printer_detail.html with Intune Commands, Export, and Icon sections
- Show command strings with Alpine.js copy-to-clipboard buttons (install-cmd, uninstall-cmd)
- Show NinjaRMM ZIP and .intunewin download links when driver assigned
- Add HTMX icon upload form with #icon-status swap target
- Remove disabled placeholder Regenerate Package button
- Add TestCommandPreview class (4 tests) to test_packages.py
- All 94 tests pass
2026-04-10 15:06:45 +02:00
kawa f9e13ba96f feat(05-02): icon upload endpoint with validation
- Create imptune/api/icons.py with POST /printers/{printer_id}/icon
- Validate PNG format, 256x256 dimensions, 750KB max size
- Store icons SHA256-addressed under cfg.DATA_DIR/icons/
- Replace existing Icon record on re-upload
- Register icons.router in main.py with ICONS_DIR makedirs
- Patch cfg.ICONS_DIR in conftest.py for tests
- All 6 icon upload tests pass
2026-04-10 15:05:36 +02:00
kawa dd6cedfed9 feat(05-01): implement NinjaRMM ZIP and intunewin package export endpoints
- GET /printers/{id}/packages/ninja: in-memory ZIP with install.ps1 + driver files in named subfolder
- GET /printers/{id}/packages/intunewin: temp dir build of .intunewin via build_intunewin()
- _get_printer_and_driver() helper validates printer, driver, inf, desc
- Driver ZIP file existence check before processing (RESEARCH pitfall 3)
- TemporaryDirectory context manager for auto-cleanup (RESEARCH pitfall 1)
- Router registered in main.py after scripts router
- All 9 package tests pass, 84 total tests green
2026-04-10 15:05:29 +02:00
kawa d8ce223b38 test(05-02): add failing tests for icon upload endpoint
- Add test_icon_upload.py with 6 TDD RED tests for PKG-04
- Add Pillow>=10.0 to requirements.txt
- Add ICONS_DIR to imptune/config.py
2026-04-10 15:04:38 +02:00
kawa a31c71e11f test(05-01): add failing tests for NinjaRMM ZIP and intunewin package export endpoints
- TestNinjaDownload: 5 tests covering ZIP response, install.ps1, driver files, 404, 422
- TestIntunewinDownload: 4 tests covering .intunewin response, structure, 404, 422
- Fixtures: driver_zip_bytes, setup_printer_with_driver, printer_no_driver
2026-04-10 15:04:11 +02:00
kawaandClaude Opus 4.6 f2d12e53d9 docs(05): create phase 5 package export plans
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:53:31 +02:00
kawaandClaude Opus 4.6 cf7adecb06 docs(phase-5): add research and validation strategy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:48:18 +02:00
kawaandClaude Sonnet 4.6 ec6c150585 docs(phase-05): research package export domain
Cover .intunewin assembly (wiring Phase 1 spike), NinjaRMM ZIP builder,
icon upload/validation, and Alpine.js clipboard preview patterns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 13:47:12 +02:00
kawaandClaude Opus 4.6 55dc7f5e09 docs(phase-04): complete phase execution and verification
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:40:54 +02:00
kawa ed0f0a0607 docs(04-02): complete uninstall+detect templates and script API endpoints plan
- 04-02-SUMMARY.md: TDD execution, 3 commits, 6 files, 75 tests green
- STATE.md: advanced to 04-02 complete, added 3 new decisions
- ROADMAP.md: phase 4 marked complete (2/2 plans done)
- REQUIREMENTS.md: SCRPT-02 and SCRPT-03 marked complete
2026-04-10 13:37:53 +02:00
kawa b7b0d1b4a5 feat(04-02): add script download API endpoints and router registration
- imptune/api/scripts.py: GET /printers/{id}/scripts/{install,uninstall,detect}
- 404 for missing printer, 422 for missing driver/INF/driver_desc
- Content-Disposition attachment header on all responses
- imptune/main.py: register scripts.router
- 5 integration tests covering all endpoint cases (200/404/422)
2026-04-10 13:36:07 +02:00
kawa 6bff8f3c0c feat(04-02): add render_uninstall and render_detect with Jinja2 templates
- render_uninstall(printer_name, driver_name, port_name): Remove-Printer/Driver/Port in safe order
- render_detect(printer_name): Get-Printer check with Write-Output + exit 0/1 Intune contract
- uninstall.ps1.j2: all Remove-* with -ErrorAction SilentlyContinue
- detect.ps1.j2: Intune detection contract template
2026-04-10 13:35:05 +02:00
kawa 0f213df92c test(04-02): add failing tests for render_uninstall and render_detect
- test_render_uninstall: asserts Remove-Printer/Driver/Port order + SilentlyContinue x3
- test_render_detect: asserts Get-Printer, Write-Output, exit 0, exit 1
2026-04-10 13:34:22 +02:00
kawa 8cb420107f docs(04-01): complete script generator install plan summary
- SUMMARY.md for phase 04 plan 01 (TDD install script generator)
- STATE.md: progress updated to 89%, decisions recorded, session updated
- ROADMAP.md: phase 4 plan progress updated (1/2 summaries)
- REQUIREMENTS.md: SCRPT-01, SCRPT-04, SCRPT-05 marked complete
2026-04-10 13:33:08 +02:00
kawa 8193e9dbbd feat(04-01): implement script_generator with install.ps1.j2 template
- Jinja2 Environment with FileSystemLoader, trim_blocks, lstrip_blocks
- render_install() with _duplex_map (LongEdge->TwoSidedLongEdge, ShortEdge->TwoSidedShortEdge)
- install.ps1.j2: WOW64 guard as first block (SCRPT-05)
- install.ps1.j2: SYSTEM/admin detection + UAC self-elevation (SCRPT-04)
- install.ps1.j2: pnputil two-step driver staging + Add-PrinterDriver (SCRPT-01)
- install.ps1.j2: idempotent port creation (Get-PrinterPort check)
- install.ps1.j2: idempotent printer creation (Get-Printer check)
- install.ps1.j2: Set-PrintConfiguration with duplex/color/paper/collate
- All 7 unit tests pass
2026-04-10 13:31:51 +02:00
kawa b4f2c64161 test(04-01): add failing tests for script_generator RED phase
- test_render_install_returns_string: basic smoke test
- test_render_install_contains_pnputil: SCRPT-01 pnputil + Add-PrinterDriver
- test_render_install_print_config: SCRPT-01 duplex mode translation
- test_render_install_wow64_guard: SCRPT-05 WOW64 relaunch guard
- test_render_install_uac_guard: SCRPT-04 SYSTEM vs user + UAC elevation
- test_render_install_idempotency: SCRPT-01 idempotency checks
- test_render_install_booleans: SCRPT-01 boolean rendering
2026-04-10 13:31:00 +02:00
kawaandClaude Opus 4.6 c7361bef18 docs(04): create phase plan for script generation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:27:14 +02:00
kawaandClaude Opus 4.6 a57ecb94d4 docs(phase-04): add research and validation strategy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:22:20 +02:00
kawaandClaude Sonnet 4.6 20b95af524 docs(04): research phase 4 script generation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 13:21:03 +02:00
kawaandClaude Opus 4.6 f80f790360 docs(phase-03): complete phase execution and verification
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:14:54 +02:00
kawa 7c0ae66d39 docs(03-02): complete printer detail page plan summary
- 03-02-SUMMARY.md: printer detail page with driver info and regenerate placeholder
- STATE.md: advance position, record metrics and decisions
- ROADMAP.md: phase 03 marked complete (2/2 plans done)
- REQUIREMENTS.md: PRNT-10 marked complete
2026-04-10 13:05:55 +02:00
kawa cad664c0f6 feat(03-02): implement printer detail page with driver info and regenerate placeholder
- Add GET /printers/{printer_id} route to pages.py with LEFT OUTER JOINs on Client and Driver
- Create printer_detail.html full-page template showing all config fields and driver info
- Display "No driver assigned" when driver FK is null
- Add disabled "Regenerate Package" button (Phase 4 placeholder)
- Make printer names in printer_list.html clickable links to detail page
2026-04-10 13:04:52 +02:00
kawa 6e7892e862 test(03-02): add failing tests for printer detail page
- test_printer_detail_shows_driver: asserts driver name appears on detail page
- test_printer_detail_not_found: asserts 404 for missing printer ID
- test_printer_detail_no_driver: asserts graceful display when driver is None
2026-04-10 13:04:01 +02:00
kawa 3b644272e7 docs(03-01): complete printer and client CRUD plan summary
- 03-01-SUMMARY.md: documents printer/client CRUD, Alpine.js port derivation,
  HTMX partials, test isolation fix, and PRNT-01 through PRNT-09 requirements
- STATE.md: updated position, decisions, metrics, session record
- ROADMAP.md: phase 03 progress updated (1/2 plans complete)
- REQUIREMENTS.md: PRNT-01 through PRNT-09 marked complete
2026-04-10 12:57:43 +02:00
kawa 356c2ee690 feat(03-01): implement printer and client CRUD with HTMX/Alpine.js UI
- imptune/api/printers.py: POST /printers (all form fields, checkbox->bool,
  FK resolution), DELETE /printers/{id}, grouped list renderer with LEFT JOIN
- imptune/api/clients.py: POST /clients with duplicate-name handling
- imptune/api/pages.py: GET /printers and GET /clients page routes
- imptune/main.py: register printers + clients routers; close db on shutdown
- imptune/db/database.py: close existing connection before re-init (test isolation)
- templates: printers.html, clients.html, printer_form.html (Alpine.js port
  auto-derivation), printer_list.html (grouped by client), client_list.html
- tests/conftest.py: close test-thread db connection in fixture teardown
- tests/test_printer_crud.py: updated to use list(select().where()) for DB
  queries (avoids Peewee thread-local cursor caching across test boundaries)

Auto-fix [Rule 1 - Bug]: DB test isolation — Peewee thread-local connections
persisted across tests causing stale DB reads; fixed via conftest teardown and
lifespan db.close() on shutdown.
2026-04-10 12:56:09 +02:00
kawa 9bc26e377b test(03-01): add failing integration tests for printer and client CRUD
- test_create_printer_persisted: POST /printers + GET /printers
- test_create_printer_duplex/color_mode/paper_size/collate: field persistence
- test_create_client: POST /clients + GET /clients
- test_printer_grouped_by_client: client group heading in list
- test_create_printer_missing_name/invalid_ip: validation 400s
- test_delete_printer: DELETE /printers/{id} removes record
2026-04-10 12:50:00 +02:00
kawaandClaude Opus 4.6 e27d0285ac docs(03): create phase plan for printer configuration
Two plans covering PRNT-01 through PRNT-10: printer+client CRUD with
Alpine.js port derivation (plan 01), and printer detail page with
regeneration placeholder (plan 02).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:35:52 +02:00
kawa 17573fbf6d docs(03): add research and validation strategy 2026-04-10 12:29:02 +02:00
kawaandClaude Sonnet 4.6 4c53ecd5db docs(phase-03): research printer configuration phase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 12:28:03 +02:00
kawaandClaude Opus 4.6 ded9d7a8c5 docs(phase-02): complete phase execution and verification
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:06:40 +02:00
kawa 0f669a90e1 docs(02-02): complete driver upload endpoint plan
- SUMMARY.md with deviations, decisions, metrics
- STATE.md: decisions logged, progress updated, session recorded
- ROADMAP.md: phase 02 marked complete (2/2 plans with summaries)
- REQUIREMENTS.md: DRV-01, DRV-03, DRV-04 marked complete
2026-04-10 12:03:43 +02:00
kawa c648fc5793 feat(02-02): add driver upload endpoint with INF parsing and dedup
- POST /drivers/upload: validates ZIP, parses INF, persists via DriverStore + Peewee
- SHA256 dedup: get_or_create prevents duplicate Driver records
- GET /drivers route added to pages.py with driver_data context
- drivers.router registered in main.py
- drivers.html template with HTMX upload form
- partials/driver_list.html HTMX target with select dropdown and unused-file notice
- Fixed conftest client fixture to use context manager (triggers lifespan/init_db)
- [Rule 3] conftest: TestClient context manager required for lifespan trigger
- [Rule 1] drivers.py: dynamic DRIVERS_DIR read so monkeypatch works in tests
2026-04-10 12:02:00 +02:00
kawa 8ecfbf25a7 test(02-02): add failing integration tests for driver upload 2026-04-10 11:59:30 +02:00
kawa 17db5ce1a8 docs(02-01): complete INF parser plan
- 02-01-SUMMARY.md: TDD execution summary with deviation notes
- STATE.md: updated position, decisions, metrics, session
- ROADMAP.md: phase 2 progress updated (1/2 summaries)
- REQUIREMENTS.md: DRV-02 and DRV-05 marked complete
2026-04-10 11:57:54 +02:00
kawa 5056922890 feat(02-01): implement INF parser with encoding detection and token resolution
- ParsedInf dataclass: driver_names, inf_filename, architecture, has_cat_file, unused_files
- _detect_encoding(): BOM sniffing for UTF-16 LE/BE, UTF-8 BOM, cp1252 fallback
- _resolve_tokens(): regex %TOKEN% expansion from [Strings] section dict
- parse_inf(): RawConfigParser(strict=False) with optionxform=str to preserve case
- Architecture detection: NTamd64->x64, NTarm64->arm64, undecorated->x86, mixed->None
- Deduplication via set(); sorted() for deterministic dropdown order
- [Rule 1 - Bug] Fixed configparser key lowercasing by setting optionxform=str
- All 16 tests pass, zero regressions in 40-test suite
2026-04-10 11:56:51 +02:00
kawa 290106d573 test(02-01): add failing tests for INF parser
- 11 test functions covering all DRV-02 and DRV-05 behaviors
- _detect_encoding tests for UTF-16 LE, UTF-16 BE, UTF-8 BOM, ANSI/cp1252
- parse_inf tests: literal DriverDesc, %TOKEN% resolution, UTF-16 fixture
- Multi-model deduplication, architecture detection (x64/arm64/x86/mixed)
- .cat file detection, unused files detection, empty models section
- INF fixtures: sample.inf, sample_utf16.inf (UTF-16 LE BOM), sample_multi_model.inf
- imptune/services/__init__.py package marker
2026-04-10 11:55:41 +02:00
kawaandClaude Opus 4.6 9f5ee24811 docs(02-driver-management): create phase plan
Two plans: INF parser TDD (wave 1), upload endpoint + UI (wave 2).
Covers DRV-01 through DRV-05.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:48:02 +02:00
kawa 7930619404 docs(phase-02): add research and validation strategy 2026-04-10 11:43:51 +02:00
kawaandClaude Sonnet 4.6 13e098e244 docs(phase-02): research driver management phase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 11:42:39 +02:00
kawaandClaude Opus 4.6 e4196f00da docs(phase-01): complete phase execution and verification
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:36:26 +02:00
kawa 4d57528963 docs(01-02): complete database schema and driver storage plan
- 01-02-SUMMARY.md: TDD execution results, decisions, self-check passed
- STATE.md: progress updated (100% phase 1), 3 decisions recorded
- ROADMAP.md: phase 1 marked Complete (3/3 summaries)
2026-04-10 11:33:20 +02:00
kawa 88d9c5f0d2 feat(01-02): wire init_db() into FastAPI lifespan startup
- Import init_db from imptune.db.database
- Call init_db() after DATA_DIR/DRIVERS_DIR creation in lifespan
- Database auto-initializes on every app startup via volume-mounted path
2026-04-10 11:31:57 +02:00
kawa dea41483b5 feat(01-02): add Peewee models, database init, and driver storage
- imptune/db/database.py: deferred SqliteDatabase with WAL + foreign_keys pragmas and init_db()
- imptune/db/models.py: full schema (Client, Driver, Printer, Icon) for phases 1-5
- imptune/storage/driver_store.py: SHA256 content-addressed DriverStore with dedup
- tests/test_db.py: 7 TDD tests covering all db and storage behaviors
2026-04-10 11:31:39 +02:00