Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 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
510eb38
chore: resolve merge conflict in computeData.scheduler.ts - use setIn…
GURUDAS-DEV Feb 22, 2026
7f74202
feat:added debug statement
GURUDAS-DEV Feb 22, 2026
697fa7b
feat: enhance sendToPathway function with retry logic and configurabl…
GURUDAS-DEV Feb 22, 2026
1cc36f5
feat: enhance sendToPathway function with retry logic and configurabl…
GURUDAS-DEV Feb 22, 2026
459117a
Accept Incoming
GURUDAS-DEV Feb 22, 2026
f500ea0
feat: Introduce route saving, environmental data computation, and sco…
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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Use the custom 'theirs' merge driver for all files to prefer incoming changes.
* merge=theirs
Comment on lines +1 to +2

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 | 🟠 Major

* merge=theirs globally silences ALL merge conflicts — high data-loss risk.

Assigning a merge driver in .gitattributes controls which driver handles specific files — and you should replace * with the file extension you actually want the custom driver applied to. The current glob * applies the "always take theirs" strategy to every file in the repository — source code, configuration, data files, binaries, and even .gitattributes itself.

Specific consequences:

  • Any developer who runs the setup script will have all merge conflicts silently resolved by accepting the incoming version, with no conflict markers and no opportunity to review.
  • Developers who haven't run the setup will silently fall back to the standard 3-way text merge, creating inconsistent behavior across the team.
  • This is committed to the repository, meaning the effect is permanent for any contributor who runs setup.

Suggest narrowing the pattern to only files that genuinely require automatic conflict resolution (e.g., auto-generated lock files like *.lock, build artifacts, etc.) or removing this entirely in favour of an explicit per-file opt-in:

-# Use the custom 'theirs' merge driver for all files to prefer incoming changes.
-* merge=theirs
+# Use the custom 'theirs' merge driver only for auto-generated files.
+package-lock.json merge=theirs
+*.lock merge=theirs
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitattributes around lines 1 - 2, The .gitattributes entry currently uses a
global pattern "* merge=theirs" which silently forces the "theirs" driver for
every file; update this to narrow or remove that pattern by replacing "*
merge=theirs" with targeted patterns (e.g., use specific globs like "*.lock
merge=theirs" or other generated artifact patterns) or remove the line entirely
so only explicit per-file rules apply; ensure the change touches the unique
symbol "* merge=theirs" in the file so only intended auto-resolved file types
get the custom merge driver.

Binary file not shown.
Binary file not shown.
30 changes: 30 additions & 0 deletions data-processing/dataProcessingServer/api/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from django.http import JsonResponse
import traceback
from django.conf import settings


class ApiExceptionMiddleware:
"""
Catch unhandled exceptions for API paths and return a JSON 500 response.
This avoids triggering Django's HTML technical_500 page (which on some
environments can fail to render) and gives a stable JSON error for the
frontend.
"""

def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
try:
return self.get_response(request)
except Exception as exc:
# Only intercept API routes
path = getattr(request, 'path', '') or ''
if path.startswith('/api/'):
if settings.DEBUG:
tb = traceback.format_exc()
return JsonResponse({'success': False, 'message': 'Internal server error', 'error': str(exc), 'trace': tb}, status=500)
else:
return JsonResponse({'success': False, 'message': 'Internal server error'}, status=500)
# Re-raise for non-API routes so Django can handle normally
raise
Comment on lines +17 to +30

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 | 🟠 Major

Error responses bypass CorsMiddleware — browser will block cross-origin error bodies.

Because ApiExceptionMiddleware sits above CorsMiddleware in MIDDLEWARE (see settings.py line 116-118), when an exception is caught here the returned JsonResponse short-circuits back without passing through CorsMiddleware. The browser will block the frontend from reading the JSON error body due to missing CORS headers.

Two possible fixes:

Option A (preferred): Move the middleware below CorsMiddleware in settings.py:

 MIDDLEWARE = [
     'corsheaders.middleware.CorsMiddleware',
+    'api.middleware.ApiExceptionMiddleware',
     'django.middleware.security.SecurityMiddleware',
     ...
-    'api.middleware.ApiExceptionMiddleware',
 ]

Option B: Manually add CORS headers in the error response here, but this duplicates django-cors-headers logic and is harder to maintain.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@data-processing/dataProcessingServer/api/middleware.py` around lines 17 - 30,
ApiExceptionMiddleware is returning JsonResponse before CorsMiddleware runs,
causing missing CORS headers; move ApiExceptionMiddleware to be listed after
CorsMiddleware in the MIDDLEWARE setting (so CorsMiddleware runs first) rather
than trying to add headers here. Edit settings.py and reorder the MIDDLEWARE
list so "corsheaders.middleware.CorsMiddleware" appears before your
"dataProcessingServer.api.middleware.ApiExceptionMiddleware" (keep references to
those exact names).

Binary file not shown.
9 changes: 9 additions & 0 deletions data-processing/dataProcessingServer/api/pathway/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
except (ImportError, AttributeError):
pass

# Pathway is Linux-only. Even if the package is importable on Windows
# (e.g. accidental/bundled install), avoid using it because it can
# hang or fail at runtime on Windows environments. Force disabled on
# Windows to ensure the Django server remains responsive.
import sys
if sys.platform.startswith("win") and PATHWAY_AVAILABLE:
PATHWAY_AVAILABLE = False
pw = None

from .transformers import compute_route_score, compute_batch_scores


Expand Down
2 changes: 2 additions & 0 deletions data-processing/dataProcessingServer/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def compute_scores(request):

routes = body.get("routes", [])
use_pathway = body.get("usePathway", False)


# Validation
if not isinstance(routes, list):
Expand Down Expand Up @@ -174,6 +175,7 @@ def compute_single_score(request):

# Import here to avoid circular imports
from .pathway.transformers import compute_route_score


result = compute_route_score(body)

Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,21 @@ def _normalize_host(value: str) -> str:
os.getenv('RENDER_EXTERNAL_HOSTNAME', ''),
os.getenv('RENDER_EXTERNAL_URL', ''),
os.getenv('RENDER_SERVICE_NAME', ''),
os.getenv('RAILWAY_PUBLIC_DOMAIN', ''),
os.getenv('BACKEND_URL', ''),
os.getenv('API_URL', ''),
os.getenv('PUBLIC_URL', ''),
os.getenv('APP_URL', ''),
]
_render_hosts = [
h for h in (_normalize_host(c) for c in _render_host_candidates) if h
]

if _allowed_hosts_from_env:
_allow_all_hosts = os.getenv('DJANGO_ALLOW_ALL_HOSTS', '').lower() in ('true', '1', 'yes')

if _allow_all_hosts:
ALLOWED_HOSTS = ['*']
elif _allowed_hosts_from_env:
ALLOWED_HOSTS = _allowed_hosts_from_env
else:
# Local dev: allow all localhost variants + Render hosts for production
Expand Down Expand Up @@ -103,6 +112,8 @@ def _normalize_host(value: str) -> str:
]

MIDDLEWARE = [
# Custom API exception middleware — placed early so API errors return JSON
'api.middleware.ApiExceptionMiddleware',
# CorsMiddleware MUST come before CommonMiddleware to handle preflight OPTIONS requests
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
Expand Down Expand Up @@ -144,8 +155,17 @@ def _normalize_host(value: str) -> str:
_cors_env = os.getenv('CORS_ALLOWED_ORIGINS', '')
_cors_from_env = [o.strip() for o in _cors_env.split(',') if o.strip()]

_cors_url_candidates = [
os.getenv('FRONTEND_URL', ''),
os.getenv('CLIENT_URL', ''),
os.getenv('WEB_URL', ''),
]
_cors_from_candidates = [u.strip() for u in _cors_url_candidates if u and u.strip()]

if _cors_from_env:
CORS_ALLOWED_ORIGINS = _cors_from_env
elif _cors_from_candidates:
CORS_ALLOWED_ORIGINS = _cors_from_candidates
else:
# Local dev fallback — never reaches production if env var is set
CORS_ALLOWED_ORIGINS = [
Expand Down
21 changes: 21 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
This repository includes a custom merge driver that prefers the incoming ("theirs") side during merges.

Setup

- Unix / Git Bash:
- Run: `./scripts/setup-merge-theirs.sh`
- Windows PowerShell:
- Run: `./scripts/setup-merge-theirs.ps1`

Notes

- After registering the driver, Git will use the 'theirs' version for all files during merges.
- To accept incoming changes for an ongoing conflict manually:

```powershell
git checkout --theirs -- .
git add -A
git commit -m "Accept incoming changes (theirs) for merge"
```

Be cautious: this will overwrite local changes with incoming ones for files that conflict.
7 changes: 7 additions & 0 deletions scripts/git-merge-theirs.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Param($O, $A, $B)
if (-not (Test-Path $B)) {
Write-Error "git-merge-theirs.ps1: missing 'their' file"
exit 1
}
Get-Content -Raw -LiteralPath $B | Set-Content -LiteralPath $A -Encoding UTF8

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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check if the file exists and confirm the code in question
fd git-merge-theirs.ps1

Repository: kaihere14/BreathClean

Length of output: 93


🌐 Web query:

PowerShell 5.1 Set-Content -Encoding UTF8 BOM behavior

💡 Result:

In Windows PowerShell 5.1, Set-Content -Encoding UTF8 always writes UTF‑8 with a BOM (EF BB BF). There is no utf8NoBOM option in 5.1’s -Encoding parameter set. [1], [2]

Implications:

  • If you need BOM-less UTF‑8 in 5.1, you must use a .NET API (e.g., System.Text.UTF8Encoding($false) with WriteAllText/WriteAllLines). [2]
  • In PowerShell 7+, the behavior differs: UTF‑8 is BOM-less by default, and a BOM is requested explicitly with -Encoding utf8BOM. [1]

Sources

  1. Stack Overflow: “PowerShell 5.1, Output to a text file with Out-File / Set-Content and utf8” (mklement0) — explains PS 5.1 -Encoding utf8 => BOM; PS 7+ defaults to BOM-less UTF-8 and supports utf8BOM. https://stackoverflow.com/questions/77987322/
  2. 2Pint Software: “Why is ‘Add-Content’ bad in PowerShell 5.1?” — notes -Encoding UTF8 creates “UTF8 with BOM” in PS 5.1 and suggests .NET workarounds. https://2pintsoftware.com/news/details/why-is-add-content-bad-in-powershell-51

🌐 Web query:

PowerShell Get-Content -Raw binary safe text processing

💡 Result:

Get-Content -Raw is not binary-safe: it reads the file as text, decoding bytes using an encoding, and returns one big string (preserving embedded newlines rather than splitting into lines). (powershell.org)

If you need binary-safe processing

Read bytes, not strings:

  • PowerShell 7+:

    [byte[]]$bytes = Get-Content -LiteralPath $path -AsByteStream -Raw

    -AsByteStream returns a byte stream and ignores -Encoding. (learn.microsoft.com)

  • Windows PowerShell 5.1:

    [byte[]]$bytes = Get-Content -LiteralPath $path -Encoding Byte -Raw

    -Encoding Byte reads raw bytes. (stackoverflow.com)

Then do explicit decoding/encoding only where appropriate, e.g.:

$text = [Text.Encoding]::UTF8.GetString($bytes)   # decode explicitly
# ...text processing...
$newBytes = [Text.Encoding]::UTF8.GetBytes($text) # re-encode explicitly
[IO.File]::WriteAllBytes($path, $newBytes)

If the file is text (but you want reliable text processing)

Be explicit about encoding (especially on Windows PowerShell 5.1, where Get-Content may assume the legacy ANSI “Default” code page when there’s no BOM). (learn.microsoft.com)

$text = Get-Content -LiteralPath $path -Raw -Encoding utf8
# ...process...
Set-Content -LiteralPath $path -Encoding utf8 -Value $text

Notes:

  • -Raw loads the whole file into memory (great for whole-file regex/replace; not great for huge files). (learn.microsoft.com)

Citations:


🌐 Web query:

PowerShell Copy-Item binary safe preserve encoding

💡 Result:

  • Binary-safe copy (no encoding changes): Use Copy-Item. It copies files as files/bytes; text encoding isn’t involved unless you read/write the content as text. (learn.microsoft.com)

    Copy-Item -LiteralPath $src -Destination $dst -Force
  • What breaks “encoding preservation”: Piping file content through cmdlets like Get-Content/Out-File converts bytes → .NET strings → bytes again, and PowerShell does not preserve the original encoding automatically; you must specify it. (stackoverflow.com)

  • If you must round-trip bytes (still binary-safe): Read as bytes, then write bytes (no encoding). Get-Content supports -AsByteStream. (learn.microsoft.com)

    $bytes = Get-Content -LiteralPath $src -AsByteStream -Raw
    [System.IO.File]::WriteAllBytes($dst, $bytes)
  • If you must rewrite text and keep a specific encoding: Specify -Encoding explicitly on read/write (and be aware Windows PowerShell 5.1 vs PowerShell 7+ differ in UTF-8 BOM behavior). (stackoverflow.com)

  • If you also need to preserve timestamps/ACLs/attributes: Prefer robocopy with appropriate flags (e.g., copying data + attributes + timestamps + security). (learn.microsoft.com)

Citations:


Replace Get-Content | Set-Content with Copy-Item for binary-safe merge operation.

Set-Content -Encoding UTF8 on Windows PowerShell 5.1 writes UTF-8 with a 3-byte BOM (EF BB BF), corrupting files and breaking downstream tools. Additionally, Get-Content -Raw processes the file as text, normalizing line endings and mangling binary content; the equivalent Unix script uses cat which is a raw byte copy.

Use Copy-Item, which is both binary-safe and encoding-agnostic:

🛡️ Proposed fix
-Get-Content -Raw -LiteralPath $B | Set-Content -LiteralPath $A -Encoding UTF8
+Copy-Item -LiteralPath $B -Destination $A -Force
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Get-Content -Raw -LiteralPath $B | Set-Content -LiteralPath $A -Encoding UTF8
Copy-Item -LiteralPath $B -Destination $A -Force
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/git-merge-theirs.ps1` at line 6, The current pipeline uses
Get-Content -Raw with Set-Content -Encoding UTF8 which treats the file as text
and writes a UTF-8 BOM (corrupting binaries); replace that pipeline with a
binary-safe file copy using Copy-Item so the script copies bytes without
re-encoding or normalizing line endings (use Copy-Item with the source variable
$B and destination $A and pass the overwrite/force option to ensure the target
is replaced).

exit 0
9 changes: 9 additions & 0 deletions scripts/git-merge-theirs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
# git merge driver that prefers "theirs" (incoming) during merges.
# Called with: %O %A %B
if [ -z "$3" ]; then
echo "git-merge-theirs: missing 'their' file parameter" >&2
exit 1
fi
cat "$3" > "$2"
exit 0
4 changes: 4 additions & 0 deletions scripts/setup-merge-theirs.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Write-Host "Registering merge.theirs driver..."
git config --local merge.theirs.name "Keep theirs (incoming) during merges"
git config --local merge.theirs.driver ".\scripts\git-merge-theirs.ps1 %O %A %B"

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 | 🔴 Critical

Driver command won't execute — .ps1 files need an explicit PowerShell interpreter.

Git invokes the merge driver command through sh (via Git for Windows / MSYS2 on Windows). A bare .\scripts\git-merge-theirs.ps1 ... path is not executable by sh — the shell has no handler for .ps1 files and the backslash path is also invalid in a POSIX shell context.

The driver path must invoke the PowerShell interpreter explicitly:

-git config --local merge.theirs.driver ".\scripts\git-merge-theirs.ps1 %O %A %B"
+git config --local merge.theirs.driver "powershell -ExecutionPolicy Bypass -File ./scripts/git-merge-theirs.ps1 %O %A %B"

Use pwsh instead of powershell if targeting PowerShell 7+.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
git config --local merge.theirs.driver ".\scripts\git-merge-theirs.ps1 %O %A %B"
git config --local merge.theirs.driver "powershell -ExecutionPolicy Bypass -File ./scripts/git-merge-theirs.ps1 %O %A %B"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/setup-merge-theirs.ps1` at line 3, The merge driver command in the
git config (git config --local merge.theirs.driver) currently points to
".\scripts\git-merge-theirs.ps1" which won't run under sh; change the driver to
invoke PowerShell explicitly (use pwsh for PowerShell 7+ or powershell for
Windows PowerShell) and use a POSIX-safe path to the script (e.g.,
./scripts/git-merge-theirs.ps1) so the shell can execute the interpreter with
the script and passed %O %A %B arguments.

Write-Host "Registered merge.theirs driver (local git config)."
7 changes: 7 additions & 0 deletions scripts/setup-merge-theirs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
# Register the 'theirs' merge driver locally and make scripts executable.
git config --local merge.theirs.name "Keep theirs (incoming) during merges"
git config --local merge.theirs.driver "./scripts/git-merge-theirs.sh %O %A %B"
chmod +x ./scripts/git-merge-theirs.sh || true
chmod +x ./scripts/git-merge-theirs.ps1 || true
echo "Registered merge.theirs driver (local git config)."
14 changes: 4 additions & 10 deletions server/src/Schema/breakPoints.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import mongoose, { Document, Schema } from "mongoose";

// --- Main BreakPoint Interface ---

export interface IBreakPoint extends Document {
routeId: mongoose.Types.ObjectId; // Reference to the parent Route document
routeOptionIndex: number; // Index of the specific route option (0, 1, 2...)
pointIndex: number; // Index of this point in the sequence (0, 1, 2...)
routeId: mongoose.Types.ObjectId;
routeOptionIndex: number;
pointIndex: number;

location: {
type: "Point";
coordinates: [number, number]; // [longitude, latitude]
coordinates: [number, number];
};
}

// --- Schema ---

const pointSchema = new Schema(
{
type: {
Expand Down Expand Up @@ -53,10 +49,8 @@ const breakPointSchema = new Schema<IBreakPoint>(
{ timestamps: true }
);

// Index for geospatial queries (finding points near a location)
breakPointSchema.index({ location: "2dsphere" });

// Index for retrieving all points for a specific route option
breakPointSchema.index({ routeId: 1, routeOptionIndex: 1 });

const BreakPoint = mongoose.model<IBreakPoint>("BreakPoint", breakPointSchema);
Expand Down
25 changes: 3 additions & 22 deletions server/src/Schema/route.schema.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import mongoose, { Document, Schema } from "mongoose";

/* ================= GEO TYPES ================= */

export interface IPoint {
type: "Point";
coordinates: [number, number]; // [longitude, latitude]
coordinates: [number, number];
}

export interface ITravelMode {
Expand All @@ -16,21 +14,16 @@ export interface ILineString {
coordinates: [number, number][];
}

/* ================= ROUTE OPTION ================= */

export interface IRouteOption {
distance: number; // in km
duration: number; // in minutes
distance: number;
duration: number;
travelMode: ITravelMode;
routeGeometry: ILineString;

// dynamically updated by pollution engine
lastComputedScore?: number;
lastComputedAt?: Date;
}

/* ================= MAIN ROUTE ================= */

export interface IRoute extends Document {
userId: mongoose.Types.ObjectId;
name?: string;
Expand All @@ -54,8 +47,6 @@ export interface IRoute extends Document {
updatedAt: Date;
}

/* ================= SCHEMAS ================= */

const pointSchema = new Schema<IPoint>(
{
type: {
Expand Down Expand Up @@ -86,8 +77,6 @@ const lineStringSchema = new Schema<ILineString>(
{ _id: false }
);

/* ===== Route Option Schema ===== */

const routeOptionSchema = new Schema<IRouteOption>(
{
distance: {
Expand Down Expand Up @@ -122,8 +111,6 @@ const routeOptionSchema = new Schema<IRouteOption>(
{ _id: false }
);

/* ===== Main Route Schema ===== */

const routeSchema = new Schema<IRoute>(
{
userId: {
Expand Down Expand Up @@ -178,18 +165,12 @@ const routeSchema = new Schema<IRoute>(
{ timestamps: true }
);

/* ================= INDEXES ================= */

// Needed for geo queries (AQI lookup, weather zone)
routeSchema.index({ "from.location": "2dsphere" });
routeSchema.index({ "to.location": "2dsphere" });
routeSchema.index({ "routes.routeGeometry": "2dsphere" });

// User queries
routeSchema.index({ userId: 1, updatedAt: -1 });
routeSchema.index({ userId: 1, isFavorite: 1 });

/* ================= MODEL ================= */

const Route = mongoose.model<IRoute>("Route", routeSchema);
export default Route;
Loading