# PortTracker Batch Operations Design **Date:** 2026-02-27 **Status:** Approved ## Problem The PortTracker CLI only supports one-at-a-time operations for status updates, mappings, and N/A marking. With ~3700 features and ~3300 tests, bulk operations require dropping to raw `sqlite3` commands. This is error-prone and bypasses any validation the CLI could provide. ## Design ### Approach Add `batch-update` and `batch-map` subcommands under each existing entity command (`feature`, `test`, `module`, `library`). All batch commands share a common filter + dry-run infrastructure. ### Shared Batch Infrastructure A new `BatchFilters` static class in `Commands/BatchFilters.cs` provides: **Filter Options** (combined with AND logic): - `--ids ` — ID range like `100-200`, comma-separated `1,5,10`, or mixed `1-5,10,20-25` - `--module ` — filter by module_id (feature/test only) - `--status ` — filter by current status value **Dry-Run Default:** - Without `--execute`, commands show a preview: "Would affect N items:" + table of matching rows - With `--execute`, changes are applied inside a transaction and "Updated N items." is printed - At least one filter is required (no accidental "update everything" with zero filters) **Shared Methods:** - `AddFilterOptions(Command cmd, bool includeModuleFilter)` — adds the common options to a command - `BuildWhereClause(...)` — returns SQL WHERE clause + parameters from parsed filter values - `PreviewOrExecute(Database db, string table, string selectSql, string updateSql, params[], bool execute)` — handles dry-run preview vs actual execution ### Feature Batch Commands **`feature batch-update`** - Filters: `--ids`, `--module`, `--status` - Setters: `--set-status` (required), `--set-notes` (optional) - Flag: `--execute` **`feature batch-map`** - Filters: `--ids`, `--module`, `--status` - Setters: `--set-project`, `--set-class`, `--set-method` (at least one required) - Flag: `--execute` ### Test Batch Commands **`test batch-update`** - Filters: `--ids`, `--module`, `--status` - Setters: `--set-status` (required), `--set-notes` (optional) - Flag: `--execute` **`test batch-map`** - Filters: `--ids`, `--module`, `--status` - Setters: `--set-project`, `--set-class`, `--set-method` (at least one required) - Flag: `--execute` ### Module Batch Commands **`module batch-update`** - Filters: `--ids`, `--status` - Setters: `--set-status` (required), `--set-notes` (optional) - Flag: `--execute` **`module batch-map`** - Filters: `--ids`, `--status` - Setters: `--set-project`, `--set-namespace`, `--set-class` (at least one required) - Flag: `--execute` ### Library Batch Commands **`library batch-update`** - Filters: `--ids`, `--status` - Setters: `--set-status` (required), `--set-notes` (optional, maps to `dotnet_usage_notes`) - Flag: `--execute` **`library batch-map`** - Filters: `--ids`, `--status` - Setters: `--set-package`, `--set-namespace`, `--set-notes` (at least one required) - Flag: `--execute` ## Examples ```bash # Preview: which features in module 5 are not_started? porttracker feature batch-update --module 5 --status not_started --set-status deferred # Execute: defer all features in module 5 with a reason porttracker feature batch-update --module 5 --status not_started --set-status deferred --set-notes "needs server runtime" --execute # Execute: mark tests 500-750 as deferred porttracker test batch-update --ids 500-750 --set-status deferred --set-notes "server-integration" --execute # Execute: batch-map all features in module 3 to a .NET project porttracker feature batch-map --module 3 --set-project "ZB.MOM.NatsNet.Server" --execute # Preview: what libraries are unmapped? porttracker library batch-update --status not_mapped --set-status mapped # Execute: batch-map libraries porttracker library batch-map --ids 1-20 --set-package "Microsoft.Extensions.Logging" --set-namespace "Microsoft.Extensions.Logging" --execute ``` ## File Changes | File | Change | |------|--------| | `Commands/BatchFilters.cs` | New — shared filter options, WHERE builder, preview/execute logic | | `Commands/FeatureCommands.cs` | Add `batch-update` and `batch-map` subcommands | | `Commands/TestCommands.cs` | Add `batch-update` and `batch-map` subcommands | | `Commands/ModuleCommands.cs` | Add `batch-update` and `batch-map` subcommands | | `Commands/LibraryCommands.cs` | Add `batch-update` and `batch-map` subcommands | | `Data/Database.cs` | Add `ExecuteInTransaction` helper for batch safety | ## Non-Goals - No batch create or batch delete — not needed for the porting workflow - No raw `--where` SQL escape hatch — structured filters cover all use cases - No interactive y/n prompts — dry-run + `--execute` flag is sufficient and scriptable