Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4753ee4
feat: integrate Mapbox for enhanced mapping functionality
GURUDAS-DEV Feb 14, 2026
84f3c35
fix: remove error logging from token verification middleware response
GURUDAS-DEV Feb 14, 2026
558e13e
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
e16f2df
feat: Implement interactive map for selecting route source/destinatio…
GURUDAS-DEV Feb 14, 2026
0598536
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
a5c32d8
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
3385dee
feat: Implement interactive Mapbox map component for source and desti…
GURUDAS-DEV Feb 14, 2026
e8e953e
feat: Minute Bug Update
GURUDAS-DEV Feb 14, 2026
0e1e982
feat: implement interactive Mapbox map for location selection on the …
GURUDAS-DEV Feb 14, 2026
e430043
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
b870060
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
0faee97
feat: implement route discovery, comparison, and map visualization wi…
GURUDAS-DEV Feb 14, 2026
b35e17f
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
4650c18
Merge branch 'main' of https://github.com/GURUDAS-DEV/BreathClean
GURUDAS-DEV Feb 14, 2026
b01b129
feat1: implement route discovery, comparison, and map visualization w…
GURUDAS-DEV Feb 14, 2026
4ab28ec
feat: Implement route discovery and comparison features with pollutio…
GURUDAS-DEV Feb 14, 2026
ecbae17
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
a8da103
feat: Implement route discovery, comparison, and saving features with…
GURUDAS-DEV Feb 14, 2026
02db6ae
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
24f4a94
feat: Add user profile page with detailed card, display saved routes,…
GURUDAS-DEV Feb 14, 2026
43a6501
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 14, 2026
da61bb5
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 15, 2026
8d69776
feat: Add public About and Features pages, introduce Navbar and Saved…
GURUDAS-DEV Feb 15, 2026
88bb043
feat: Add a new About Us page and a SavedRouteItemClient component.
GURUDAS-DEV Feb 15, 2026
fd1079a
feat: Add a new About Us page and a SavedRouteItemClient component.
GURUDAS-DEV Feb 15, 2026
7034411
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 15, 2026
a31c58e
feat: implement initial landing page with navigation, mission, how it…
GURUDAS-DEV Feb 15, 2026
bb73943
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 15, 2026
d8803c7
feat: Implement route scoring API including breakpoint calculation an…
GURUDAS-DEV Feb 15, 2026
3d3ad64
feat: Implement API for route score calculation considering weather a…
GURUDAS-DEV Feb 15, 2026
79f1878
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 15, 2026
41881ef
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 15, 2026
4091e1c
feat: Integrate Air Quality Index (AQI) data into route comparison fe…
GURUDAS-DEV Feb 15, 2026
c111433
refactor: Remove outdated AQI documentation and guides
GURUDAS-DEV Feb 15, 2026
38c2d82
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 15, 2026
c7c87f9
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 16, 2026
a2c09e2
feat: Setup Django Project and setup api app and a testing router
GURUDAS-DEV Feb 16, 2026
0f32fd3
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 16, 2026
40a8199
feat: Implement scoring transformers for BreathClean Pathway pipeline
GURUDAS-DEV Feb 17, 2026
1056d1c
feat: Implement a data processing server and scheduler for dynamic ro…
GURUDAS-DEV Feb 20, 2026
f4f2d38
feat: Add data processing pipeline for route score computation using …
GURUDAS-DEV Feb 21, 2026
f3f0b7e
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 21, 2026
0502047
chore: Specify Python runtime version 3.11.9 in runtime.txt
GURUDAS-DEV Feb 21, 2026
95fba52
feat: add project dependencies
GURUDAS-DEV Feb 21, 2026
227efcd
feat: add STATIC_ROOT setting to configure static files directory
GURUDAS-DEV Feb 21, 2026
dd66f71
feat: update requirements to include gunicorn for production server
GURUDAS-DEV Feb 21, 2026
1527690
feat: update ALLOWED_HOSTS configuration and requirements for Django …
GURUDAS-DEV Feb 21, 2026
5894240
fix: revert Django version to 5.2.11 and clean up requirements
GURUDAS-DEV Feb 21, 2026
692349c
feat: enhance ALLOWED_HOSTS configuration to support multiple host so…
GURUDAS-DEV Feb 21, 2026
6bfd4df
feat: Implement initial setup for Django data processing server and E…
GURUDAS-DEV Feb 22, 2026
e568621
Merge branch 'kaihere14:main' into main
GURUDAS-DEV Feb 22, 2026
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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
168 changes: 137 additions & 31 deletions data-processing/dataProcessingServer/dataProcessingServer/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,23 @@

import os
from pathlib import Path
from urllib.parse import urlparse

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# ---------------------------------------------------------------------------
# Security settings — driven by environment variables.
# Security — driven by environment variables.
#
# Required in production:
# DJANGO_SECRET_KEY — a long, random secret key
# DJANGO_SECRET_KEY — a long, random secret key
#
# Optional (have sensible dev defaults):
# Optional (sensible dev defaults apply if not set):
# DJANGO_DEBUG — set to "False" / "0" to disable debug mode
# DJANGO_ALLOWED_HOSTS — comma-separated list of allowed hostnames
# ---------------------------------------------------------------------------

# Detect whether we are running in development mode: if no explicit secret
# key is provided via the environment, we fall back to an insecure default
# and treat the environment as development.
_SECRET_KEY_ENV = os.getenv('DJANGO_SECRET_KEY')
_IS_DEV = _SECRET_KEY_ENV is None

Expand All @@ -45,17 +43,51 @@
if _debug_env is not None:
DEBUG = _debug_env.lower() in ('true', '1', 'yes')
else:
# Default to True only in development.
# Default to True in development (when no SECRET_KEY is set).
DEBUG = _IS_DEV

# ALLOWED_HOSTS — populated from a comma-separated env var, or empty in dev.

def _normalize_host(value: str) -> str:
host = (value or '').strip()
if not host:
return ''
if '://' in host:
host = (urlparse(host).hostname or '').strip()
else:
host = host.split('/')[0].split(':')[0].strip()
return host.lower()


# ALLOWED_HOSTS
_allowed_hosts_env = os.getenv('DJANGO_ALLOWED_HOSTS', '')
ALLOWED_HOSTS = [
h.strip() for h in _allowed_hosts_env.split(',') if h.strip()
] if _allowed_hosts_env else []
_allowed_hosts_from_env = [
_normalize_host(item) for item in _allowed_hosts_env.split(',') if item.strip()
]

_render_host_candidates = [
os.getenv('RENDER_EXTERNAL_HOSTNAME', ''),
os.getenv('RENDER_EXTERNAL_URL', ''),
os.getenv('RENDER_SERVICE_NAME', ''),
]
_render_hosts = [
h for h in (_normalize_host(c) for c in _render_host_candidates) if h
]

if _allowed_hosts_from_env:
ALLOWED_HOSTS = _allowed_hosts_from_env
else:
# Local dev: allow all localhost variants + Render hosts for production
ALLOWED_HOSTS = _render_hosts + [
'localhost',
'127.0.0.1',
'[::1]', # IPv6 localhost
'.onrender.com', # Render.com deployments
]


# ---------------------------------------------------------------------------
# Application definition
# ---------------------------------------------------------------------------

INSTALLED_APPS = [
'django.contrib.admin',
Expand All @@ -64,10 +96,15 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Third-party
'corsheaders', # pip install django-cors-headers
# Local apps
'api',
]

MIDDLEWARE = [
# CorsMiddleware MUST come before CommonMiddleware to handle preflight OPTIONS requests
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
Expand Down Expand Up @@ -97,8 +134,59 @@
WSGI_APPLICATION = 'dataProcessingServer.wsgi.application'


# ---------------------------------------------------------------------------
# CORS — Cross-Origin Resource Sharing
#
# In production set this env var to your actual domains:
# CORS_ALLOWED_ORIGINS=https://yourfrontend.com,https://yourapi.com
# ---------------------------------------------------------------------------

_cors_env = os.getenv('CORS_ALLOWED_ORIGINS', '')
_cors_from_env = [o.strip() for o in _cors_env.split(',') if o.strip()]

if _cors_from_env:
CORS_ALLOWED_ORIGINS = _cors_from_env
else:
# Local dev fallback — never reaches production if env var is set
CORS_ALLOWED_ORIGINS = [
'http://localhost:8000',
'http://127.0.0.1:8000',
'http://localhost:3000',
'http://127.0.0.1:3000',
'http://localhost:8001',
'http://127.0.0.1:8001',
]

# Allow credentials (cookies, Authorization headers) in cross-origin requests
CORS_ALLOW_CREDENTIALS = True

# Allow all standard + custom headers needed for JSON API calls
CORS_ALLOW_HEADERS = [
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
]

# Allow POST (and other non-simple methods) cross-origin
CORS_ALLOW_METHODS = [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
]


# ---------------------------------------------------------------------------
# Database
# https://docs.djangoproject.com/en/6.0/ref/settings/#databases
# ---------------------------------------------------------------------------

DATABASES = {
'default': {
Expand All @@ -108,38 +196,56 @@
}


# ---------------------------------------------------------------------------
# Password validation
# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators
# ---------------------------------------------------------------------------

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'},
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'},
{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'},
]


# ---------------------------------------------------------------------------
# Internationalization
# https://docs.djangoproject.com/en/6.0/topics/i18n/
# ---------------------------------------------------------------------------

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/6.0/howto/static-files/
# ---------------------------------------------------------------------------
# Static files
# ---------------------------------------------------------------------------

STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'


# ---------------------------------------------------------------------------
# Production security — auto-enabled when DEBUG=False
# (no env vars needed; these activate automatically in production)
# ---------------------------------------------------------------------------

if not DEBUG:
# Force all traffic over HTTPS
SECURE_SSL_REDIRECT = True

# Prevent cookies being sent over HTTP
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

# Tell browsers to only use HTTPS for 1 year
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True

# Prevent browsers from sniffing content type
SECURE_CONTENT_TYPE_NOSNIFF = True

# Clickjacking protection
X_FRAME_OPTIONS = 'DENY'
9 changes: 7 additions & 2 deletions data-processing/dataProcessingServer/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# BreathClean Data Processing Server Requirements

# Django (must match version referenced in settings.py — Django 6.0.2)
Django>=6.0,<7.0
Django==5.2.11
Comment on lines 3 to +4
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "requirements.txt" -o -name "settings.py" | head -20

Repository: kaihere14/BreathClean

Length of output: 192


🏁 Script executed:

# Read the requirements.txt file to verify the actual content
cat -n data-processing/dataProcessingServer/requirements.txt

Repository: kaihere14/BreathClean

Length of output: 1268


🌐 Web query:

Django 5.2.11 release

💡 Result:

Django 5.2.11 was released on February 3, 2026 (Django 5.2 LTS) as a security release. It fixes 6 security issues in 5.2.10: 3 “high”, 2 “moderate”, and 1 “low” severity. Key fixes include a PostGIS RasterField SQL injection (CVE-2026-1207), SQL injection vectors involving FilteredRelation/aliases (CVE-2026-1287, CVE-2026-1312), ASGI repeated-headers DoS (CVE-2025-14550), Truncator HTML DoS (CVE-2026-1285), and mod_wsgi auth timing-based username enumeration (CVE-2025-13473). [1][2]

Upgrade/install with pip:

pip install --upgrade "Django==5.2.11"

The release is available via the official Django download page and on PyPI. [3][4]

Sources: Django 5.2.11 release notes [1], Django security announcement [2], Django downloads page [3], PyPI release history [4].


🏁 Script executed:

cat -n data-processing/dataProcessingServer/dataProcessingServer/settings.py | head -50

Repository: kaihere14/BreathClean

Length of output: 2000


Update stale Django version references in requirements.txt and settings.py.

Line 3 of requirements.txt states Django 6.0.2 but the actual pin is Django==5.2.11 (LTS). The same stale version appears in settings.py's docstring (lines 4, 7, 10). Update both files to reflect Django 5.2.11 and remove the hardcoded version number from the requirements.txt comment to avoid future drift.

📝 Suggested changes

requirements.txt:

-# Django (must match version referenced in settings.py — Django 6.0.2)
+# Django LTS (must match version referenced in settings.py)
 Django==5.2.11

settings.py (lines 4, 7, 10):

-Generated by 'django-admin startproject' using Django 6.0.2.
+Generated by 'django-admin startproject' using Django 5.2.11.

-https://docs.djangoproject.com/en/6.0/topics/settings/
+https://docs.djangoproject.com/en/5.2/topics/settings/

-https://docs.djangoproject.com/en/6.0/ref/settings/
+https://docs.djangoproject.com/en/5.2/ref/settings/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data-processing/dataProcessingServer/requirements.txt` around lines 3 - 4,
Update the stale Django version references: in requirements.txt remove the
hardcoded comment "Django (must match version referenced in settings.py — Django
6.0.2)" and ensure the pinned dependency line is exactly "Django==5.2.11"; in
settings.py update the docstring occurrences that mention "Django 6.0.2" to
"Django 5.2.11" so docstrings and the requirements pin match, and avoid
embedding a specific version in the comment to prevent future drift.


# CORS headers — allows Node server (port 8000) and Next.js (port 3000) to call this API
django-cors-headers>=4.3.0

# Pathway - Real-time data processing framework
# NOTE: Pathway is licensed under BSL 1.1 with service-use restrictions.
Expand All @@ -14,9 +17,11 @@ urllib3>=2.6.0,<3.0
# For JSON handling (included in Python stdlib, but explicit)
# json - stdlib

# Production server
gunicorn>=21.0.0

# Optional: For async support
# uvicorn>=0.24.0
# gunicorn>=21.0.0

# Optional: For database connections (if connecting directly to MongoDB)
# pymongo>=4.6.0
Expand Down
1 change: 1 addition & 0 deletions data-processing/dataProcessingServer/runtime.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python-3.11.9
14 changes: 7 additions & 7 deletions server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ connectDB()
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);

// Initialize the cron scheduler only when explicitly opted in
if (process.env.ENABLE_SCHEDULER === "true") {
initScheduler();
console.log("Batch scoring scheduler initialized");
} else {
console.log("Scheduler disabled (set ENABLE_SCHEDULER=true to enable)");
}
// Start the periodic batch scoring scheduler
initScheduler();

// Also fire once immediately on startup (no wait for first cron tick)
runManualBatchScoring().catch((err) =>
console.error("[Scheduler] Startup run failed:", err)
);
});
})
.catch((error) => {
Expand Down
Loading