---
phase: 20-windows-client
plan: 01
subsystem: desktop-app
tags: [csharp, winforms, printing, system-tray, pdfium, thermal-printer]

requires:
  - phase: 18-print-queue-backend
    provides: REST API (pending, download, complete), API key auth
  - phase: 19-ui-integration
    provides: UI creating print jobs (single + bulk)
provides:
  - Windows tray application polling API and printing labels
  - Self-contained .exe with PdfiumViewer for PDF rendering
affects: []

tech-stack:
  added: [".NET 8 WinForms", "PdfiumViewer 2.13.0", "pdfium native x64"]
  patterns: [polling-service, tray-application-context, synchronization-context-ui-updates]

key-files:
  created:
    - clients/windows/OrderPROPrint/OrderPROPrint.sln
    - clients/windows/OrderPROPrint/OrderPROPrint.csproj
    - clients/windows/OrderPROPrint/Program.cs
    - clients/windows/OrderPROPrint/TrayApplicationContext.cs
    - clients/windows/OrderPROPrint/Models/AppSettings.cs
    - clients/windows/OrderPROPrint/Models/PrintJob.cs
    - clients/windows/OrderPROPrint/Services/PrintApiClient.cs
    - clients/windows/OrderPROPrint/Services/PrintService.cs
    - clients/windows/OrderPROPrint/Services/PollingService.cs
    - clients/windows/OrderPROPrint/Forms/SettingsForm.cs
    - clients/windows/OrderPROPrint/Forms/SettingsForm.Designer.cs
    - clients/windows/OrderPROPrint/Forms/LogForm.cs
    - clients/windows/OrderPROPrint/Forms/LogForm.Designer.cs

key-decisions:
  - "PdfiumViewer instead of SumatraPDF — zero external dependencies, native PDF rendering"
  - "Directory publish instead of single-file — pdfium.dll native not compatible with PublishSingleFile"
  - "SynchronizationContext.Post for thread-safe tray icon updates from polling timer"
  - "Option C (single client) — multi-client support deferred"

patterns-established:
  - "C# desktop app lives in clients/windows/ subdirectory of orderPRO repo"
  - "PendingJobsResponse wrapper for API JSON deserialization ({jobs: [...]})"

duration: ~2h
started: 2026-03-22T20:30:00Z
completed: 2026-03-22T22:45:00Z
---

# Phase 20 Plan 01: Windows Client Summary

**Aplikacja C# WinForms w system tray — polling API orderPRO, automatyczne pobieranie i drukowanie etykiet PDF na drukarce termicznej via PdfiumViewer.**

## Performance

| Metric | Value |
|--------|-------|
| Duration | ~2h |
| Started | 2026-03-22 |
| Completed | 2026-03-22 |
| Tasks | 3 (2 auto + 1 checkpoint) |
| Files created | 13 |

## Acceptance Criteria Results

| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Aplikacja w system tray | Pass | NotifyIcon + ContextMenuStrip z Ustawienia, Logi, Wstrzymaj, O programie, Zamknij |
| AC-2: Konfiguracja API | Pass | SettingsForm z URL, klucz, drukarka, interwał + Test połączenia |
| AC-3: Polling i pobieranie | Pass | Timer co N sekund, download label, mark complete |
| AC-4: Drukowanie A6 | Pass | PdfiumViewer CreatePrintDocument z PaperSize A6 (105x148mm) |
| AC-5: Obsługa błędów | Pass | Error icon, tooltip, logi — polling kontynuuje |

## Accomplishments

- Standalone .exe (self-contained .NET 8, ~170MB z runtime)
- System tray z menu kontekstowym i dwuklikiem na ustawienia
- Polling z konfigurowalnym interwałem (5-300s)
- PdfiumViewer renderuje PDF i drukuje bez zewnętrznych narzędzi
- Okno logów z historią (ciemny motyw, Consolas, kopiowanie)
- Thread-safe UI updates via SynchronizationContext
- Settings w %APPDATA%/OrderPROPrint/settings.json

## Deviations from Plan

### Summary

| Type | Count | Impact |
|------|-------|--------|
| Scope additions | 1 | Okno logów (request użytkownika) |
| Auto-fixed | 3 | JSON deserialization, pdfium.dll, NotifyIcon API |

**Total impact:** Lepsza diagnostyka dzięki logom, stabilniejszy druk.

### Auto-fixed Issues

**1. JSON deserialization mismatch**
- **Issue:** API zwraca `{"jobs": [...]}`, klient deserializował jako `List<PrintJob>`
- **Fix:** Dodano `PendingJobsResponse` wrapper, poprawiono property names
- **Files:** Models/PrintJob.cs, Services/PrintApiClient.cs

**2. pdfium.dll missing in publish**
- **Issue:** `PublishSingleFile` nie dołącza natywnej DLL z NuGet
- **Fix:** Directory publish + MSBuild target `CopyPdfiumNative`
- **Files:** OrderPROPrint.csproj

**3. NotifyIcon API incompatibility**
- **Issue:** `NotifyIcon.IsDisposed` i `.Invoke()` nie istnieją w .NET 8
- **Fix:** SynchronizationContext.Post + własny `_isDisposed` flag
- **Files:** TrayApplicationContext.cs

### Scope Additions

**1. Okno logów (LogForm)**
- **Requested by:** użytkownik podczas testów
- **Purpose:** diagnostyka błędów druku
- **Files:** Forms/LogForm.cs, Forms/LogForm.Designer.cs

## Decisions Made

| Decision | Rationale | Impact |
|----------|-----------|--------|
| PdfiumViewer zamiast SumatraPDF | Zero external deps, native rendering | Większy .exe ale prostsze wdrożenie |
| Directory publish zamiast single-file | pdfium.dll native incompatible | Cały folder publish/ do skopiowania |
| Opcja C — jeden klient | Multi-client wymaga zmian backendu | Dla wielu komputerów trzeba dodać api_key_id |
| .NET 8 SDK zainstalowany via winget | Potrzebny do budowania projektu | Nowa zależność dev na maszynie |

## SonarQube Scan

**Not applicable** — sonar-scanner skonfigurowany tylko dla PHP. Projekt C# jest poza zakresem skanowania.

## Next Phase Readiness

**Ready:**
- Milestone v0.7 kompletny — wszystkie 3 fazy zakończone
- Pełny flow: zlecenie z UI → API → Windows Client → drukarka

**Concerns:**
- Multi-client: wielu klientów drukuje duplikaty (opcja A/B do rozważenia w przyszłości)
- Rozmiar .exe: 170MB (self-contained z runtime .NET)

**Blockers:**
- None

---
*Phase: 20-windows-client, Plan: 01*
*Completed: 2026-03-22*
