Skip to content

Commit ffa0130

Browse files
committed
fix: restore execute endpoints, fix API paths, and use relative URLs
- Re-add get_current_user dependency to execute_single_request and execute_test_suite (their bodies reference user.id for history saving) - Fix ApiKeysPage: use /api/v1/api-keys instead of /api-keys (was returning SPA HTML instead of JSON) - Fix ImportExportPage: use /api/v1/ prefix for collections, import, and export endpoints - Add Array.isArray guards for API responses in ApiKeysPage and ImportExportPage - Set VITE_API_URL to empty in .env.production so the SPA uses relative URLs (same-origin) instead of hardcoded Azure URL
1 parent b261f1b commit ffa0130

4 files changed

Lines changed: 15 additions & 10 deletions

File tree

frontend/.env.production

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
# Production Backend URL (Azure App Service)
2-
VITE_API_URL=https://apiwatch-shivamkumar.azurewebsites.net
1+
# Production Backend URL
2+
# When deployed, the SPA is served by the same FastAPI backend,
3+
# so an empty VITE_API_URL uses relative URLs (same-origin).
4+
VITE_API_URL=

frontend/src/pages/ApiKeysPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export default function ApiKeysPage() {
3131
const fetchKeys = useCallback(async () => {
3232
try {
3333
setLoading(true);
34-
const res = await api.get('/api-keys');
35-
setKeys(res.data);
34+
const res = await api.get('/api/v1/api-keys');
35+
setKeys(Array.isArray(res.data) ? res.data : []);
3636
} catch {
3737
// silently handle
3838
} finally {
@@ -53,7 +53,7 @@ export default function ApiKeysPage() {
5353
d.setDate(d.getDate() + expiresInDays);
5454
payload.expires_at = d.toISOString();
5555
}
56-
const res = await api.post('/api-keys', payload);
56+
const res = await api.post('/api/v1/api-keys', payload);
5757
setNewKeyValue(res.data.raw_key);
5858
setName('');
5959
setScopes(['read', 'write']);
@@ -68,7 +68,7 @@ export default function ApiKeysPage() {
6868
const handleRevoke = async (id: string) => {
6969
if (!confirm('Revoke this API key? This cannot be undone.')) return;
7070
try {
71-
await api.delete(`/api-keys/${id}`);
71+
await api.delete(`/api/v1/api-keys/${id}`);
7272
fetchKeys();
7373
} catch {
7474
// silently handle

frontend/src/pages/ImportExportPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export default function ImportExportPage() {
3131
const fetchCollections = useCallback(async () => {
3232
try {
3333
setLoading(true);
34-
const res = await api.get('/collections');
35-
setCollections(res.data);
34+
const res = await api.get('/api/v1/collections');
35+
setCollections(Array.isArray(res.data) ? res.data : []);
3636
} catch {
3737
// silently handle
3838
} finally {
@@ -53,7 +53,7 @@ export default function ImportExportPage() {
5353
setImportResult(null);
5454
const formData = new FormData();
5555
formData.append('file', file);
56-
await api.post('/import-export/import/postman', formData, {
56+
await api.post('/api/v1/import-export/import/postman', formData, {
5757
headers: { 'Content-Type': 'multipart/form-data' },
5858
});
5959
setImportResult({ success: true, message: `Successfully imported "${file.name}"` });
@@ -69,7 +69,7 @@ export default function ImportExportPage() {
6969
const handleExport = async (collectionId: string, format: 'postman' | 'openapi') => {
7070
try {
7171
setExporting(`${collectionId}-${format}`);
72-
const res = await api.get(`/import-export/export/${format}/${collectionId}`);
72+
const res = await api.get(`/api/v1/import-export/export/${format}/${collectionId}`);
7373
const blob = new Blob([JSON.stringify(res.data, null, 2)], { type: 'application/json' });
7474
const url = URL.createObjectURL(blob);
7575
const a = document.createElement('a');

src/api_server.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from src.diagnose import DiagnosisEngine
3030
from src.database import init_db, close_db, get_db, check_db_health
3131
from src.models import RequestHistory
32+
from src.jwt_auth import get_current_user
3233
from src.routes import api_v1_router, mock_catch_router
3334
from src.rate_limit import RateLimitMiddleware, RateLimitConfig
3435
from src.cache import get_cache, close_cache
@@ -300,6 +301,7 @@ async def health_check():
300301
async def execute_single_request(
301302
request_input: RequestConfigInput,
302303
db: AsyncSession = Depends(get_db),
304+
user = Depends(get_current_user),
303305
):
304306
"""Execute a single API request (async via httpx)."""
305307
try:
@@ -366,6 +368,7 @@ async def execute_single_request(
366368
async def execute_test_suite(
367369
suite_input: TestSuiteInput,
368370
db: AsyncSession = Depends(get_db),
371+
user = Depends(get_current_user),
369372
) -> List[RequestResult]:
370373
"""Execute a test suite (async via httpx)."""
371374
try:

0 commit comments

Comments
 (0)