Skip to content

bug: /api/v1/* routes return 404 — v1Router is defined but never mounted in Express app #9

Description

@Uchechukwu-Ekezie

Description

The README and API documentation state that /api/v1/ is the canonical API namespace and /api/ is the legacy namespace scheduled for deprecation. However, v1Router is imported but never mounted in backend/src/index.ts. All /api/v1/* requests return 404 Route not found.

Steps to Reproduce

# Start the backend
npm run dev --prefix backend

# Try the documented canonical endpoint
curl http://localhost:3001/api/v1/portfolio/GABC...
# Returns: {"success": false, "error": "Route not found"}  ✗

# The legacy endpoint works fine
curl http://localhost:3001/api/portfolio/GABC...
# Returns: {"success": true, "portfolio": {...}}  ✓

Root Cause

backend/src/api/v1Router.ts (entire file):

import { Router } from 'express'
import { portfolioRouter } from './routes'

const v1Router = Router()
v1Router.use('/', portfolioRouter)

export { v1Router }

backend/src/index.ts:

import { portfolioRouter } from './api/routes'
// v1Router is NOT imported

app.use('/api', portfolioRouter)   // ← Legacy namespace mounted ✓
app.use('/', portfolioRouter)      // ← Root namespace mounted
// app.use('/api/v1', v1Router)    ← This line is missing ✗

v1Router exists as a module but is never imported or registered with the Express app.

README Documentation (Contradicts Actual Behavior)

From README.md (~line 170):

Canonical API namespace: /api/v1/*
Legacy compatibility namespace (deprecated, temporary): /api/*

This is the opposite of reality — /api/* works and /api/v1/* does not.

Impact

  1. Any client or integration built against /api/v1/ (as the README instructs) receives 404 for every request
  2. The documented deprecation path is inverted — the "legacy" namespace is the only one that functions
  3. There is no migration path for consumers to upgrade to v1, because v1 doesn't exist

Proposed Fix

Option A (Recommended): Mount v1Router in index.ts

// backend/src/index.ts
import { portfolioRouter } from './api/routes'
import { v1Router } from './api/v1Router'

// Mount canonical v1 namespace
app.use('/api/v1', v1Router)

// Mount legacy namespace with deprecation header middleware
app.use('/api', legacyApiDeprecation, portfolioRouter)

This makes both namespaces functional and allows a real deprecation timeline for /api/*.

Option B: Remove v1Router and update documentation

If versioned routing is not planned, delete v1Router.ts, remove references to /api/v1/ from all documentation, and update README to reflect that /api/ is the current and only namespace.

Verify the fix

curl http://localhost:3001/api/v1/portfolio/GABC...
# Should return: {"success": true, "portfolio": {...}}

Files Affected

  • backend/src/index.ts — add app.use('/api/v1', v1Router) import and mount
  • backend/src/api/v1Router.ts — no change needed (already correct)
  • README.md — update or remove /api/v1/ references until fix is deployed
  • docs/API.md — clarify which namespace is currently active

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official Campaign

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions