Closes #ISSUE-009 - Implement DEV_MODE Offline-First Protection Shield

This commit is contained in:
Antigravity Agent
2026-06-12 20:50:10 +02:00
parent ef4edd97a6
commit 6e4dd29d1d
5 changed files with 112 additions and 38 deletions

View File

@@ -134,9 +134,10 @@ async function fetchFmpData(ticker: string, apiKey: string): Promise<any> {
export async function GET() {
const apiKey = process.env.FMP_API_KEY;
const now = Date.now();
const isDevMode = process.env.DEV_MODE === 'true';
// Return cached result if valid
if (cache && (now - cache.timestamp < CACHE_TTL)) {
// Return cached result if valid (unless in DEV_MODE)
if (!isDevMode && cache && (now - cache.timestamp < CACHE_TTL)) {
return NextResponse.json(cache.data, {
status: 200,
headers: { 'Cache-Control': 'public, max-age=3600' }
@@ -147,7 +148,9 @@ export async function GET() {
// Deep clone fallback data
const companyData: CompanyData[] = JSON.parse(JSON.stringify(MOCK_TECH_AI_DATA));
if (apiKey) {
if (isDevMode) {
// Short-circuit: completely skip outbound FMP fetches
} else if (apiKey) {
try {
// Test the API key first with a quick check
const testRes = await fetchWithTimeout(`https://financialmodelingprep.com/api/v3/income-statement/NVDA?period=quarter&limit=1&apikey=${apiKey}`);
@@ -422,6 +425,7 @@ export async function GET() {
const payload = {
dates,
liveDataAvailable,
isShieldActive: isDevMode,
timestamp: now,
metrics: {
monetizationGap: {
@@ -436,13 +440,22 @@ export async function GET() {
}
};
cache = {
timestamp: now,
data: payload
if (!isDevMode) {
cache = {
timestamp: now,
data: payload
};
}
const responseHeaders: Record<string, string> = {
'Cache-Control': isDevMode ? 'no-store, max-age=0, must-revalidate' : 'public, max-age=3600'
};
if (isDevMode) {
responseHeaders['X-Shield-Active'] = 'true';
}
return NextResponse.json(payload, {
status: 200,
headers: { 'Cache-Control': 'public, max-age=3600' }
headers: responseHeaders
});
}