Skip to content

docs(backend): add backend/docs/ARCHITECTURE.md and fix broken indexe… - #1412

Open
olu-cmd wants to merge 1 commit into
LabsCrypt:mainfrom
olu-cmd:docs_ARCHITECTURE_md
Open

docs(backend): add backend/docs/ARCHITECTURE.md and fix broken indexe…#1412
olu-cmd wants to merge 1 commit into
LabsCrypt:mainfrom
olu-cmd:docs_ARCHITECTURE_md

Conversation

@olu-cmd

@olu-cmd olu-cmd commented Aug 31, 2026

Copy link
Copy Markdown

Close #1299

Fix: Create missing backend/docs/ARCHITECTURE.md and repair broken indexer references

Description

Closes audit issue 97/100backend/src/services/indexerService.ts:11 and backend/src/services/soroban-indexer.service.ts:9-17 both referenced docs/ARCHITECTURE.md for the full indexer ownership model, but no such file existed anywhere in backend/docs/ (verified via directory listing). This was a dead link for exactly the document contributors need when investigating the known dual-indexer race (Architecture #67).

This PR creates the missing file and wires both services to it.

Root Cause

  • docs/ARCHITECTURE.md (root) exists and documents system-wide flows, but backend/docs/ARCHITECTURE.md was never created.
  • Both indexer services contained module-doc references to docs/ARCHITECTURE.md expecting a backend-local architecture doc with indexer ownership, SSE flow, and keeper-key model (Architecture Frontend: Stream Details Screen #72). backend/docs/ only contained API_VERSIONING.md, AUTHENTICATION.md, DEPRECATION_POLICY.md, SANDBOX_MODE.md, SSE_ARCHITECTURE.md, SSE_IMPLEMENTATION.md.

Solution

1. New file: backend/docs/ARCHITECTURE.md (138 lines)

Single authoritative backend architecture doc, scoped to what the audit requested:

1. Indexer Ownership (Source of Truth)

File Role Status
backend/src/workers/soroban-event-worker.ts (SorobanEventWorker) Source-of-truth poller — RPC getEvents, XDR decode, persist Stream/StreamEvent, advance IndexerState, broadcast SSE Active — authoritative, started via backend/src/workers/index.ts:16startWorkers()
backend/src/services/soroban-indexer.service.ts (SorobanIndexerService) Legacy duplicate poller, same tables @deprecated — do not extend, kept for API/test compat only. Removal tracked as Architecture #67 / issue #801
backend/src/services/indexerService.ts (barrel → indexer.service.ts) Control-plane helpers (getIndexerStatus, resetIndexer, replayFromLedger) — read/reset IndexerState singleton and trigger worker via triggerPoll() Active, misleading name to be renamed to indexer.service.ts post-consolidation

Also documents: why two indexers exist, race on IndexerState singleton, current startup model (only SorobanEventWorker started in backend/src/index.ts:32), cursor/idempotency (@@unique([transactionHash, eventType]) in backend/prisma/schema.prisma:82, ensureIndexerState() with P2002 race handling, runExclusive/batchMutex serialization), and pointer to operational runbook in SSE_ARCHITECTURE.md#operational-runbook.

2. SSE Broadcast Flow

Soroban RPC → SorobanEventWorker → PostgreSQL → SSE Service → (Redis pub/sub) → GET /events/subscribe → Browser

Indexer-driven origin (never from HTTP controllers), Redis fanout via backend/src/lib/redis.ts / psubscribe on sse:stream:* / sse:user:*, filtering in backend/src/services/sse.service.ts:182, links to SSE_ARCHITECTURE.md and SSE_IMPLEMENTATION.md.

3. Keeper-Key Authorization Model (Architecture #72)

Action Signer Key
Top-up / Cancel Server (custodial) KEEPER_SECRET_KEY via backend/src/services/sorobanService.ts:365 / backend/src/controllers/stream/cancel.ts:90
Withdraw / Pause / Resume / Create Wallet (non-custodial) Backend only simulates; real tx signed by Freighter

Documents env handling, throw when unset, scope, and that frontend must never receive KEEPER_SECRET_KEY.

All sections include file:line anchors and cross-links to docs/ARCHITECTURE.md, SSE_ARCHITECTURE.md, AUTHENTICATION.md.

2. Service reference fixes

File Change
backend/src/services/indexerService.ts:1 Added barrel module doc linking to backend/docs/ARCHITECTURE.md (Indexer Ownership) + docs/ARCHITECTURE.md
backend/src/services/soroban-indexer.service.ts:13 Expanded @deprecated JSDoc to link backend/docs/ARCHITECTURE.md (Indexer Ownership) + dual-indexer race Architecture #67
backend/src/services/indexer.service.ts:1 Added control-plane header doc linking backend/docs/ARCHITECTURE.md (Ownership, SSE, Keeper-Key) + Architecture #67

References use backend/docs/ARCHITECTURE.md (resolves inside backend/docs/) and docs/ARCHITECTURE.md (root) — both now valid.

Acceptance Criteria

How to Verify

ls backend/docs/ARCHITECTURE.md
grep -n "Indexer Ownership" backend/docs/ARCHITECTURE.md
grep -rn "ARCHITECTURE" backend/src/services/
cat backend/docs/ARCHITECTURE.md

Risk

Docs/comment-only. No runtime behavior change. Low risk.

Related

…r references

Fixes audit issue 97/100 — both indexer services referenced
docs/ARCHITECTURE.md but no such file existed in backend/docs/.
Document indexer ownership (SorobanEventWorker is authoritative,
SorobanIndexerService is deprecated legacy per Architecture LabsCrypt#67/LabsCrypt#801),
SSE broadcast flow, and keeper-key authorization model
(Architecture LabsCrypt#72), and link both services to the new doc.
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.

[Audit] docs/ARCHITECTURE.md, referenced by two services, does not exist

1 participant