Files
azure-image-chooser/migration-plan/plan.md

8.5 KiB

Plan: React + Vite Rewrite of Azure Image Chooser

Rewrite the current Streamlit application into a two-tier web app (React + Vite frontend and Node.js backend) while preserving core image-discovery behavior (location -> publisher -> offer -> SKU -> version) and generated usage outputs, and redesigning UX and template architecture, with strict non-destructive workspace constraints.

Hard constraints

  1. Existing workspace files must remain untouched, except .gitignore.
  2. All new application source must live under src/.
  3. Build artifacts must be emitted only to dist/.
  4. A new Dockerfile and entrypoint.sh must be added at the workspace root.
  5. The container runtime must use Node.js 24 LTS on Debian trixie-slim (node:24-trixie-slim).
  6. All new source code must be TypeScript and use the TypeScript 6 transpiler (latest revision).
  7. Frontend UI must use plain Material UI v9.x.x.
  8. All MUI-related questions and implementation decisions must be resolved using mui-mcp as the primary source/tool.
  9. Frontend must use the latest stable React line (React 19.2.x), with no legacy compatibility or migration work included.
  10. Docker is not available in the target environment; container lifecycle operations must use Apple-sponsored container CLI only.

Steps

  1. Phase 0 - Planning artifact handoff

  2. After plan mode is turned off, copy plan artifacts to workspace directory migration-plan/ for future reference:

    • migration-plan/plan.md
    • migration-plan/version-manifest.md
  3. Keep session/repo memory files as source-of-truth backups.

  4. Phase 1 - Baseline and migration contract

  5. Capture current functional contract from existing app behavior in app/image-chooser.py: cascading selectors, semantic version sorting, empty-state behavior, and SKU export format.

  6. Define backend API contract for frontend consumption: locations, publishers, offers, skus, versions, templates, rendered output, and SKU export endpoints, including error payloads.

  7. Lock frontend framework prerequisites from current MUI status before scaffolding: Material UI v9.x.x, React 19.2.x (latest stable), Emotion styling engine defaults, and required companion packages.

  8. Explicitly exclude legacy React compatibility paths and migration workarounds from scope (no legacy shims, no backward-compat migration tracks).

  9. Define target repository layout under src/ for frontend and backend packages, with dist/ as the fixed artifact directory.

  10. Define non-destructive execution guardrails: no edits to legacy files except .gitignore updates for node_modules and artifact outputs.

  11. Phase 2 - Node backend in src

  12. Scaffold backend under src/backend in TypeScript (mandatory) with modules for Azure compute discovery, template catalog, rendering, and validation, compiled with TypeScript 6.

  13. Implement Azure integration equivalent to current data loaders, including region_type=Physical filtering and conditional semantic version sorting when all versions match X.Y.Z.

  14. Implement endpoint caching (TTL by endpoint+params) and structured logging.

  15. Implement redesigned template subsystem with metadata model and render endpoint.

  16. Add backend tests under src/backend aligned to the API contract.

  17. Phase 3 - React + Vite frontend in src

  18. Scaffold frontend under src/frontend using Vite with TypeScript (mandatory), configure output directory to dist/, compile with TypeScript 6, use React 19.2.x (latest stable), and use plain Material UI v9.x.x as the UI component library.

  19. Build cascading async selectors with deterministic reset behavior (location -> publisher -> offer -> sku -> version).

  20. Implement API-driven state management (for example TanStack Query) with loading, empty, and error states.

  21. Implement usage output UI with template selection, rendered snippet display, copy action, and SKU export display, using plain Material UI v9.x.x components and styling primitives (Emotion-based engine).

  22. Add frontend tests under src/frontend for cascade behavior and output rendering.

  23. Phase 4 - Root runtime wrapper and cutover

  24. Add new root Dockerfile that builds/runs the new src-based application stack on Node.js 24 LTS with Debian trixie-slim (node:24-trixie-slim), and ensure runtime commands are documented/executed via Apple container CLI (not Docker).

  25. Add new root entrypoint.sh that starts the new runtime components.

  26. Update .gitignore for node_modules, dist artifacts, and any new temporary outputs.

  27. Validate core behavior parity against Streamlit baseline using representative selections and generated outputs.

  28. Keep legacy assets in place (untouched) during and after migration unless separately approved for cleanup.

Parallelism and dependencies

  1. Phase 0 runs first and gates execution handoff artifacts in workspace.
  2. Phase 1 blocks implementation.
  3. After API contract freeze, backend (Phase 2) and frontend scaffold (Phase 3) can run in parallel.
  4. Phase 4 depends on stable frontend/backend run commands and artifact paths.

Relevant files

  • /Users/slawek/src/azure-image-chooser/app/image-chooser.py - source-of-truth behavior reference only; do not modify.
  • /Users/slawek/src/azure-image-chooser/app/templates.json - current template catalog reference only; do not modify.
  • /Users/slawek/src/azure-image-chooser/app/templates/arm_vm.jsonc - output reference only; do not modify.
  • /Users/slawek/src/azure-image-chooser/app/templates/azurerm_hcl.tpl - output reference only; do not modify.
  • /Users/slawek/src/azure-image-chooser/app/templates/shell.tpl - output reference only; do not modify.
  • /Users/slawek/src/azure-image-chooser/.gitignore - only existing file allowed to be changed.
  • /Users/slawek/src/azure-image-chooser/src/ - new source tree for rewritten application.
  • /Users/slawek/src/azure-image-chooser/dist/ - artifact output directory.
  • /Users/slawek/src/azure-image-chooser/Dockerfile - new root runtime image definition.
  • /Users/slawek/src/azure-image-chooser/entrypoint.sh - new root runtime entrypoint.

Verification

  1. Workspace contains migration-plan/plan.md and migration-plan/version-manifest.md after plan mode is off.
  2. Git diff check confirms only new files plus .gitignore modifications; no edits in legacy files.
  3. Backend tests pass for API contract, validation, filtering, sorting, and rendering.
  4. Type-check/transpile verification passes with TypeScript 6 for both backend and frontend packages.
  5. Frontend tests pass for selector cascade and output rendering.
  6. Frontend dependency and implementation checks confirm plain Material UI v9.x.x is used (no alternate UI framework).
  7. Verification confirms MUI installation prerequisites are met for React 19.2.x and Emotion packages.
  8. Verification confirms there are no legacy compatibility layers or migration-specific workarounds in frontend dependencies/configuration.
  9. Local run verifies UI flow and generated outputs match baseline behavior for representative scenarios.
  10. Image build inspection via Apple container CLI confirms the runtime base image is Node.js 24 LTS on Debian trixie-slim (node:24-trixie-slim).
  11. Artifact generation confirms outputs land only in dist/ directory.

Decisions

  • Use Node.js backend (confirmed).
  • Keep only core functionality unchanged; UX and architecture can be redesigned (confirmed).
  • Redesign template system now (confirmed).
  • Enforce non-destructive migration: existing files untouched except .gitignore (confirmed).
  • Place all new application code in src/ and add new root Dockerfile + entrypoint.sh (confirmed).
  • Use Node.js 24 LTS on Debian trixie-slim as container runtime base image (confirmed).
  • Use TypeScript-only source with TypeScript 6 transpiler across backend and frontend (confirmed).
  • Use plain Material UI v9.x.x for frontend UI implementation (confirmed).
  • Use mui-mcp as the primary tool/source for all MUI-related implementation questions (confirmed).
  • Use latest stable React (19.2.x at planning time) and exclude legacy compatibility/migration paths (confirmed).
  • Use Apple container CLI (macOS 26, Apple silicon) for container operations; no Docker dependency (confirmed).

Scope boundaries

  • In scope: functional core parity for image lookup and output generation, new frontend/backend architecture in src/, root runtime wrappers, and .gitignore updates.
  • Out of scope: modifying existing legacy app/ and terraform/ files, removing legacy code, or altering old deployment definitions.

Further Considerations

  1. Artifact output is fixed to dist/ for consistency with the chosen convention.
  2. If backend and frontend are separate runtime processes, define entrypoint process model early (single-process with static serve vs process manager).