Unblocks the CdcDestination contract locally on the CDC branch. Swap to a
published registry version before merge (CI guard blocks file: deps).
Co-Authored-By: WOZCODE <contact@withwoz.com>
Removing N tables via Edit Objects previously looped a single-table
DELETE per table (maestro deleteTable hardcodes job_ids:[one]), so the
Debezium source + Snowflake sink connectors were rewritten/restarted once
per table. platform-api's DELETE /pipeline/:id/jobs already batches (2
connector writes total for any N), but nothing above it used the array.
New maestro DELETE /pipelines/:pipelineId/inputs/:inputId/tables takes
{ table_names: [] }: soft-deletes each in DynamoDB (tracking successes),
resolves all table_names -> job_ids from the platform pipeline in one GET,
then makes ONE DELETE /pipeline/:id/jobs with all job_ids. All-or-nothing:
any failure (a later mark, an unmatched table, or the platform delete)
rolls back only the marks made in this call.
The single-table deleteTable route is kept (unchanged) — nothing else
depends on removing it, and that's a separable cleanup.
Tests: N tables -> one platform DELETE with all job_ids and no per-job
call; rollback on platform failure; rollback + no delete when a later mark
fails; 404 for an unmatched table. 8 controller specs pass; maestro builds.
Co-Authored-By: WOZCODE <contact@withwoz.com>
Switch @dadosfera/protospack-v2 from the local file: tarball (removed from
the protospack-v2 repo) to the CI-published CodeArtifact version. Installs
and builds clean; test suites pass.
Co-Authored-By: WOZCODE <contact@withwoz.com>
The guard read `status[status.length-1].last_status` on the pipeline_run
history. For a pipeline that has never run — which is the permanent state
of CDC pipelines, since they replicate continuously and never record
batch runs — pipeline_run is empty, so the last element is undefined and
`.last_status` threw, surfacing as "Error checking pipeline status:
Cannot read properties of undefined (reading 'last_status')". This
blocked Edit Objects (and delete-table) for every CDC pipeline.
Treat an empty/statusless run history as "not running" and allow the
edit (undefined never satisfied 'running' anyway). Also stop the catch
from double-wrapping the deliberate is-running BadRequestException, so
that rejection keeps its clear message; genuine status-check failures
still fail closed with the wrapped message (safe default for a
destructive-op gate).
Adds a guard spec: empty history -> allow, statusless -> allow, not
running -> allow, running -> is-running message (not wrapped), platform
error -> wrapped message.
Co-Authored-By: WOZCODE <contact@withwoz.com>
Claude-Session: https://claude.ai/code/session_01145m1zZMfx8RSJBxAhySdg
The pipeline create body carries `config.tables[].destinations`, which
the CDC path in pi-factory needs to honor a user-supplied raw Snowflake
table name. The gRPC PipelineV2CreateRequest previously had no `config`
field, so `...body` dropped it on the wire.
Bump protospack to cdc.3 (adds optional `config` string). Serialize
`body.config` into the create request the same way `properties` is
handled, and add `config?` to the ICreatePipelineV2Req DTO so it's
typed. Add a spec asserting the gRPC request carries a stringified
config with the destination intact.
Co-Authored-By: WOZCODE <contact@withwoz.com>
Claude-Session: https://claude.ai/code/session_01145m1zZMfx8RSJBxAhySdg
updatePlatformJobs pushes batch sync_mode/memory to jobs by positional
index — meaningless for CDC and corrupting. CDC add/remove use dedicated
endpoints, so skip updatePlatformJobs for CDC inputs. The input record
update still runs.
Co-Authored-By: WOZCODE <contact@withwoz.com>
deleteTable called the DB-row-only DELETE /jobs/{id}, leaving the CDC
connector still replicating a removed table. For CDC jobs, call
DELETE /pipeline/{id}/jobs (RemoveJobsUsecase) with delete_snowflake_tables
false so replication stops but landed data is kept. Batch path unchanged.
Co-Authored-By: WOZCODE <contact@withwoz.com>