feat: add Heap region support#7732
Conversation
|
@SahilJat is attempting to deploy a commit to the Flagsmith Team on Vercel. A member of the Team first needs to authorize it. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7732 +/- ##
==========================================
- Coverage 98.54% 98.39% -0.15%
==========================================
Files 1452 1453 +1
Lines 55793 55818 +25
==========================================
- Hits 54983 54924 -59
- Misses 810 894 +84 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@gemini-code-assist review |
There was a problem hiding this comment.
Code Review
This pull request introduces a configurable base_url for the Heap integration, allowing users to specify custom endpoints (such as for EU-based Heap instances) instead of relying on a hardcoded default. The changes include backend model updates, serializers, database migrations, unit tests, and frontend configuration. The reviewer's feedback focuses on ensuring data integrity by explicitly enforcing null=False and blank=False on the new base_url field in both the model and migration, as well as safely backfilling soft-deleted records during the migration using the all_objects manager.
|
|
||
|
|
||
| class HeapConfiguration(EnvironmentIntegrationModel): | ||
| base_url = models.URLField(default=DEFAULT_HEAP_API_URL) |
There was a problem hiding this comment.
Since IntegrationsModel defines base_url with null=True, overriding it here without explicitly setting null=False allows base_url to be set to None. This can lead to runtime errors when constructing the track URL (e.g., 'None/api/track'). Enforce null=False and blank=False to guarantee data integrity.
| base_url = models.URLField(default=DEFAULT_HEAP_API_URL) | |
| base_url = models.URLField(default=DEFAULT_HEAP_API_URL, null=False, blank=False) |
| heap_configuration_model.objects.filter( | ||
| Q(base_url__isnull=True) | Q(base_url="") | ||
| ).update(base_url="https://heapanalytics.com") |
There was a problem hiding this comment.
To prevent database migration failures when altering the base_url field to null=False, we must ensure that all existing records—including soft-deleted ones—are backfilled. Since HeapConfiguration inherits from SoftDeleteExportableModel, the default objects manager might filter out soft-deleted records depending on how the manager is configured or serialized in migrations. Using all_objects (or falling back to objects) ensures all records are safely updated.
| heap_configuration_model.objects.filter( | |
| Q(base_url__isnull=True) | Q(base_url="") | |
| ).update(base_url="https://heapanalytics.com") | |
| manager = getattr(heap_configuration_model, "all_objects", heap_configuration_model.objects) | |
| manager.filter( | |
| Q(base_url__isnull=True) | Q(base_url="") | |
| ).update(base_url="https://heapanalytics.com") |
| migrations.AlterField( | ||
| model_name="heapconfiguration", | ||
| name="base_url", | ||
| field=models.URLField(default="https://heapanalytics.com"), | ||
| ), |
There was a problem hiding this comment.
Update the AlterField operation to enforce null=False and blank=False in the database schema, matching the model definition and preventing future null values.
| migrations.AlterField( | |
| model_name="heapconfiguration", | |
| name="base_url", | |
| field=models.URLField(default="https://heapanalytics.com"), | |
| ), | |
| migrations.AlterField( | |
| model_name="heapconfiguration", | |
| name="base_url", | |
| field=models.URLField(default="https://heapanalytics.com", null=False, blank=False), | |
| ), |
Zaimwa9
left a comment
There was a problem hiding this comment.
Overall we are able to drop the database migration. I guess this was inspired by the amplitude but with heap the url field is null for all the integrations and previous records will still be using the same url.
So self.url = "{config.base_url or DEFAULT_HEAP_API_URL}/api/track" should do the job.
We are still discussing internally how to address the frontend so a first step would be to focus on the backend. We will discuss and come back to you
Thanks for submitting a PR! Please check the boxes below:
[x] I have read the Contributing Guide /Flagsmith/flagsmith/blob/main/CONTRIBUTING.md.
[ ] I have added information to docs/ if required so people know about the feature.
[x] I have filled in the "Changes" section below.
[x] I have filled in the "How did you test this code" section below.
Changes
Closes #7730
The Heap integration was hardcoded to target https://heapanalytics.com , preventing users with European Heap instances ( https://eu.heapanalytics.com ) from using the integration.
This PR adds base_url support to the Heap integration, following the same pattern as the existing Amplitude integration:
• api/integrations/heap/constants.py — New file with DEFAULT_HEAP_API_URL constant.
• api/integrations/heap/models.py — Override the inherited base_url field with a default value of https://heapanalytics.com .
• api/integrations/heap/heap.py — Use config.base_url instead of the hardcoded HEAP_API_URL constant.
• api/integrations/heap/serializers.py — Expose base_url in the API serializer fields.
• api/integrations/heap/migrations/0004_add_default_base_url.py — Data migration to backfill existing rows with the default URL + alter the field to set a default.
• frontend/common/stores/default-flags.ts — Add base_url field to the Heap integration UI configuration.
This change is fully backwards compatible — existing configurations receive the default US URL via the data migration, and new configurations without an explicit base_url also default to US.
How did you test this code?
Unit tests
Added and updated tests in:
• api/tests/unit/integrations/heap/test_unit_heap.py :
• Existing test now asserts default URL resolves to https://heapanalytics.com/api/track .
• New test test_heap_wrapper__eu_base_url__uses_eu_url verifies EU URL is used correctly.
• api/tests/unit/integrations/heap/test_unit_heap_views.py :
• Updated list test to assert base_url is present in API response with default value.
• Updated create test to verify default base_url is set when omitted.
• New test test_create_heap_config__with_eu_base_url__returns_created verifies creating a config with a custom EU base URL.
Manual verification
Start the API: cd api && make serve
Create a Heap config without base_url — confirm it defaults to https://heapanalytics.com :
curl -X POST http://localhost:8000/api/v1/environments/<ENV_KEY>/integrations/heap/
-H "Authorization: Token "
-H "Content-Type: application/json"
-d '{"api_key": "test-key"}'
Create a Heap config with EU base_url — confirm it is stored and returned:
curl -X POST http://localhost:8000/api/v1/environments/<ENV_KEY>/integrations/heap/
-H "Authorization: Token "
-H "Content-Type: application/json"
-d '{"api_key": "test-key", "base_url": "https://eu.heapanalytics.com"}'
Start the frontend ( cd frontend && ENV=local npm run dev ) and navigate to Integrations → Heap Analytics — confirm the "Base URL" field is visible alongside the API Key field.