Skip to content

Commit 72d84f4

Browse files
feat: Add Next.js API proxy routes for portfolio and stock endpoints
- Add /api/portfolio/default route for portfolio data - Add /api/portfolio/default/allocation route for allocation breakdown - Add /api/stock/prices route for batch stock price fetching - Remove old /api/stock/route.ts in favor of new batch endpoint - All routes proxy to .NET Core backend with proper error handling
1 parent 7bc5419 commit 72d84f4

File tree

4 files changed

+119
-52
lines changed

4 files changed

+119
-52
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { NextResponse } from 'next/server';
2+
3+
const DOTNET_API_URL = process.env.DOTNET_API_URL || 'http://localhost:5245/api';
4+
5+
export async function GET() {
6+
try {
7+
const response = await fetch(`${DOTNET_API_URL}/portfolio/default/allocation`, {
8+
method: 'GET',
9+
headers: {
10+
'Content-Type': 'application/json',
11+
},
12+
});
13+
14+
if (!response.ok) {
15+
console.error(`Failed to fetch allocation breakdown: ${response.status} ${response.statusText}`);
16+
return NextResponse.json(
17+
{ error: `Failed to fetch allocation breakdown` },
18+
{ status: response.status }
19+
);
20+
}
21+
22+
const allocationData = await response.json();
23+
return NextResponse.json(allocationData);
24+
} catch (error) {
25+
console.error('Error fetching allocation breakdown:', error);
26+
return NextResponse.json(
27+
{ error: 'Internal server error' },
28+
{ status: 500 }
29+
);
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { NextResponse } from 'next/server';
2+
3+
const DOTNET_API_URL = process.env.DOTNET_API_URL || 'http://localhost:5245/api';
4+
5+
export async function GET() {
6+
try {
7+
const response = await fetch(`${DOTNET_API_URL}/portfolio/default`, {
8+
method: 'GET',
9+
headers: {
10+
'Content-Type': 'application/json',
11+
},
12+
});
13+
14+
if (!response.ok) {
15+
console.error(`Failed to fetch default portfolio: ${response.status} ${response.statusText}`);
16+
return NextResponse.json(
17+
{ error: `Failed to fetch default portfolio` },
18+
{ status: response.status }
19+
);
20+
}
21+
22+
const portfolioData = await response.json();
23+
return NextResponse.json(portfolioData);
24+
} catch (error) {
25+
console.error('Error fetching default portfolio:', error);
26+
return NextResponse.json(
27+
{ error: 'Internal server error' },
28+
{ status: 500 }
29+
);
30+
}
31+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { NextResponse } from 'next/server';
2+
3+
const DOTNET_API_URL = process.env.DOTNET_API_URL || 'http://localhost:5245/api';
4+
5+
export async function POST(request: Request) {
6+
try {
7+
const body = await request.json();
8+
9+
if (!body.symbols || !Array.isArray(body.symbols) || body.symbols.length === 0) {
10+
return NextResponse.json(
11+
{ error: 'Symbols array is required and cannot be empty' },
12+
{ status: 400 }
13+
);
14+
}
15+
16+
const response = await fetch(`${DOTNET_API_URL}/stock/prices`, {
17+
method: 'POST',
18+
headers: {
19+
'Content-Type': 'application/json',
20+
},
21+
body: JSON.stringify({ symbols: body.symbols }),
22+
});
23+
24+
if (!response.ok) {
25+
console.error(`Failed to fetch stock prices: ${response.status} ${response.statusText}`);
26+
27+
// Handle specific error cases
28+
if (response.status === 400) {
29+
const errorData = await response.json().catch(() => ({}));
30+
if (errorData.error === 'API_CREDENTIALS_MISSING') {
31+
console.error('Alpaca API credentials missing:', errorData.message);
32+
return NextResponse.json(
33+
{
34+
error: 'API_CREDENTIALS_MISSING',
35+
message: errorData.message || 'Alpaca API credentials are not configured. Please add your API keys to the backend configuration.'
36+
},
37+
{ status: 400 }
38+
);
39+
}
40+
}
41+
42+
return NextResponse.json(
43+
{ error: `Failed to fetch stock prices` },
44+
{ status: response.status }
45+
);
46+
}
47+
48+
const pricesData = await response.json();
49+
return NextResponse.json(pricesData);
50+
} catch (error) {
51+
console.error('Error fetching stock prices:', error);
52+
return NextResponse.json(
53+
{ error: 'Internal server error' },
54+
{ status: 500 }
55+
);
56+
}
57+
}

frontend/src/app/api/stock/route.ts

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)