feat(cdc): addTable route — DynamoDB-first + rollback

This commit is contained in:
Rafael
2026-08-17 17:01:05 -03:00
parent fab2061efc
commit 55308420ff
7 changed files with 240 additions and 5 deletions
@@ -5,6 +5,7 @@
jest.mock('../customers/customers.service', () => ({ CustomersService: class {} }));
jest.mock('../catalog/catalog.service', () => ({ CatalogService: class {} }));
jest.mock('../inputs/inputs.service', () => ({ InputsService: class {} }));
jest.mock('../pipelinesV2/pipelines.service', () => ({ PipelinesService: class {} }));
import { Test, TestingModule } from '@nestjs/testing';
import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
@@ -16,6 +17,7 @@ import { DynamoDBService } from '../../services/dynamodb';
import { CustomersService } from '../customers/customers.service';
import { CatalogService } from '../catalog/catalog.service';
import { InputsService } from '../inputs/inputs.service';
import { PipelinesService } from '../pipelinesV2/pipelines.service';
const logger = {
info: (...args) => args,
@@ -49,6 +51,7 @@ describe('PlatformApiController - deleteTable', () => {
{ provide: CustomersService, useValue: {} },
{ provide: CatalogService, useValue: {} },
{ provide: InputsService, useValue: inputsService },
{ provide: PipelinesService, useValue: {} },
{ provide: DadosferaLogger, useValue: { logger } },
],
}).compile();
@@ -105,3 +108,94 @@ describe('PlatformApiController - deleteTable', () => {
expect(reconfiguredConnector).toBe(false);
});
});
describe('PlatformApiController - addTable', () => {
let controller: PlatformApiController;
let inputsService: { addCdcTable: jest.Mock; removeCdcTable: jest.Mock };
let pipelinesClientService: { addCdcJobs: jest.Mock };
const body = {
table_name: 'orders',
table_schema: 'public',
primary_keys: ['id'],
destinations: {
raw: { table_schema: 'raw', table_name: 'orders' },
qualify: { table_schema: 'qualify', table_name: 'orders' },
},
};
beforeEach(async () => {
inputsService = {
addCdcTable: jest.fn(),
removeCdcTable: jest.fn(),
};
pipelinesClientService = {
addCdcJobs: jest.fn(),
};
const module: TestingModule = await Test.createTestingModule({
controllers: [PlatformApiController],
providers: [
{ provide: PlatformApiService, useValue: { proxy: jest.fn() } },
{ provide: ElasticsearchService, useValue: {} },
{ provide: DynamoDBService, useValue: {} },
{ provide: CustomersService, useValue: {} },
{ provide: CatalogService, useValue: {} },
{ provide: InputsService, useValue: inputsService },
{ provide: PipelinesService, useValue: pipelinesClientService },
{ provide: DadosferaLogger, useValue: { logger } },
],
}).compile();
controller = module.get<PlatformApiController>(PlatformApiController);
});
it('addTable: DynamoDB append then platform AddJobs, returns job_ids', async () => {
inputsService.addCdcTable.mockResolvedValue({ input: {} });
pipelinesClientService.addCdcJobs.mockResolvedValue({ job_ids: ['p_2'], skipped: [] });
const result = await controller.addTable('pid', 'iid', body, mockUser);
expect(inputsService.addCdcTable).toHaveBeenCalledWith({
id: 'iid',
table: {
table_schema: 'public',
table_name: 'orders',
primary_keys: ['id'],
name: 'orders',
},
info: { customer_id: 'c1', customer: 'cust', user_id: 'u1' },
});
expect(pipelinesClientService.addCdcJobs).toHaveBeenCalledWith({
pipeline_id: 'pid',
input_id: 'iid',
tables: [{
table_schema: 'public',
table_name: 'orders',
primary_keys: ['id'],
destinations: body.destinations,
}],
info: { customer_id: 'c1', user_id: 'u1', customer: 'cust' },
});
expect(result).toEqual({ job_ids: ['p_2'], skipped: [] });
expect(inputsService.removeCdcTable).not.toHaveBeenCalled();
const addCdcTableOrder = inputsService.addCdcTable.mock.invocationCallOrder[0];
const addCdcJobsOrder = pipelinesClientService.addCdcJobs.mock.invocationCallOrder[0];
expect(addCdcTableOrder).toBeLessThan(addCdcJobsOrder);
});
it('addTable: rolls back the DynamoDB row when AddJobs fails', async () => {
inputsService.addCdcTable.mockResolvedValue({ input: {} });
pipelinesClientService.addCdcJobs.mockRejectedValue(new Error('platform down'));
inputsService.removeCdcTable.mockResolvedValue({});
await expect(controller.addTable('pid', 'iid', body, mockUser)).rejects.toThrow('platform down');
expect(inputsService.removeCdcTable).toHaveBeenCalledWith({
id: 'iid',
table_name: 'orders',
info: { customer_id: 'c1', customer: 'cust', user_id: 'u1' },
});
});
});