Skip to content

Fetcher integration: all API paths, DTOs, headers, and mock are misaligned with real Fetcher contract #104

@gandalf-at-lerian

Description

@gandalf-at-lerian

Summary

The Matcher's Fetcher HTTP client (internal/discovery/adapters/fetcher/client.go + types.go) is 100% misaligned with the real Fetcher API. 5 of 6 routes return 404, required headers are never sent, and DTOs silently parse into empty/wrong values. E2E tests pass because the mock (tests/e2e/mock/fetcher_server.go) mirrors the Matcher's expectations, not the real Fetcher.

Route mismatches (all return 404 in prod)

Matcher calls Fetcher actual
GET /api/v1/connections GET /v1/management/connections
GET /api/v1/connections/{id}/schema GET /v1/management/connections/:id/schema
POST /api/v1/connections/{id}/test POST /v1/management/connections/:id/test
POST /api/v1/extractions POST /v1/fetcher
GET /api/v1/extractions/{jobId} GET /v1/fetcher/:id

Only GET /health is correct.

Missing headers

  • X-Organization-Id (required on ALL protected routes) — never sent
  • X-Product-Name (required on CreateConnection, optional on List) — never sent
  • The ?orgId= query param sent in ListConnections is ignored by the Fetcher

DTO mismatches

ListConnections

Fetcher returns {"items": [...], "page", "limit", "total"} (Pagination). Matcher expects {"connections": [...]}. Result: always empty list.

ConnectionResponse

Matcher reads databaseType → Fetcher sends type. Field always empty.

TestConnection

Fetcher returns {status (string), message, latencyMs}. Matcher expects {connectionId, healthy (bool), latencyMs, errorMessage}. The validateFetcherResourceID check always fails because connectionId is absent.

Schema

Fetcher returns id (not connectionId), tables use name (not tableName), columns are fields []string (not columns []{name,type,nullable}). ID validation always fails.

Extraction submit

Completely different contracts. Matcher sends {connectionId, tables}. Fetcher expects {dataRequest: {mappedFields: {datasource: {table: [fields]}}}}.

Extraction status

Fetcher returns id (not jobId). Status values differ: Fetcher uses processing/completed (lowercase), Matcher expects RUNNING/COMPLETE.

Health check

Fetcher returns plain text "healthy". Matcher tries JSON parse {"status": "healthy"} → always fails → IsHealthy() = false.

Mock vs Real Fetcher

The mock server (tests/e2e/mock/fetcher_server.go) uses the same wrong routes and wrong DTOs as the client. Tests are green but prod is 100% broken.

Files to fix

  1. internal/discovery/adapters/fetcher/client.go — routes, headers, request building
  2. internal/discovery/adapters/fetcher/types.go — all DTOs
  3. internal/discovery/adapters/fetcher/config.go — health check plain text handling
  4. tests/e2e/mock/fetcher_server.go — align with real Fetcher contract

Context

Found during Console ↔ Matcher ↔ Fetcher integration work by @augustoalvarenga.

Full field-by-field audit report available on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions