Skip to content

Cross-repository intelligence does not detect dynamic BFF-to-backend connections #2291

Description

@xzbnm

Version

0.11.1

Platform

Windows (x64)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

Below is a complete GitHub issue draft you can submit to the project maintainers.


Cross-repository intelligence does not detect dynamic BFF-to-backend connections

Summary

The cross-repository intelligence indexer successfully indexes each repository individually, but it fails to detect real HTTP/API relationships between our frontend applications and the backend service.

Our projects are connected in production through Next.js BFF/proxy routes and environment-based backend URLs. The indexer reports zero cross-repository HTTP or async edges even though the source code clearly contains frontend-to-backend calls.

Repositories

The repositories are organized as:

F:/projects/sites/BM/
├── Admin/
│   └── bm-admin-nextjs/
├── Backend/
│   └── backend-bm/
└── Enduser/
    └── bm-enduser/

Projects indexed as:

bm-admin
bm-backend
bm-enduser

Relevant architecture

Admin Next.js frontend
        │
        ▼
Admin Next.js BFF routes
/api/backend/*
        │
        ▼
Backend NestJS API
Enduser Next.js frontend
        │
        ▼
Enduser Next.js API routes
        │
        ▼
Backend NestJS API via BACKEND_URL

Example: Admin → Backend

The Admin frontend calls an internal BFF endpoint:

F:/projects/sites/BM/Admin/bm-admin-nextjs/src/app/(admin)/certification/page.tsx
const res = await fetch(`/api/backend/${path}`, {
  ...init,
  cache: 'no-store',
});

The BFF proxy then forwards the request to the backend:

F:/projects/sites/BM/Admin/bm-admin-nextjs/src/app/api/backend/[...path]/route.ts
const target = `${BACKEND_URL}/${path.join('/')}${search}`;

const res = await fetch(target, {
  method,
  headers,
  body: hasBody ? await request.text() : undefined,
});

BACKEND_URL is configured through the environment and is not statically resolved by the indexer.

Example: Enduser → Backend

The Enduser application makes backend calls using a dynamic environment variable:

F:/projects/sites/BM/Enduser/bm-enduser/src/app/api/wallet/topup/zibal/route.ts
const response = await fetch(
  `${process.env.BACKEND_URL}/wallet/topup/zibal`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify(body),
  },
);

Additional examples include:

src/app/api/wallet/me/route.ts
src/app/api/trades/list/route.ts
src/app/api/trades/[id]/route.ts
src/app/api/tickets/route.ts
src/app/api/experts/route.ts
src/app/api/expert-slots/route.ts
src/app/api/live/dashboard/route.ts
src/app/api/signals/channels/[id]/route.ts

All of these use the same pattern:

fetch(`${process.env.BACKEND_URL}/...`)

Backend controllers

The backend contains NestJS controllers corresponding to these routes, for example:

F:/projects/sites/BM/Backend/backend-bm/src/features/admin/admin.controller.ts
F:/projects/sites/BM/Backend/backend-bm/src/core/auth/auth.controller.ts
F:/projects/sites/BM/Backend/backend-bm/src/features/ticketing/ticketing.controller.ts
F:/projects/sites/BM/Backend/backend-bm/src/features/certification/certification.controller.ts
F:/projects/sites/BM/Backend/backend-bm/src/features/wallet/wallet.controller.ts

The backend uses decorator-based route definitions such as:

@Controller('admin')
@Controller('auth')
@Controller('tickets')
@Controller('certification')
@Controller('wallet')

However, these NestJS controller decorators are not being matched against the frontend request paths.

Indexing results

Individual indexing succeeds:

bm-admin:
  nodes: 1017
  edges: 3561
  status: ready

bm-backend:
  nodes: 3627
  edges: 12565
  status: ready

bm-enduser:
  nodes: 1322
  edges: 4291
  status: ready

The cross-repository scan was executed against all indexed projects:

{
  "project": "bm-admin",
  "mode": "cross-repo-intelligence",
  "projects_scanned": 11,
  "cross_http_calls": 0,
  "cross_async_calls": 0,
  "total_cross_edges": 0
}
{
  "project": "bm-backend",
  "mode": "cross-repo-intelligence",
  "projects_scanned": 11,
  "cross_http_calls": 0,
  "cross_async_calls": 0,
  "total_cross_edges": 0
}
{
  "project": "bm-enduser",
  "mode": "cross-repo-intelligence",
  "projects_scanned": 11,
  "cross_http_calls": 0,
  "cross_async_calls": 0,
  "total_cross_edges": 0,
  "cross_channel": 2
}

The two detected channel edges are internal Socket.IO example files inside bm-enduser; they are not connections between the three repositories.

Current graph behavior

The Admin graph detects requests such as:

/api/backend/*
/api/auth/login
/api/auth/logout
/api/auth/me

But these are represented as internal Next.js routes rather than as calls to bm-backend.

The Enduser graph detects routes such as:

/api/auth/refresh

But calls using:

${process.env.BACKEND_URL}/...

are not resolved to the bm-backend project.

The Backend graph contains controller classes and methods, but its NestJS decorators are not exposed as matchable HTTP Route nodes for cross-repository analysis.

Expected behavior

The indexer should infer and create cross-repository edges such as:

bm-admin → bm-backend
bm-enduser → bm-backend

For example:

Admin /api/backend/admin/users
    → Backend AdminController.listUsers

Enduser /api/tickets
    → Backend TicketingController.getMine

Enduser /api/auth/login
    → Backend AuthController.login

The relationship should remain detectable even when:

  • The frontend uses a Next.js BFF/proxy route.
  • The backend URL is provided through process.env.BACKEND_URL.
  • The request URL is constructed using a template literal.
  • The backend uses NestJS @Controller() and HTTP method decorators.
  • The frontend route and backend route exist in different repositories.

Suggested implementation

Possible improvements:

  1. Resolve environment-backed base URLs using project configuration metadata.

  2. Treat BACKEND_URL, API_URL, and similar variables as service references.

  3. Follow Next.js catch-all BFF routes such as:

    app/api/backend/[...path]/route.ts
    
  4. Extract the forwarded path from expressions such as:

    `${BACKEND_URL}/${path.join('/')}`
  5. Parse NestJS decorators into Route nodes:

    @Controller('admin')
    @Get('users')
    @Post('login')
  6. Normalize route prefixes and dynamic parameters:

    /users/:id
    /users/{id}
    /users/[id]
    
  7. Create CROSS_HTTP_CALLS edges between frontend/BFF requests and backend controller routes.

  8. Add diagnostic output showing why a potential cross-repository call could not be resolved.

Additional diagnostic output requested

For unresolved calls, the indexer could report something like:

Unresolved cross-repository HTTP call

Source project: bm-enduser
Source file: src/app/api/tickets/route.ts
Expression: ${process.env.BACKEND_URL}/tickets/mine
Base URL variable: BACKEND_URL
Candidate target projects:
  - bm-backend
Reason:
  - Environment variable value unavailable
  - No matching backend Route node found
Suggested action:
  - Configure BACKEND_URL mapping or enable NestJS decorator route extraction

This would make it clear whether the problem is caused by:

  • Missing environment configuration.
  • Unsupported framework syntax.
  • Missing route extraction.
  • Route normalization mismatch.
  • Unresolved dynamic string construction.

Impact

Without these cross-repository edges:

  • Architecture diagrams are incomplete.
  • Impact analysis cannot identify frontend consumers of backend endpoints.
  • API changes in bm-backend do not show affected Admin or Enduser code.
  • Call-chain and dependency analysis misses the most important service boundaries.
  • The graph reports false isolation between applications that are actually tightly coupled.

Environment

OS: Windows
Workspace root: F:/projects/sites/BM
Indexer mode: full
Cross-repository mode: cross-repo-intelligence
Projects:
  bm-admin
  bm-backend
  bm-enduser

Acceptance criteria

This issue can be considered fixed when the indexer can:

  • Detect at least one bm-admin → bm-backend HTTP edge.
  • Detect at least one bm-enduser → bm-backend HTTP edge.
  • Resolve environment-based backend URLs through configured mappings.
  • Parse NestJS controller decorators into matchable routes.
  • Follow Next.js BFF/proxy routes.
  • Preserve these relationships after normal incremental re-indexing.
  • Provide diagnostics for unresolved dynamic requests.

Reproduction

.

Logs


Diagnostics trajectory (memory / performance / leak issues)


Project scale (if relevant)

No response

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingparsing/qualityGraph extraction bugs, false positives, missing edgesux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions