Skip to content

Refactor azure-devops data-plane calls into dedicated azdevops_db.ps1 #23

@jdschleicher

Description

@jdschleicher

Problem Statement

powcuts_by_cli/azdevops_workitems.ps1 has grown to ~1,900 lines and embeds ~40 raw az boards … invocations directly inside business-logic functions (queries, work-item creates, relation adds, iteration/area listings, work-item shows). This couples high-level workflows to the az CLI surface, makes failure handling inconsistent across call sites, and complicates future caching, mocking, or output-format changes. There is no single seam for the "talks to Azure DevOps" boundary.

User Story

As a maintainer of bashcuts, I want every data-plane Azure DevOps CLI call to go through a thin wrapper layer in azdevops_db.ps1, so that the higher-level functions in azdevops_workitems.ps1 stop knowing about az invocation mechanics, error parsing, and JSON deserialization, and so future improvements (caching, retry, alternative transports) are a one-file change.

Acceptance Criteria

  • New file powcuts_by_cli/azdevops_db.ps1 exists and is dot-sourced from powcuts_home.ps1
  • Every data-plane az call currently in azdevops_workitems.ps1 and pow_az_cli.ps1 is invoked through a wrapper function in azdevops_db.ps1 — specifically:
    • az boards query (WIQL queries)
    • az boards work-item create (incl. user story creation)
    • az boards work-item show
    • az boards work-item update
    • az boards work-item relation add
    • az boards iteration project list
    • az boards area project list
  • Session/admin calls (az login, az account show, az extension list/add, az devops configure) remain in azdevops_workitems.ps1 — out of scope
  • Wrapper functions follow Verb-Noun PascalCase with approved verbs, e.g. Invoke-AzDevOpsBoardsQuery, New-AzDevOpsWorkItem, Get-AzDevOpsWorkItem, Set-AzDevOpsWorkItem, Add-AzDevOpsWorkItemRelation, Get-AzDevOpsIterationList, Get-AzDevOpsAreaList
  • Existing Invoke-AzDevOpsAzJson and Invoke-AzDevOpsBoardsQuery (lines 336 / 364) are relocated to azdevops_db.ps1 and become the canonical JSON+error path; duplicate ad-hoc az ... | ConvertFrom-Json patterns in azdevops_workitems.ps1 are routed through them
  • All callers in azdevops_workitems.ps1 and pow_az_cli.ps1 use the wrappers — grep -nE '\baz boards' powcuts_by_cli/azdevops_workitems.ps1 powcuts_by_cli/pow_az_cli.ps1 returns no active call sites (only comments / Write-Host hints)
  • No public-facing function signature changes — every existing user-callable command (Get-AzDevOpsAssigned, Open-AzDevOpsAssigned, Sync-AzDevOpsCache, New-AzDevOpsUserStory, etc.) keeps the same name, parameters, and output shape
  • pwsh parses both azdevops_db.ps1 and the modified azdevops_workitems.ps1 and pow_az_cli.ps1 with zero errors
  • Behavior verified in a fresh PowerShell terminal: re-run the smoke flow (Connect-AzDevOps, Sync-AzDevOpsCache, Get-AzDevOpsAssigned, New-AzDevOpsUserStory) and confirm identical output to pre-refactor
  • CLAUDE.md style rules respected — multi-line if/switch branches, named magic strings, two blank lines between top-level functions, no return <call> patterns

Affected Areas

Area File(s) Change Type
New data-plane wrapper layer powcuts_by_cli/azdevops_db.ps1 Create
Dot-source wire-up powcuts_home.ps1 Modify
Replace inline az boards … with wrapper calls powcuts_by_cli/azdevops_workitems.ps1 Modify
Replace inline az boards work-item create with wrapper powcuts_by_cli/pow_az_cli.ps1 Modify

Shell Parity Note

Bash side (bashcuts_by_cli/.az_bashcuts) is out of scope for this issue — its shortcuts are simple inline aliases/functions and don't have the same call-site duplication problem. A parity follow-up can be filed if it becomes valuable.

Out of Scope

  • Bash-side refactor of .az_bashcuts
  • Session/admin calls (az login, az account show, az extension, az devops configure)
  • New features, new wrapper capabilities, retry logic, or caching changes beyond what already exists
  • Renaming or signature changes to user-facing functions
  • Any change to pow_az_cli.ps1 beyond routing its single az boards work-item create through the new wrapper

Open Questions

  • Should the new file's wrappers Write-Verbose the underlying az invocation for debuggability, or stay silent? (lean: silent — match current behavior)
  • Where should the wrappers' output stream live — return parsed objects (current Invoke-AzDevOpsAzJson style) or both raw + parsed? (lean: parsed only, matches existing helper)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions