Skip to content

Fix CI: resolve unmerged conflicts across the backend + fix a hidden route collision - #109

Open
prodbycorne wants to merge 1 commit into
mainfrom
fix/ci-merge-corruption-backend
Open

Fix CI: resolve unmerged conflicts across the backend + fix a hidden route collision#109
prodbycorne wants to merge 1 commit into
mainfrom
fix/ci-merge-corruption-backend

Conversation

@prodbycorne

Copy link
Copy Markdown
Contributor

Summary

main's CI has been failing on every run — several previously-merged PRs left their merge conflicts concatenated instead of resolved. This surfaced as a long chain of failures:

  • package.json / package-lock.json: duplicate keys and a dropped closing brace → npm ci failed immediately (EJSONPARSE / EUSAGE).
  • src/index.js: three conflicting "start/stop the server" implementations spliced together (duplicate server declarations, a hard syntax error). Reconciled into the one async startServer()/shutdown() design, folding indexerPoller back into it — it's still used by src/routes/indexer.js but had been dropped from the lifecycle code by the bad merge.
  • src/routes/airdrops.js: misplaced require()s stuck mid-function, a duplicate router/upload/validator, a dead broken validateAirdropCreate() left over from a since-superseded manual validator, and two POST routes each registered twice with different middleware — merged into one registration per route using every needed middleware.
  • src/services/priceOracle.js: SOURCES had 6 entries instead of 3 — two competing circuit-breaker designs for the same 3 sources merged side by side instead of combined. Fixed to 3 entries carrying both the generic CircuitBreaker (used for fetch-with-failover) and the per-source getCircuitState (used by /health's price_source_circuits).
  • src/config.js: duplicate databaseUrl / stellar.* keys where a raw process.env fallback silently overrode the envalid-validated value (JS object literals: last key wins).
  • Several test files (auth, alerts-routes, circuitBreaker, health, prices, airdrops): duplicate mock methods, orphan fragments, or two entire test files concatenated together — fixed by keeping whichever version matches current source behavior and removing the dead duplicate.

A real bug found once the suite could finally run

src/routes/indexer.js registered GET /airdrops/:id/recipients — the exact same path as the airdrops CRUD API's paginated recipients endpoint in src/routes/airdrops.js. Since indexerRouter is mounted before airdropsRouter in src/index.js, it silently shadowed the real endpoint: the paginated off-chain recipients list has never actually been reachable through the deployed app. Renamed the indexer's endpoint to GET /airdrops/:id/onchain-recipients (it serves indexed on-chain claim data, a different concern from the off-chain uploaded recipient list) and updated its test to match.

Test plan

  • npm ci — succeeds (was failing with EJSONPARSE)
  • npx @redocly/cli lint openapi.yaml — valid
  • npm test — 337/337 passing across 37 suites (was 9 suites failing / 33 tests failing)

These are the exact steps .github/workflows/ci.yml's test job runs. (docker-build job not verifiable locally — no Docker available in this environment — but the Dockerfile and package.json/lockfile it depends on are unchanged in shape beyond this fix.)

main was left in a broken state where several PRs' merge conflicts were
concatenated instead of resolved, breaking every CI run:

- package.json / package-lock.json had duplicate keys and a dropped closing
  brace, so `npm ci` failed with EJSONPARSE / EUSAGE.
- src/index.js had three conflicting "how do we start/stop the server"
  implementations spliced together (duplicate `server` declarations, a
  syntax error), reconciled into one: the async startServer()/shutdown()
  design, with indexerPoller folded back in since it was dropped from that
  path by the bad merge but is still used elsewhere.
- src/routes/airdrops.js had misplaced requires stuck mid-function, a
  duplicate router/upload/validateWithCurrentLedger, a dead broken
  validateAirdropCreate() left over from a since-superseded manual
  validator, and two POST routes each registered twice with different
  middleware (merged into one registration using every needed middleware).
- src/services/priceOracle.js's SOURCES array had 6 entries instead of 3
  (two competing circuit-breaker designs for the same 3 sources); merged
  into 3 entries carrying both the generic CircuitBreaker used for
  fetch-with-failover and the per-source getCircuitState used by the
  /health endpoint's price_source_circuits.
- src/config.js had duplicate databaseUrl/stellar.* keys where a raw
  process.env fallback silently overrode the envalid-validated value.
- Several test files (test/auth.test.js, test/alerts-routes.test.js,
  test/circuitBreaker.test.js, test/health.test.js, test/prices.test.js,
  test/airdrops.test.js) had the same pattern: duplicate mock methods,
  orphan fragments, or two whole test files concatenated together, fixed by
  keeping the version that matches current source behavior and removing
  dead duplicates.

Also found and fixed a real, independent routing bug surfaced once the
suite could finally run: src/routes/indexer.js registered
`GET /airdrops/:id/recipients`, the exact same path as the airdrops CRUD
API's paginated recipients endpoint. Since indexerRouter is mounted first,
it silently shadowed the real endpoint in the full app — the paginated
recipients list was unreachable in production. Renamed the indexer's
route to `GET /airdrops/:id/onchain-recipients` (updated its test to
match) since it serves indexed on-chain claim data, a different concern
from the off-chain uploaded recipient list.

npm ci, `npx @redocly/cli lint openapi.yaml`, and `npm test` (337 tests
across 37 suites) all pass locally, matching CI's exact steps.
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