Skip to content

Aligning activity-backend with frontend schema#9

Merged
ArthurINIA merged 14 commits into
mainfrom
front-back-alignment
Jan 28, 2026
Merged

Aligning activity-backend with frontend schema#9
ArthurINIA merged 14 commits into
mainfrom
front-back-alignment

Conversation

@ArthurINIA

@ArthurINIA ArthurINIA commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

28/01/2026 1406 HKT
Aligning activity-backend with frontend schema

  • created helper methods to convert backend schema to frontend schema
  • defined schema compatible with frontend
  • updated supabase create_activity method to adapt new schema
  • tested and documented aligned endpoints

Summary by CodeRabbit

  • Documentation

    • Added curl-based test scenarios and a frontend↔backend API contract describing endpoints, payloads, pagination, and known field mismatches.
  • Chores

    • Startup instructions updated to use HOST/PORT environment variables.
  • New Features

    • Activity APIs now return frontend-formatted payloads (latitude/longitude/altitude), include total counts, accept start/end times, compute GPS-derived metrics (distance, elevation), and map frontend visibility flags.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 28, 2026 06:08
@coderabbitai

coderabbitai Bot commented Jan 28, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds frontend-aligned activity models and mapping helpers, updates routes to accept/return frontend payloads and compute GPS-derived metrics, persists start/end times via the Supabase client, and adds README and API/curl documentation.

Changes

Cohort / File(s) Summary
Documentation
activity-backend/CURL_TESTS.md, activity-backend/FRONTEND_ACTIVITY_API_SCHEMA.md, activity-backend/README.md
New curl test scenarios and frontend↔backend API schema docs; README run instructions changed to use HOST/PORT env vars and run python main.py.
Models (frontend shapes)
activity-backend/models.py
Added FrontendLocation, FrontendActivityCreate, FrontendActivityUpdate, FrontendActivityResponse; expanded create/update fields; ActivitiesListResponse now includes total.
Routes and transformation logic
activity-backend/routes/activities.py
Added mapping helpers (_activity_to_frontend, _to_frontend_locations, _to_location_points, _compute_metrics_from_locations, _haversine_distance_m, _parse_iso); endpoints now accept/return frontend schemas, compute metrics from GPS points, and map visibility/is_public.
Database client
activity-backend/services/supabase_client.py
create_activity signature updated to accept start_time/end_time, include them in the insert payload, and accept wider gps_path typing.

Sequence Diagrams

sequenceDiagram
    participant Frontend
    participant Routes as Route Handler
    participant Transform as Transform Logic
    participant Supabase as Database
    Frontend->>Routes: POST /activities (FrontendActivityCreate)
    Routes->>Transform: _parse_iso(start_time/end_time)
    Routes->>Transform: _to_location_points(gps_path)
    Transform->>Transform: _compute_metrics_from_locations(locations)
    Routes->>Supabase: create_activity(..., start_time, end_time, distance, elevation, gps_path)
    Supabase-->>Routes: created activity record
    Routes->>Transform: _activity_to_frontend(record)
    Transform-->>Routes: FrontendActivityResponse
    Routes-->>Frontend: FrontendActivityResponse
Loading
sequenceDiagram
    participant Frontend
    participant Routes as Route Handler
    participant Supabase as Database
    participant Transform as Transform Logic
    Frontend->>Routes: GET /activities/{id}
    Routes->>Supabase: fetch activity and locations
    Supabase-->>Routes: backend activity record + locations
    Routes->>Transform: _activity_to_frontend(activity)
    Transform->>Transform: _to_frontend_locations(locations)
    Transform-->>Routes: FrontendLocation[]
    Routes-->>Frontend: FrontendActivityResponse
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through code with nimble feet,

parsed timestamps, paths, and metrics neat,
stitched location points to distances fine,
saved times in tables, shaped each frontend line,
a little rabbit left this tidy beat.


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

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.

Pull request overview

This PR aligns the activity-backend API with the frontend schema expectations to eliminate the need for manual data transformation on the frontend. The backend now accepts and returns data structures that match what the Flutter frontend expects.

Changes:

  • Introduced frontend-compatible schemas (FrontendActivityCreate, FrontendActivityResponse, FrontendActivityUpdate, FrontendLocation) in models.py
  • Added helper functions to convert between backend and frontend schemas and compute metrics (distance, elevation gain, pace) from GPS location data
  • Updated all activity endpoints to accept frontend schemas and return frontend-compatible responses
  • Added start_time and end_time parameters to the create_activity method in supabase_client.py
  • Added comprehensive documentation for API schemas and curl test examples

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 20 comments.

Show a summary per file
File Description
activity-backend/models.py Added frontend-compatible schema models (FrontendLocation, FrontendActivityCreate, FrontendActivityUpdate, FrontendActivityResponse)
activity-backend/routes/activities.py Added conversion helper functions and updated all endpoints to use frontend schemas; server now computes metrics from location data
activity-backend/services/supabase_client.py Updated create_activity method signature to accept start_time and end_time parameters
activity-backend/README.md Updated deployment instructions to use python main.py with environment variables
activity-backend/FRONTEND_ACTIVITY_API_SCHEMA.md New documentation describing the alignment between frontend and backend API schemas
activity-backend/CURL_TESTS.md New documentation with curl examples for testing the aligned API endpoints

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

start_dt = _parse_iso(data.start_time)
end_dt = _parse_iso(data.end_time)
duration_seconds = max(0, int((end_dt - start_dt).total_seconds()))
metrics = _compute_metrics_from_locations([loc.model_dump() for loc in data.locations])

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

The endpoint doesn't validate that the locations list is not empty. If a user submits an activity with an empty locations array, the metrics will all be 0 (distance, elevation gain), but the activity will still be created. While this might be intentional for some use cases (manual entry), it could also result in invalid or meaningless activities. Consider adding validation to require at least a minimum number of location points or documenting this behavior.

Copilot uses AI. Check for mistakes.
Comment thread activity-backend/FRONTEND_ACTIVITY_API_SCHEMA.md Outdated
Comment thread activity-backend/services/supabase_client.py Outdated
Comment thread activity-backend/routes/activities.py Outdated
Comment thread activity-backend/FRONTEND_ACTIVITY_API_SCHEMA.md Outdated
Comment on lines +88 to +89
start_time: str
end_time: str

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

The FrontendActivityResponse schema requires start_time and end_time to be non-optional strings, but the _activity_to_frontend function uses fallbacks including datetime.utcnow().isoformat() when these fields are missing. If the database doesn't have these fields for older activities, this could create inconsistent or incorrect timestamps. Consider either making these fields optional in the response schema or ensuring all activities in the database have these fields populated.

Suggested change
start_time: str
end_time: str
start_time: Optional[str] = None
end_time: Optional[str] = None

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +38
- Backend returns: an object `{ items: [ActivityResponse], total: int }`.
- Data provenance: list comes from backend store; pagination mismatch means frontend currently ignores `total` and expects bare array.

## GET /activities/{id}
- Frontend expects response shaped like `Activity.fromJson` (includes type, distance, duration, start_time, end_time, pace metrics, locations, etc.).
- Backend returns `ActivityResponse` (fields: id, user_id, name, activity_type, gps_path, duration_seconds, distance_meters, elevation_gain_meters, visibility, description, created_at).

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

Lines 33 and 38 state that the backend returns the old schema, but this PR changes the backend to return FrontendActivityResponse (an array for lists, and the frontend-compatible shape for individual activities). This documentation is now outdated and should be updated to reflect the new response format.

Copilot uses AI. Check for mistakes.
"calories": activity.get("calories"),
"is_public": (activity.get("visibility") == "public"),
"created_at": created_at,
"locations": _to_frontend_locations(activity.get("id"), gps_path),

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

The _to_frontend_locations function receives activity.get("id") which could be None, potentially causing issues when setting activity_id in the location objects. While the frontend schema allows activity_id to be None, this might not be the intended behavior for responses. Consider handling the case where activity.get("id") is None.

Copilot uses AI. Check for mistakes.
Comment thread activity-backend/routes/activities.py Outdated
Comment on lines +111 to +112
except Exception:
avg_pace = None

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

The error handling catches a generic Exception and sets avg_pace to None, which could mask other errors. While division errors are unlikely here (given the conditional check), this broad exception handling could hide unexpected issues. Consider being more specific about which exceptions to catch or at least logging the exception for debugging.

Suggested change
except Exception:
avg_pace = None
except (TypeError, ZeroDivisionError) as exc:
logger.exception("Failed to compute average pace", exc_info=exc)

Copilot uses AI. Check for mistakes.
ArthurINIA and others added 5 commits January 28, 2026 14:22
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@ArthurINIA ArthurINIA merged commit 44cba45 into main Jan 28, 2026
1 of 3 checks passed
@chefmatteo chefmatteo deleted the front-back-alignment branch May 15, 2026 22:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants