Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/routers/detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ async def detect_abandoned_vehicle_endpoint(image: UploadFile = File(...)):
@router.post("/api/detect-emotion")
async def detect_emotion_endpoint(
image: UploadFile = File(...),
client: httpx.AsyncClient = backend.dependencies.Depends(get_http_client)
client = backend.dependencies.Depends(get_http_client)
):
Comment on lines 461 to 463
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This endpoint now declares the dependency as client = backend.dependencies.Depends(get_http_client), which drops the httpx.AsyncClient type annotation and couples the router to backend.dependencies just to access Depends. Consider importing Depends from fastapi in this module and using a forward-reference/TYPE_CHECKING import for the httpx type so you can keep the annotation without reintroducing runtime import/circular issues.

Copilot uses AI. Check for mistakes.
"""
Analyze facial emotions in the image using Hugging Face inference.
Expand Down
3 changes: 3 additions & 0 deletions frontend/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ export default {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
['@babel/preset-react', { runtime: 'automatic' }]
],
plugins: [
'babel-plugin-transform-vite-meta-env'
]
};
13 changes: 13 additions & 0 deletions frontend/netlify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Netlify Configuration for VishwaGuru Frontend

[build]
# Execute from frontend dir
publish = "dist"
command = "npm install && npm run build"
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Use npm ci instead of npm install in the Netlify build command to make deploys reproducible and less flaky.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/netlify.toml, line 6:

<comment>Use `npm ci` instead of `npm install` in the Netlify build command to make deploys reproducible and less flaky.</comment>

<file context>
@@ -0,0 +1,28 @@
+[build]
+  # Execute from frontend dir
+  publish = "dist"
+  command = "npm install && npm run build"
+
+[build.environment]
</file context>
Fix with Cubic


[build.environment]
NODE_VERSION = "20"
CI = "false"

# Environment variables (set these in Netlify dashboard)
# VITE_API_URL = https://your-backend.onrender.com
27 changes: 27 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
},
"dependencies": {
"@supabase/supabase-js": "^2.95.3",
"@vitejs/plugin-react": "^5.1.2",
"autoprefixer": "^10.4.23",
"dexie": "^4.2.1",
"framer-motion": "^12.29.2",
"i18next": "^25.8.0",
"i18next-browser-languagedetector": "^8.2.0",
"lucide-react": "^0.562.0",
"postcss": "^8.5.6",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-i18next": "^16.5.3",
"react-router-dom": "^7.12.0",
"react-webcam": "^7.2.0",
"@vitejs/plugin-react": "^5.1.2",
"autoprefixer": "^10.4.23",
"postcss": "^8.5.6",
"tailwindcss": "^3.4.1",
"vite": "^7.3.0",
"vite-plugin-pwa": "^1.2.0"
Expand All @@ -45,6 +45,8 @@
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"babel-jest": "^29.7.0",
"babel-plugin-transform-import-meta": "^2.3.3",
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

babel-plugin-transform-import-meta is added to devDependencies but is not referenced anywhere in the Jest/Babel configuration (only babel-plugin-transform-vite-meta-env is configured). Please either remove this dependency to avoid drift, or add it to frontend/babel.config.js with a clear reason/order if it’s actually required for the Jest transform.

Suggested change
"babel-plugin-transform-import-meta": "^2.3.3",

Copilot uses AI. Check for mistakes.
"babel-plugin-transform-vite-meta-env": "^1.0.3",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
Expand Down
5 changes: 5 additions & 0 deletions frontend/public/_headers
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
1 change: 1 addition & 0 deletions frontend/public/_redirects
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* /index.html 200
26 changes: 13 additions & 13 deletions frontend/src/api/__tests__/detectors.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ describe('detectorsApi', () => {
});

const detectorTestCases = [
{ name: 'pothole', endpoint: '/api/detect-pothole' },
{ name: 'garbage', endpoint: '/api/detect-garbage' },
{ name: 'vandalism', endpoint: '/api/detect-vandalism' },
{ name: 'flooding', endpoint: '/api/detect-flooding' },
{ name: 'infrastructure', endpoint: '/api/detect-infrastructure' },
{ name: 'illegalParking', endpoint: '/api/detect-illegal-parking' },
{ name: 'streetLight', endpoint: '/api/detect-street-light' },
{ name: 'fire', endpoint: '/api/detect-fire' },
{ name: 'strayAnimal', endpoint: '/api/detect-stray-animal' },
{ name: 'blockedRoad', endpoint: '/api/detect-blocked-road' },
{ name: 'treeHazard', endpoint: '/api/detect-tree-hazard' },
{ name: 'pest', endpoint: '/api/detect-pest' }
{ name: 'pothole', endpoint: '/detect-pothole' },
{ name: 'garbage', endpoint: '/detect-garbage' },
{ name: 'vandalism', endpoint: '/detect-vandalism' },
{ name: 'flooding', endpoint: '/detect-flooding' },
{ name: 'infrastructure', endpoint: '/detect-infrastructure' },
{ name: 'illegalParking', endpoint: '/detect-illegal-parking' },
{ name: 'streetLight', endpoint: '/detect-street-light' },
{ name: 'fire', endpoint: '/detect-fire' },
{ name: 'strayAnimal', endpoint: '/detect-stray-animal' },
{ name: 'blockedRoad', endpoint: '/detect-blocked-road' },
{ name: 'treeHazard', endpoint: '/detect-tree-hazard' },
{ name: 'pest', endpoint: '/detect-pest' }
];

detectorTestCases.forEach(({ name, endpoint }) => {
Expand Down Expand Up @@ -114,7 +114,7 @@ describe('detectorsApi', () => {

await detectorsApi.pothole(mockFormData);

expect(apiClient.postForm).toHaveBeenCalledWith('/api/detect-pothole', mockFormData);
expect(apiClient.postForm).toHaveBeenCalledWith('/detect-pothole', mockFormData);
}
});

Expand Down
10 changes: 7 additions & 3 deletions frontend/src/api/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,15 @@ describe('API Index Exports', () => {
// issues: issuesApi (1)
// detectors: detectorsApi (1)
// misc: miscApi (1)
// Total: 5 top-level exports
// auth: authApi (1)
// admin: adminApi (1)
// grievances: grievancesApi (1)
// resolutionProof: resolutionProofApi (1)
// Total: 9 top-level exports
const exportKeys = Object.keys(api);
expect(exportKeys.length).toBe(5);
expect(exportKeys.length).toBe(9);

const expectedKeys = ['apiClient', 'getApiUrl', 'issuesApi', 'detectorsApi', 'miscApi'];
const expectedKeys = ['apiClient', 'getApiUrl', 'issuesApi', 'detectorsApi', 'miscApi', 'authApi', 'adminApi', 'grievancesApi', 'resolutionProofApi'];
expectedKeys.forEach(key => {
expect(exportKeys).toContain(key);
});
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/api/__tests__/issues.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('issuesApi', () => {

const result = await issuesApi.getRecent();

expect(apiClient.get).toHaveBeenCalledWith('/api/issues/recent');
expect(apiClient.get).toHaveBeenCalledWith('/issues/recent', { params: { limit: 10, offset: 0 } });
expect(result).toEqual(mockIssues);
});

Expand All @@ -48,7 +48,7 @@ describe('issuesApi', () => {

const result = await issuesApi.getRecent();

expect(apiClient.get).toHaveBeenCalledWith('/api/issues/recent');
expect(apiClient.get).toHaveBeenCalledWith('/issues/recent', { params: { limit: 10, offset: 0 } });
expect(result).toEqual(fakeRecentIssues);
expect(consoleWarnSpy).toHaveBeenCalledWith('Failed to fetch recent issues, using fake data', error);

Expand Down Expand Up @@ -81,7 +81,7 @@ describe('issuesApi', () => {

const result = await issuesApi.create(mockFormData);

expect(apiClient.postForm).toHaveBeenCalledWith('/api/issues', mockFormData);
expect(apiClient.postForm).toHaveBeenCalledWith('/issues', mockFormData);
expect(result).toEqual(mockResponse);
});

Expand All @@ -106,7 +106,7 @@ describe('issuesApi', () => {

const result = await issuesApi.create(mockFormData);

expect(apiClient.postForm).toHaveBeenCalledWith('/api/issues', mockFormData);
expect(apiClient.postForm).toHaveBeenCalledWith('/issues', mockFormData);
expect(result).toEqual(mockResponse);
});
});
Expand All @@ -120,7 +120,7 @@ describe('issuesApi', () => {

const result = await issuesApi.vote(issueId);

expect(apiClient.post).toHaveBeenCalledWith('/api/issues/123/vote', {});
expect(apiClient.post).toHaveBeenCalledWith('/issues/123/vote', {});
expect(result).toEqual(mockResponse);
});

Expand All @@ -132,7 +132,7 @@ describe('issuesApi', () => {

await issuesApi.vote(issueId);

expect(apiClient.post).toHaveBeenCalledWith(`/api/issues/${issueId}/vote`, {});
expect(apiClient.post).toHaveBeenCalledWith(`/issues/${issueId}/vote`, {});
}
});

Expand Down
16 changes: 8 additions & 8 deletions frontend/src/api/__tests__/misc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('miscApi', () => {

const result = await miscApi.getResponsibilityMap();

expect(apiClient.get).toHaveBeenCalledWith('/api/responsibility-map');
expect(apiClient.get).toHaveBeenCalledWith('/responsibility-map');
expect(result).toEqual(mockMap);
});

Expand All @@ -47,7 +47,7 @@ describe('miscApi', () => {

const result = await miscApi.getResponsibilityMap();

expect(apiClient.get).toHaveBeenCalledWith('/api/responsibility-map');
expect(apiClient.get).toHaveBeenCalledWith('/responsibility-map');
expect(result).toEqual(fakeResponsibilityMap);
expect(consoleWarnSpy).toHaveBeenCalledWith('Failed to fetch responsibility map, using fake data', error);

Expand Down Expand Up @@ -79,7 +79,7 @@ describe('miscApi', () => {

const result = await miscApi.chat(message);

expect(apiClient.post).toHaveBeenCalledWith('/api/chat', { query: message });
expect(apiClient.post).toHaveBeenCalledWith('/chat', { query: message });
expect(result).toEqual(mockResponse);
});

Expand All @@ -96,7 +96,7 @@ describe('miscApi', () => {

await miscApi.chat(message);

expect(apiClient.post).toHaveBeenCalledWith('/api/chat', { query: message });
expect(apiClient.post).toHaveBeenCalledWith('/chat', { query: message });
}
});

Expand All @@ -117,7 +117,7 @@ describe('miscApi', () => {

const result = await miscApi.chat(message);

expect(apiClient.post).toHaveBeenCalledWith('/api/chat', { query: message });
expect(apiClient.post).toHaveBeenCalledWith('/chat', { query: message });
expect(result).toEqual(mockResponse);
});
});
Expand All @@ -135,7 +135,7 @@ describe('miscApi', () => {

const result = await miscApi.getRepContact(pincode);

expect(apiClient.get).toHaveBeenCalledWith('/api/mh/rep-contacts?pincode=400001');
expect(apiClient.get).toHaveBeenCalledWith('/mh/rep-contacts?pincode=400001');
expect(result).toEqual(mockResponse);
});

Expand All @@ -147,7 +147,7 @@ describe('miscApi', () => {

await miscApi.getRepContact(pincode);

expect(apiClient.get).toHaveBeenCalledWith(`/api/mh/rep-contacts?pincode=${pincode}`);
expect(apiClient.get).toHaveBeenCalledWith(`/mh/rep-contacts?pincode=${pincode}`);
}
});

Expand Down Expand Up @@ -189,7 +189,7 @@ describe('miscApi', () => {

const result = await miscApi.getStats();

expect(apiClient.get).toHaveBeenCalledWith('/api/stats');
expect(apiClient.get).toHaveBeenCalledWith('/stats');
expect(result).toEqual(mockStats);
});

Expand Down
14 changes: 0 additions & 14 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,3 @@
# Environment variables (set these in Netlify dashboard)
# VITE_API_URL = https://your-backend.onrender.com

# Redirects for SPA
[[redirects]]
from = "/*"
to = "/index.html"
status = 200

# Headers for security
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
X-XSS-Protection = "1; mode=block"
Referrer-Policy = "strict-origin-when-cross-origin"
Loading