Skip to content

feat(datasources): add json-layouts and delete commands (FT-1918)#33

Merged
joalves merged 8 commits into
mainfrom
feat/FT-1918/datasource-commands
May 11, 2026
Merged

feat(datasources): add json-layouts and delete commands (FT-1918)#33
joalves merged 8 commits into
mainfrom
feat/FT-1918/datasource-commands

Conversation

@joalves
Copy link
Copy Markdown
Collaborator

@joalves joalves commented May 11, 2026

Summary

Wraps four datasource backend endpoints that the CLI was missing:

  • absmartly datasources delete <id>DELETE /v1/datasources/:id. Backend rejects with a clear error if the datasource is the default or used by a goal — those propagate verbatim.
  • absmartly datasources json-layouts create <id> → creates the json_layouts table on the datasource.
  • absmartly datasources json-layouts recreate <id> --yes → drops and recreates the table. Destructive — bails out before any client setup unless --yes is passed.
  • absmartly datasources json-layouts preview <id> → returns row count + a 5-row sample of the json_layouts table.

The three json_layouts endpoints were added to the office backend on the FT-1865 branch; this PR adds the corresponding CLI surface. The delete command is for a pre-existing backend endpoint that the CLI had never wrapped.

Each command follows the existing three-layer pattern: APIClient method → core/datasources wrapper → commander subcommand, with tests at each layer that the layer cares about.

JIRA: FT-1918

Test plan

  • bun run test — full suite (2320 tests, all pass)
  • bun run lint
  • bun run build
  • absmartly datasources --help lists delete and json-layouts
  • absmartly datasources json-layouts --help lists create, recreate, preview
  • absmartly datasources json-layouts recreate --help documents the --yes flag
  • Manual smoke against a dev backend: delete a non-default unused datasource succeeds; delete on the default returns the backend's conflict message
  • Manual smoke against a dev backend: json-layouts create / preview / recreate --yes on a real datasource
  • Manual smoke: json-layouts recreate without --yes prints the red refusal to stderr and exits 1

Summary by CodeRabbit

  • New Features

    • Datasource deletion functionality
    • JSON layouts management with create, recreate, and preview operations
    • New CLI commands for datasource operations
  • Tests

    • Added test coverage for datasource deletion and JSON layouts commands

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Walkthrough

This PR extends the datasources command to support deletion and JSON layout management. Four new HTTP client methods are added for datasource deletion via DELETE /datasources/:id and JSON layout operations via POST requests to /json_layouts/create, /json_layouts/recreate, and /json_layouts/preview endpoints. Core wrapper functions with corresponding parameter interfaces convert these into CommandResult objects following the existing pattern. CLI subcommands expose delete and a nested json-layouts group (with create, recreate, and preview subcommands) that invoke the core functions and provide user feedback. Comprehensive tests cover both core and CLI layers with mock setup and operation verification, including validation that the recreate subcommand requires a --yes confirmation flag.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A hop through datasources we go,
Delete what's old, let JSON layouts flow,
From API calls to CLI commands bright,
Each layer tested, every path just right!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding json-layouts and delete commands for datasources, with issue reference.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/FT-1918/datasource-commands

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
src/api-client/api-client.ts (1)

2447-2453: ⚡ Quick win

Validate ok:false envelopes for json-layouts mutations.

createDatasourceJsonLayouts and recreateDatasourceJsonLayouts currently ignore API envelope failures, so a 200 response with ok: false could be reported as success.

Proposed patch
 async createDatasourceJsonLayouts(id: DatasourceId): Promise<void> {
-  await this.request('POST', `/datasources/${id}/json_layouts/create`);
+  const response = await this.request('POST', `/datasources/${id}/json_layouts/create`);
+  this.validateOkResponse(response, 'createDatasourceJsonLayouts');
 }

 async recreateDatasourceJsonLayouts(id: DatasourceId): Promise<void> {
-  await this.request('POST', `/datasources/${id}/json_layouts/recreate`);
+  const response = await this.request('POST', `/datasources/${id}/json_layouts/recreate`);
+  this.validateOkResponse(response, 'recreateDatasourceJsonLayouts');
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api-client/api-client.ts` around lines 2447 - 2453, The two methods
createDatasourceJsonLayouts and recreateDatasourceJsonLayouts currently call
this.request and ignore the API envelope, so they treat a 200 with {ok:false} as
success; change each to capture the response (e.g. const res = await
this.request(...)) and validate res.ok === true, throwing an Error (including
res.error or res.message if present) when ok is false so failures are surfaced
instead of swallowed.
src/core/datasources/datasources.test.ts (1)

20-37: ⚡ Quick win

Reset shared mocks between tests for isolation.

mockClient is reused across all specs without a reset hook, so call history/implementations can bleed between cases.

Proposed patch
 import { describe, it, expect, vi } from 'vitest';
+import { beforeEach } from 'vitest';
@@
 describe('datasources', () => {
   const mockClient = {
@@
   };
+
+  beforeEach(() => {
+    vi.clearAllMocks();
+  });

Also applies to: 132-165

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/datasources/datasources.test.ts` around lines 20 - 37, The shared
mockClient in the describe('datasources', ...) block is reused across tests so
call histories and implementations can leak; add a test hook to reset mocks
between specs—for example add beforeEach(() =>
Object.values(mockClient).forEach(fn => fn.mockReset())) or use Vitest's
vi.resetAllMocks()/vi.clearAllMocks() in beforeEach/afterEach—apply the same
change for the other mock block around lines with the second mockClient (the
132-165 region) so all mock functions (e.g., listDatasources, getDatasource,
createDatasource, etc.) are reset before each test.
src/commands/datasources/index.ts (1)

209-216: ⚡ Quick win

Prefer throwing over direct process.exit(1) in the recreate guard.

The current code's process.exit(1) bypasses withErrorHandling's error handler entirely. Throwing allows handleCommandError to manage the exit consistently, consolidating error logging to a single code path rather than having duplicated error output logic.

Proposed patch
     withErrorHandling(async (id: DatasourceId, options: { yes: boolean }) => {
       if (!options.yes) {
-        console.error(
-          chalk.red(
-            `✗ Refusing to recreate the json_layouts table on datasource ${id} without --yes. This drops the existing table.`
-          )
-        );
-        process.exit(1);
+        throw new Error(
+          `Refusing to recreate the json_layouts table on datasource ${id} without --yes. This drops the existing table.`
+        );
       }
       const globalOptions = getGlobalOptions(jsonLayoutsRecreateCommand);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/datasources/index.ts` around lines 209 - 216, The recreate guard
currently calls process.exit(1) when options.yes is false which bypasses the
withErrorHandling/handleCommandError path; instead, throw a descriptive Error
(e.g., new Error with the same message) from the block that checks options.yes
so the error bubbles up to withErrorHandling/handleCommandError for consistent
logging and exit handling; update the block surrounding the options.yes check
(the recreate logic in the command handler) to remove process.exit(1) and throw
the Error, leaving the existing chalk/red message text intact for the thrown
error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/api-client/api-client.ts`:
- Around line 2447-2453: The two methods createDatasourceJsonLayouts and
recreateDatasourceJsonLayouts currently call this.request and ignore the API
envelope, so they treat a 200 with {ok:false} as success; change each to capture
the response (e.g. const res = await this.request(...)) and validate res.ok ===
true, throwing an Error (including res.error or res.message if present) when ok
is false so failures are surfaced instead of swallowed.

In `@src/commands/datasources/index.ts`:
- Around line 209-216: The recreate guard currently calls process.exit(1) when
options.yes is false which bypasses the withErrorHandling/handleCommandError
path; instead, throw a descriptive Error (e.g., new Error with the same message)
from the block that checks options.yes so the error bubbles up to
withErrorHandling/handleCommandError for consistent logging and exit handling;
update the block surrounding the options.yes check (the recreate logic in the
command handler) to remove process.exit(1) and throw the Error, leaving the
existing chalk/red message text intact for the thrown error.

In `@src/core/datasources/datasources.test.ts`:
- Around line 20-37: The shared mockClient in the describe('datasources', ...)
block is reused across tests so call histories and implementations can leak; add
a test hook to reset mocks between specs—for example add beforeEach(() =>
Object.values(mockClient).forEach(fn => fn.mockReset())) or use Vitest's
vi.resetAllMocks()/vi.clearAllMocks() in beforeEach/afterEach—apply the same
change for the other mock block around lines with the second mockClient (the
132-165 region) so all mock functions (e.g., listDatasources, getDatasource,
createDatasource, etc.) are reset before each test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e65ad684-075c-4fb7-bf71-7f7d89772a97

📥 Commits

Reviewing files that changed from the base of the PR and between 957789b and fda1172.

📒 Files selected for processing (5)
  • src/api-client/api-client.ts
  • src/commands/datasources/datasources.test.ts
  • src/commands/datasources/index.ts
  • src/core/datasources/datasources.test.ts
  • src/core/datasources/datasources.ts

@joalves joalves merged commit 7867bfa into main May 11, 2026
5 checks passed
@joalves joalves deleted the feat/FT-1918/datasource-commands branch May 12, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant