Skip to content

feat(backend): add service and endpoint for health scores - #804

Merged
czajkub merged 12 commits into
mainfrom
health-score-services
Apr 8, 2026
Merged

czajkub merged 12 commits into
mainfrom
health-score-services

Conversation

@czajkub

@czajkub czajkub commented Apr 8, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Add service, repository and endpoint for health scores with some helper methods

Checklist

General

  • My code follows the project's code style
  • I have performed a self-review of my code
  • I have added tests that prove my fix/feature works (if applicable)
  • New and existing tests pass locally
  • I have updated relevant documentation in docs/ (or no docs update needed)

Backend Changes

You have to be in backend directory to make it work:

  • uv run pre-commit run --all-files passes

Summary by CodeRabbit

  • New Features

    • GET /users/{user_id}/health-scores endpoint with filtering (category, provider, data source, date range), pagination, totals, timeseries metadata, and date-range validation
    • Bulk-create support for inserting multiple health scores (ignores duplicates on conflict)
    • Service-level helpers to fetch latest score by category and latest per-category
  • Tests

    • New API, service, and repository tests covering filtering, pagination, auth, bulk-create, and latest-score retrieval

@czajkub czajkub self-assigned this Apr 8, 2026
@czajkub czajkub added backend Tickets related to the backend (FastAPI, Celery, database) health-scores Issues related to Health Scores (like Sleep Score, Stress Level etc.) labels Apr 8, 2026
@coderabbitai

coderabbitai Bot commented Apr 8, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds HealthScore domain: repository with JSONB component queries and bulk insert, query params schema and validation, service layer and singleton, API listing endpoint with filters/pagination, factories, and end-to-end tests for repository, service, and API.

Changes

Cohort / File(s) Summary
Repository
backend/app/repositories/__init__.py, backend/app/repositories/health_score_repository.py
Add HealthScoreRepository (extends CrudRepository) with JSONB component queries (get_by_all_components, get_by_any_component), joined/filtered retrieval (get_with_filters), bulk_create using ON CONFLICT DO NOTHING, and latest-per-category helpers.
Schemas
backend/app/schemas/model_crud/activities/health_score.py, backend/app/schemas/model_crud/activities/__init__.py
Add HealthScoreQueryParams Pydantic model (start/end datetimes, category/provider/data_source_id, limit/offset, validator) and re-export it in package __all__.
Service
backend/app/services/health_score_service.py
Add HealthScoreService wrapping repository operations and a module-level health_score_service singleton.
API Routes
backend/app/api/routes/v1/health_scores.py, backend/app/api/routes/v1/__init__.py
Add GET /users/{user_id}/health-scores route: parse query params into HealthScoreQueryParams, call service, return PaginatedResponse[HealthScoreResponse]; register router on v1 router.
Tests & Factories
backend/tests/factories.py, backend/tests/repositories/test_health_score_repository.py, backend/tests/services/test_health_score_service.py, backend/tests/api/v1/test_health_scores.py
Add HealthScoreFactory and comprehensive tests covering create/bulk_create, filter behavior (category/provider/date), pagination/total_count, conflict handling, auth/scoping, and latest-per-category semantics.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client/API
  participant Router as API Router
  participant Service as HealthScoreService
  participant Repo as HealthScoreRepository
  participant DB as PostgreSQL (HealthScore, DataSource)

  Client->>Router: GET /users/{user_id}/health-scores (query params)
  Router->>Service: get_scores_with_filters(db_session, user_id, params)
  Service->>Repo: get_with_filters(db_session, user_id, params)
  Repo->>DB: SELECT ... JOIN DataSource WHERE DataSource.user_id = user_id AND <filters> ORDER BY recorded_at DESC LIMIT/OFFSET
  DB-->>Repo: rows + total_count
  Repo-->>Service: (models list, total_count)
  Service-->>Router: (models list, total_count)
  Router-->>Client: PaginatedResponse with data, pagination, metadata
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • bartmichalak
  • KaliszS

Poem

🐇 I hopped through JSONB and skipped a fight,

inserting scores by day and night.
Per-category latest, filters in tune—
bulk inserts skip clashes and hum a tune.
A joyful hop for this new feature's light.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(backend): add service and endpoint for health scores' directly and clearly describes the main changes in the PR, which adds a HealthScoreService, HealthScoreRepository, HTTP endpoint, and supporting infrastructure for health scores.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch health-score-services

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@railway-app

railway-app Bot commented Apr 8, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the open-wearables-pr-804 environment in Open Wearables

Service Status Web Updated (UTC)
celery-beat ✅ Success (View Logs) Apr 8, 2026 at 1:16 pm
backend ✅ Success (View Logs) Web Apr 8, 2026 at 1:16 pm
celery-worker ✅ Success (View Logs) Apr 8, 2026 at 1:16 pm
celery-flower ✅ Success (View Logs) Web Apr 8, 2026 at 1:16 pm
frontend ✅ Success (View Logs) Web Apr 8, 2026 at 1:16 pm

@railway-app
railway-app Bot temporarily deployed to Open Wearables / open-wearables-pr-804 April 8, 2026 11:40 Destroyed

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/app/repositories/health_score_repository.py`:
- Line 50: The docstring stating "Bulk insert health scores, updating on
conflict with the unique constraint." conflicts with the actual implementation
which calls on_conflict_do_nothing; update either the docstring or the behavior:
either change the docstring to say "do nothing on conflict" to match the
on_conflict_do_nothing call, or replace on_conflict_do_nothing with an
on_conflict_do_update clause that sets the desired columns (e.g.,
timestamp/score) so the DB updates on unique constraint conflicts; locate the
method whose docstring is "Bulk insert health scores, updating on conflict with
the unique constraint." and the database call using on_conflict_do_nothing to
make the aligned change.
- Line 59: The current on_conflict_do_nothing call with
index_elements=["data_source_id","category","recorded_at"] will not dedupe rows
where data_source_id IS NULL; change the upsert to either (A) target a coalesced
expression so NULLs are treated the same (e.g. use a COALESCE(data_source_id,
'INTERNAL') expression in the conflict key via sa.text or equivalent) or (B)
switch to on_conflict_do_update so duplicates (including NULL data_source_id)
will update instead of inserting; also update the function/docstring in
health_score_repository.py (the upsert code path and the docstring near the
current call) to reflect the actual behavior (use COALESCE in the conflict key
or perform an on_conflict_do_update with appropriate set_ values) and ensure the
conflict key expression matches any database index you create for COALESCE-based
uniqueness.

In `@backend/app/schemas/model_crud/activities/health_score.py`:
- Around line 44-51: Add a Pydantic schema-level validator to
HealthScoreQueryParams that rejects windows where start_datetime is not strictly
before end_datetime: implement a `@root_validator` (or `@model_validator` in newer
Pydantic) inside the HealthScoreQueryParams class to check if both
start_datetime and end_datetime are provided and raise a ValueError (with a
clear message like "start_datetime must be before end_datetime") when
start_datetime >= end_datetime; update any tests accordingly so invalid query
params are rejected at the schema level rather than passed to the DB layer.

In `@backend/app/services/health_score_service.py`:
- Around line 20-50: Add the missing `@handle_exceptions` decorator to all public
service methods in this file: get_by_all_components, get_by_any_component,
bulk_create, get_latest_by_category, get_latest_per_category, and
get_scores_with_filters; import handle_exceptions from app.utils.exceptions at
the top of the module and place the decorator immediately above each method
definition so the service layer follows the exception-handling convention.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 04c6e261-5c0e-4b1f-9ba3-6d1f47e81a21

📥 Commits

Reviewing files that changed from the base of the PR and between 16428fb and 936619c.

📒 Files selected for processing (5)
  • backend/app/repositories/__init__.py
  • backend/app/repositories/health_score_repository.py
  • backend/app/schemas/model_crud/activities/__init__.py
  • backend/app/schemas/model_crud/activities/health_score.py
  • backend/app/services/health_score_service.py

Comment thread backend/app/repositories/health_score_repository.py Outdated
Comment thread backend/app/repositories/health_score_repository.py
Comment thread backend/app/schemas/model_crud/activities/health_score.py
Comment thread backend/app/services/health_score_service.py
@railway-app
railway-app Bot temporarily deployed to Open Wearables / open-wearables-pr-804 April 8, 2026 11:56 Destroyed

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

♻️ Duplicate comments (1)
backend/tests/repositories/test_health_score_repository.py (1)

194-221: ⚠️ Potential issue | 🟠 Major

Add a test for duplicate health scores with data_source_id=None (internally computed scores).

The existing test at lines 194–221 only validates duplicate prevention for non-null data_source_id (external provider scores). Due to PostgreSQL NULL semantics, the UNIQUE constraint on (data_source_id, category, recorded_at) does NOT prevent duplicates when data_source_id is NULL. This creates a gap in test coverage for internally computed scores.

Suggested test addition
 class TestHealthScoreRepositoryBulkCreate:
@@
     def test_bulk_create_ignores_duplicates(self, db: Session, repo: HealthScoreRepository) -> None:
         ...
         assert len(results) == 1
         assert results[0].value == Decimal("80.00")
+
+    def test_bulk_create_allows_duplicates_when_data_source_id_is_null(self, db: Session, repo: HealthScoreRepository) -> None:
+        recorded_at = datetime.now(timezone.utc)
+        first = HealthScoreCreate(
+            id=uuid4(),
+            data_source_id=None,
+            provider=ProviderName.INTERNAL,
+            category=HealthScoreCategory.SLEEP,
+            value=Decimal("80.00"),
+            recorded_at=recorded_at,
+        )
+        second = HealthScoreCreate(
+            id=uuid4(),
+            data_source_id=None,
+            provider=ProviderName.INTERNAL,
+            category=HealthScoreCategory.SLEEP,
+            value=Decimal("99.00"),
+            recorded_at=recorded_at,
+        )
+        repo.bulk_create(db, [first, second])
+        db.commit()
+
+        results = (
+            db.query(HealthScore)
+            .filter(
+                HealthScore.data_source_id.is_(None),
+                HealthScore.category == HealthScoreCategory.SLEEP,
+                HealthScore.recorded_at == recorded_at,
+            )
+            .all()
+        )
+        assert len(results) == 2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/repositories/test_health_score_repository.py` around lines 194
- 221, The test test_bulk_create_ignores_duplicates only covers duplicates when
data_source_id is set, but NULL data_source_id bypasses the DB UNIQUE
constraint; add a new test variant that creates two HealthScoreCreate objects
with data_source_id=None (same category and recorded_at) and calls
HealthScoreRepository.bulk_create twice, then query HealthScore to assert only
one row exists and its value matches the first insert; ensure you use the same
recorded_at and category and reference HealthScoreCreate,
HealthScoreRepository.bulk_create, and the data_source_id=None case so the
repository logic for handling internal (computed) scores is exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/tests/factories.py`:
- Around line 501-507: The _create method in HealthScoreFactory currently
discards any explicit data_source_id and always creates a DataSource, which
prevents tests from setting data_source_id=None; update
HealthScoreFactory._create so it first checks whether "data_source_id" exists in
kwargs (even if its value is None) and if present, use it as-is without creating
a DataSource; otherwise preserve the existing behavior of accepting a
data_source object via the data_source kwarg or creating a DataSourceFactory()
and setting kwargs["data_source_id"] to its id before calling super()._create.

In `@backend/tests/services/test_health_score_service.py`:
- Around line 93-95: The test has function-local imports inside test_bulk_create
(uuid4 and HealthScoreCreate); move these imports to module scope by adding
"from uuid import uuid4" and "from app.schemas.model_crud.activities import
HealthScoreCreate" at the top of the test file, then remove the in-function
import statements so test_bulk_create only uses those symbols without
re-importing them.

---

Duplicate comments:
In `@backend/tests/repositories/test_health_score_repository.py`:
- Around line 194-221: The test test_bulk_create_ignores_duplicates only covers
duplicates when data_source_id is set, but NULL data_source_id bypasses the DB
UNIQUE constraint; add a new test variant that creates two HealthScoreCreate
objects with data_source_id=None (same category and recorded_at) and calls
HealthScoreRepository.bulk_create twice, then query HealthScore to assert only
one row exists and its value matches the first insert; ensure you use the same
recorded_at and category and reference HealthScoreCreate,
HealthScoreRepository.bulk_create, and the data_source_id=None case so the
repository logic for handling internal (computed) scores is exercised.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 14e2a2a5-9486-4acc-a17e-73136f0f042b

📥 Commits

Reviewing files that changed from the base of the PR and between 936619c and c97dc47.

📒 Files selected for processing (7)
  • backend/app/repositories/health_score_repository.py
  • backend/app/schemas/model_crud/activities/health_score.py
  • backend/app/services/health_score_service.py
  • backend/tests/api/v1/test_health_scores.py
  • backend/tests/factories.py
  • backend/tests/repositories/test_health_score_repository.py
  • backend/tests/services/test_health_score_service.py
✅ Files skipped from review due to trivial changes (1)
  • backend/app/services/health_score_service.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • backend/app/schemas/model_crud/activities/health_score.py
  • backend/app/repositories/health_score_repository.py

Comment thread backend/tests/factories.py
Comment thread backend/tests/services/test_health_score_service.py Outdated
@railway-app
railway-app Bot temporarily deployed to Open Wearables / open-wearables-pr-804 April 8, 2026 12:22 Destroyed
@railway-app
railway-app Bot temporarily deployed to Open Wearables / open-wearables-pr-804 April 8, 2026 12:26 Destroyed

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (2)
backend/app/api/routes/v1/__init__.py (2)

64-64: Tag naming deviates from kebab-case guideline.

Per coding guidelines, tags should use "singular + kebab-case" (e.g., health-score). However, the current value "Health Scores" follows the pattern of adjacent tags ("Summaries", "Timeseries", "Events"). Consider aligning with the guideline for consistency if the team standardizes on kebab-case.

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

In `@backend/app/api/routes/v1/__init__.py` at line 64, The tag on the router
include uses a non-kebab-case plural string; update the call to
v1_router.include_router(health_scores_router, tags=[...]) to use the singular
kebab-case tag "health-score" instead of "Health Scores" so it matches the
project's "singular + kebab-case" convention and the other route tags.

11-11: Import is out of alphabetical order.

The health_scores import should come after garmin_webhooks (alphabetically: events < garmin_webhooks < health_scores). Running isort or pre-commit should fix this automatically.

Proposed fix
 from .events import router as events_router
-from .health_scores import router as health_scores_router
 from .garmin_webhooks import router as garmin_webhooks_router
+from .health_scores import router as health_scores_router
 from .import_xml import router as import_xml_router
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/app/api/routes/v1/__init__.py` at line 11, The import order is not
alphabetical: move the "from .health_scores import router as
health_scores_router" line so it appears after "from .garmin_webhooks import
router as garmin_webhooks_router" (ensuring the sequence is events_router,
garmin_webhooks_router, health_scores_router); alternatively run
isort/pre-commit to reorder imports automatically and verify the module-level
routers remain correctly named (events_router, garmin_webhooks_router,
health_scores_router).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@backend/app/api/routes/v1/__init__.py`:
- Line 64: The tag on the router include uses a non-kebab-case plural string;
update the call to v1_router.include_router(health_scores_router, tags=[...]) to
use the singular kebab-case tag "health-score" instead of "Health Scores" so it
matches the project's "singular + kebab-case" convention and the other route
tags.
- Line 11: The import order is not alphabetical: move the "from .health_scores
import router as health_scores_router" line so it appears after "from
.garmin_webhooks import router as garmin_webhooks_router" (ensuring the sequence
is events_router, garmin_webhooks_router, health_scores_router); alternatively
run isort/pre-commit to reorder imports automatically and verify the
module-level routers remain correctly named (events_router,
garmin_webhooks_router, health_scores_router).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 26b313c0-8efa-404b-82fd-6e653fadbbf0

📥 Commits

Reviewing files that changed from the base of the PR and between c97dc47 and 2a80e2c.

📒 Files selected for processing (6)
  • backend/app/api/routes/v1/__init__.py
  • backend/app/api/routes/v1/health_scores.py
  • backend/app/repositories/health_score_repository.py
  • backend/tests/api/v1/test_health_scores.py
  • backend/tests/repositories/test_health_score_repository.py
  • backend/tests/services/test_health_score_service.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • backend/tests/repositories/test_health_score_repository.py
  • backend/tests/api/v1/test_health_scores.py
  • backend/app/repositories/health_score_repository.py

@railway-app
railway-app Bot temporarily deployed to Open Wearables / open-wearables-pr-804 April 8, 2026 12:35 Destroyed

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/tests/factories.py (1)

492-508: Align default provider with generated data_source to avoid inconsistent fixtures.

Right now defaults can produce provider=GARMIN with a generated Apple data_source_id. That can make tests ambiguous.

Proposed adjustment
 class HealthScoreFactory(BaseFactory):
@@
-    provider = ProviderName.GARMIN
+    provider = ProviderName.APPLE
@@
     def _create(cls, model_class: type[HealthScore], *args: Any, **kwargs: Any) -> HealthScore:
         if "data_source_id" in kwargs:
             kwargs.pop("data_source", None)
         else:
             data_source = kwargs.pop("data_source", None)
             if data_source is None:
                 data_source = DataSourceFactory()
             kwargs["data_source_id"] = data_source.id
+            if "provider" not in kwargs:
+                kwargs["provider"] = data_source.provider
         return super()._create(model_class, *args, **kwargs)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/factories.py` around lines 492 - 508, The HealthScore factory
can produce mismatched defaults (provider=ProviderName.GARMIN) while creating a
DataSource with a different provider; update the _create method in the
HealthScore factory so that when you generate a DataSource (the data_source
variable created from DataSourceFactory()), you also set kwargs["provider"] =
data_source.provider unless a provider was explicitly passed in; keep existing
behavior when data_source_id is passed in and ensure you still set
kwargs["data_source_id"] = data_source.id after creating the DataSource.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/tests/factories.py`:
- Line 485: The new HealthScoreFactory class was added but not exported in the
module's __all__; update the module-level __all__ list to include
"HealthScoreFactory" so it is reachable by `from tests.factories import *`.
Locate the __all__ variable in this file and add the string "HealthScoreFactory"
alongside the other factory names (ensure exact spelling and quotes match
existing entries).

---

Nitpick comments:
In `@backend/tests/factories.py`:
- Around line 492-508: The HealthScore factory can produce mismatched defaults
(provider=ProviderName.GARMIN) while creating a DataSource with a different
provider; update the _create method in the HealthScore factory so that when you
generate a DataSource (the data_source variable created from
DataSourceFactory()), you also set kwargs["provider"] = data_source.provider
unless a provider was explicitly passed in; keep existing behavior when
data_source_id is passed in and ensure you still set kwargs["data_source_id"] =
data_source.id after creating the DataSource.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fa35e400-d5cf-49c0-a8f6-7b23b25b292e

📥 Commits

Reviewing files that changed from the base of the PR and between d74c4a2 and 23ce1b9.

📒 Files selected for processing (2)
  • backend/tests/factories.py
  • backend/tests/services/test_health_score_service.py
✅ Files skipped from review due to trivial changes (1)
  • backend/tests/services/test_health_score_service.py

return super()._create(model_class, *args, **kwargs)


class HealthScoreFactory(BaseFactory):

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

Export the new factory in __all__ for consistency with other factories.

HealthScoreFactory is added but not listed in the module export list, which can break from tests.factories import * patterns.

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

In `@backend/tests/factories.py` at line 485, The new HealthScoreFactory class was
added but not exported in the module's __all__; update the module-level __all__
list to include "HealthScoreFactory" so it is reachable by `from tests.factories
import *`. Locate the __all__ variable in this file and add the string
"HealthScoreFactory" alongside the other factory names (ensure exact spelling
and quotes match existing entries).

@czajkub
czajkub force-pushed the health-score-services branch from 23ce1b9 to d5c8524 Compare April 8, 2026 12:43
@railway-app
railway-app Bot temporarily deployed to Open Wearables / open-wearables-pr-804 April 8, 2026 12:44 Destroyed
@railway-app
railway-app Bot temporarily deployed to Open Wearables / open-wearables-pr-804 April 8, 2026 13:16 Destroyed
@czajkub
czajkub merged commit 5ddfde6 into main Apr 8, 2026
18 checks passed
@czajkub
czajkub deleted the health-score-services branch April 8, 2026 13:17
czajkub added a commit that referenced this pull request Apr 8, 2026

This branch was successfully deployed

No deployments
Open Wearables / open-wearables-pr-804 — 8c4028bc Deployed Apr 8, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Tickets related to the backend (FastAPI, Celery, database) health-scores Issues related to Health Scores (like Sleep Score, Stress Level etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants