Skip to content

fix(ci): repair backend startup crash and CI workflow config on main - #1091

Merged
joelpeace48-cell merged 4 commits into
mainfrom
fix/ci-eventindexer-and-pipeline
Jul 29, 2026
Merged

fix(ci): repair backend startup crash and CI workflow config on main#1091
joelpeace48-cell merged 4 commits into
mainfrom
fix/ci-eventindexer-and-pipeline

Conversation

@joelpeace48-cell

Copy link
Copy Markdown
Contributor

main has been broken since a series of bad merges landed. This fixes
every currently-failing check on main-branch CI:

  • backend/src/jobs/eventIndexer.js: a merge dropped a comment's opening
    /** and the Semaphore class's closing }, leaving doc-comment text
    as bare tokens. Node can't parse the module, so the backend crashed
    on every boot (root cause of Security Headers Check failing on every
    recent commit).
  • backend/src/index.js: two more merge artifacts — indexerRepository
    and defaultRateLimiter were referenced in the /graphql route wiring
    but never declared anywhere in scope.
  • backend/src/db/migrations/037_outbox.js: missing the required
    version/description exports, so the migration runner threw
    instead of applying it.
  • backend/src/db/migrations/038 (new): 026_notification_preferences.js
    and 026_operator_balance_log.js share version 26, so the checked-in
    trivela.db (which already has 26 recorded from whichever file ran
    first) never got notification_channel_settings created, crashing the
    notification repository at boot. Same disease as the existing 034
    backfill migration for the version-13 collision; this heals it the
    same way with a fresh version number.
  • .github/workflows/frontend-ci.yml: a bad merge dropped the
    accessibility job's steps: entirely and spliced its steps into
    cross-browser-e2e instead, producing an invalid job with no steps
    and no uses: — GitHub can't even schedule the workflow. Split the
    steps back into their own jobs.
  • .github/workflows/performance-gate.yml: actions-rs/toolchain@v1 is
    unmaintained and doesn't install the wasm32-unknown-unknown target
    that stellar-cli needs to build. Swapped for dtolnay/rust-toolchain
    with the target declared explicitly, matching the working pattern
    already used in ci-performance.yml.
  • Repo-wide prettier --write per format:check's own globs — 50 files
    had drifted since nobody had run it before committing.

Verified locally: backend now boots clean and GET /health returns 200
with every header Security Headers Check greps for; all workflow YAML
re-validated; node --check clean across backend/src.

main has been broken since a series of bad merges landed. This fixes
every currently-failing check on main-branch CI:

- backend/src/jobs/eventIndexer.js: a merge dropped a comment's opening
  `/**` and the Semaphore class's closing `}`, leaving doc-comment text
  as bare tokens. Node can't parse the module, so the backend crashed
  on every boot (root cause of Security Headers Check failing on every
  recent commit).
- backend/src/index.js: two more merge artifacts — `indexerRepository`
  and `defaultRateLimiter` were referenced in the /graphql route wiring
  but never declared anywhere in scope.
- backend/src/db/migrations/037_outbox.js: missing the required
  `version`/`description` exports, so the migration runner threw
  instead of applying it.
- backend/src/db/migrations/038 (new): 026_notification_preferences.js
  and 026_operator_balance_log.js share version 26, so the checked-in
  trivela.db (which already has 26 recorded from whichever file ran
  first) never got notification_channel_settings created, crashing the
  notification repository at boot. Same disease as the existing 034
  backfill migration for the version-13 collision; this heals it the
  same way with a fresh version number.
- .github/workflows/frontend-ci.yml: a bad merge dropped the
  `accessibility` job's `steps:` entirely and spliced its steps into
  `cross-browser-e2e` instead, producing an invalid job with no steps
  and no `uses:` — GitHub can't even schedule the workflow. Split the
  steps back into their own jobs.
- .github/workflows/performance-gate.yml: `actions-rs/toolchain@v1` is
  unmaintained and doesn't install the wasm32-unknown-unknown target
  that `stellar-cli` needs to build. Swapped for `dtolnay/rust-toolchain`
  with the target declared explicitly, matching the working pattern
  already used in ci-performance.yml.
- Repo-wide `prettier --write` per format:check's own globs — 50 files
  had drifted since nobody had run it before committing.

Verified locally: backend now boots clean and GET /health returns 200
with every header Security Headers Check greps for; all workflow YAML
re-validated; `node --check` clean across backend/src.
purged.push({ table, count: result.changes });
log.info(`[pii-purge] Deleted ${result.changes} rows from ${table} for campaign ${campaignId}`);
log.info(
`[pii-purge] Deleted ${result.changes} rows from ${table} for campaign ${campaignId}`,
Follow-up to the previous commit, after watching the PR's actual GitHub
Actions run rather than just the reduced main-branch check set:

- backend/src/jobs/eventIndexer.js: an orphaned early
  `return { processEvent, poll, pollWithCursor };` sat in the middle of
  createEventIndexer (left behind by the same merge that broke the
  header comment, from before gap-detection/reorg-safety/SSE support
  existed). It silently made every function after it — getState,
  getCursor, updateCursor, getHealth, getMetrics, startSse,
  confirmPending, detectReorg, handleReorg, and the real final return —
  dead code. None of those were ever actually reachable at runtime.
  Confirmed against the commit that authored the stray line: in that
  commit it was the correct final return; later merges added the real
  feature set after it without removing it.
- backend/src/index.js: gracefulShutdown (in startServer) assigned
  `isShuttingDown = true` directly, but that variable is local to
  createApp — a different top-level function. Since ES modules are
  strict mode, this throws ReferenceError the moment SIGTERM/SIGINT
  fires, crashing the shutdown handler instead of shutting down
  gracefully. The very next line, `app._close?.()`, already flips the
  flag correctly through createApp's own closure — removed the
  redundant broken assignment.
- backend/src/services/cacheService.js: empty `catch {}` in
  CacheService.clear() failed eslint's no-empty rule. Added a comment
  explaining it's an intentional best-effort swallow.
- .github/workflows/performance-gate.yml: the `load-test` job's
  `npm run build` step compiles the Rust contracts too, but the job
  had no Rust setup at all — same missing wasm32-unknown-unknown
  target as gas-profiling. Added the same dtolnay/rust-toolchain step.
  Separately, gas-profiling's `cargo install stellar-cli` needs
  libdbus-1-dev + pkg-config on the runner; added an apt-get step.
- frontend: `prettier --write .` — 8 .jsx files had drifted from the
  frontend workspace's own format:check globs (separate from the root
  format:check fixed previously, which doesn't cover frontend/src).

Verified: backend lint now 0 errors (was 3: no-undef, no-unreachable,
no-empty); backend still boots clean with /health returning all
security headers; SIGTERM now logs "graceful shutdown complete"
instead of crashing; frontend format:check passes; performance-gate.yml
re-validated as YAML.
- .github/workflows/monitoring-ci.yml: amtool doesn't expand \${VAR}
  references — the workflow set SLACK_WEBHOOK_URL/PAGERDUTY_SERVICE_KEY
  as step env vars assuming amtool would resolve them itself, but
  amtool check-config just reads the literal file, so it tried to
  parse the literal string "${SLACK_WEBHOOK_URL}" as a URL and failed
  with "unsupported scheme". Render a throwaway copy through envsubst
  first, then validate that. Confirmed locally: only the two intended
  placeholders get substituted, nothing else in the file changes.

- frontend/src/components/PageMeta.test.jsx: react-helmet-async commits
  its <head> tags via requestAnimationFrame, not synchronously during
  render(), so all 11 assertions were reading the pre-mount DOM and
  getting undefined. Not a component bug — PageMeta.jsx's tags are
  correct. Made renderMeta async and await one animation frame before
  asserting. Verified: all 11 tests pass, and the full frontend suite
  (36 files, 422 tests) passes clean.
sdk/client's generate script (openapi-ts) cleans its entire --output
directory before writing, and the hand-written ZK proof module
(zk/index.ts, zk/proof.worker.ts, zk/types.ts — a Web Worker and its
types, not generator output) lived inside that same directory. Running
"the fix" (regenerate + commit, which is what the CI check effectively
asks contributors to do locally) would have silently deleted real
source code. Confirmed nothing in the repo currently imports zk/, so
relocating it to sdk/client/zk/ (a sibling of the generated src/) needed
no import-path updates. Added an explicit "./zk" export in package.json
so it stays consumable at @trivela/client/zk if/when it's wired up.

With zk/ out of the way, ran the actual generate step and it reveals
real (and previously invisible) drift: backend/openapi.yaml has PII
export/purge endpoints and ApiKeyRateTier that were never regenerated
into the committed client. Committing that regenerated output — it's
mechanical, spec-driven, no hand-written logic involved.
@joelpeace48-cell
joelpeace48-cell merged commit 254a467 into main Jul 29, 2026
18 of 29 checks passed
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.

3 participants