refactor: share feature flag contract across backend and web
This commit is contained in:
parent
d99cb94d19
commit
5bba149a7b
@ -48,6 +48,7 @@ import {
|
||||
canonicalLifecycleService,
|
||||
type CanonicalLifecycleProfileMeta
|
||||
} from './canonicalLifecycleService.js';
|
||||
import type { TradingFeatureFlagsResponse } from '../../../shared/feature-flags.js';
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
authUserId?: string;
|
||||
@ -1645,14 +1646,15 @@ export class ApiServer {
|
||||
});
|
||||
|
||||
this.app.get('/api/feature-flags', this.requireAuth, (_req, res) => {
|
||||
res.json({
|
||||
const flags: TradingFeatureFlagsResponse = {
|
||||
backtest: {
|
||||
enableBacktest: Boolean(config.ENABLE_BACKTEST),
|
||||
customerEnabled: Boolean(config.BACKTEST_CUSTOMER_ENABLED),
|
||||
maxCsvBytes: Number(config.BACKTEST_MAX_CSV_BYTES),
|
||||
maxRows: Number(config.BACKTEST_MAX_ROWS),
|
||||
}
|
||||
});
|
||||
};
|
||||
res.json(flags);
|
||||
});
|
||||
|
||||
this.app.get('/api/me/profile', this.requireAuth, async (req, res) => {
|
||||
|
||||
@ -4,16 +4,17 @@
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"rootDir": "..",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../shared/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"src/test_*"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,6 +228,7 @@ Manual mobile release smoke is still required before broad rollout:
|
||||
- web now uses platform-session handling end to end; the remaining auth cleanup is removing dormant compatibility stubs and aligning profile bootstrap contracts fully with backend-owned product APIs
|
||||
- root `pnpm verify` is green again after aligning the web Vitest harness with platform-session storage and current API contracts
|
||||
- mobile does not yet include push notification infrastructure
|
||||
- feature-flag ownership and exchange/order-level correlation-ID propagation are not fully standardized yet
|
||||
- broader feature-flag ownership beyond the current shared backtest contract is not fully standardized yet
|
||||
- exchange/order-level correlation-ID propagation is not fully standardized yet
|
||||
|
||||
These are follow-up items, not hidden defects. They should remain tracked in `docs/ROADMAP.md`.
|
||||
|
||||
@ -42,6 +42,7 @@ It assumes:
|
||||
- [x] Release smoke coverage now exists for web auth and product accessibility flows, with a tracked mobile release smoke checklist in operations
|
||||
- [x] Request ID propagation is now standardized across the main web/mobile API paths, operator actions, lifecycle fetches, and backend HTTP responses
|
||||
- [x] Backtest feature access now reads from an explicit backend feature-flags contract instead of scraping generic runtime config
|
||||
- [x] Feature-flag key ownership and response shape for backtest are now shared across backend and web through a common product contract
|
||||
- [x] Trading user profiles and marketplace presets now have Cosmos-backed authority paths
|
||||
- [x] Runtime order, trade-history, manual-entry, order-activity, and reconciliation-audit repositories now use Cosmos-backed trading-record storage instead of the legacy service layer
|
||||
- [x] Runtime sub-tag repair now operates through the Cosmos-backed order repository
|
||||
|
||||
15
shared/feature-flags.ts
Normal file
15
shared/feature-flags.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export const BACKTEST_FLAG_KEYS = {
|
||||
ENABLE_BACKTEST: 'ENABLE_BACKTEST',
|
||||
BACKTEST_CUSTOMER_ENABLED: 'BACKTEST_CUSTOMER_ENABLED',
|
||||
} as const;
|
||||
|
||||
export interface BacktestFeatureFlags {
|
||||
enableBacktest: boolean;
|
||||
customerEnabled: boolean;
|
||||
maxCsvBytes?: number;
|
||||
maxRows?: number;
|
||||
}
|
||||
|
||||
export interface TradingFeatureFlagsResponse {
|
||||
backtest: BacktestFeatureFlags;
|
||||
}
|
||||
@ -1,10 +1,11 @@
|
||||
import { getPlatformAccessToken } from '../lib/authSession';
|
||||
import { tradingRuntime } from '../lib/runtime';
|
||||
import { createRequestId } from '../../../shared/request-id.js';
|
||||
import type { TradingFeatureFlagsResponse } from '../../../shared/feature-flags.js';
|
||||
|
||||
export interface BacktestRuntimeFlags {
|
||||
enableBacktest: boolean;
|
||||
customerEnabled: boolean;
|
||||
enableBacktest: boolean;
|
||||
customerEnabled: boolean;
|
||||
}
|
||||
|
||||
const CACHE_TTL_MS = 15_000;
|
||||
@ -64,7 +65,7 @@ export const loadBacktestRuntimeFlags = async (): Promise<BacktestRuntimeFlags>
|
||||
throw new Error(`Failed to fetch feature flags (${response.status})`);
|
||||
}
|
||||
|
||||
const body = await response.json().catch(() => ({} as any));
|
||||
const body = await response.json().catch(() => ({} as TradingFeatureFlagsResponse));
|
||||
const loaded: BacktestRuntimeFlags = {
|
||||
enableBacktest: toBoolean(body?.backtest?.enableBacktest, false),
|
||||
customerEnabled: toBoolean(body?.backtest?.customerEnabled, false)
|
||||
|
||||
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { AlertCircle, CheckCircle2, LayoutDashboard, Info, Zap, Key, ShieldAlert } from 'lucide-react';
|
||||
import { clearBacktestRuntimeFlagCache } from '../backtest/flags';
|
||||
import { fetchDynamicConfigItems, upsertDynamicConfigItems } from '../lib/dynamicConfigApi';
|
||||
import { BACKTEST_FLAG_KEYS } from '../../../shared/feature-flags.js';
|
||||
|
||||
interface ConfigItem {
|
||||
key: string;
|
||||
@ -14,11 +15,6 @@ interface BacktestFlagState {
|
||||
customerEnabled: boolean;
|
||||
}
|
||||
|
||||
const BACKTEST_FLAG_KEYS = {
|
||||
ENABLE_BACKTEST: 'ENABLE_BACKTEST',
|
||||
BACKTEST_CUSTOMER_ENABLED: 'BACKTEST_CUSTOMER_ENABLED'
|
||||
} as const;
|
||||
|
||||
const readBooleanConfig = (configs: ConfigItem[], key: string, fallback: boolean = false): boolean => {
|
||||
const row = configs.find((item) => item.key === key);
|
||||
if (!row) return fallback;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user