├── .do └── deploy.template.yaml ├── .dockerignore ├── .dokku-monorepo ├── .git-blame-ignore-revs ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── actions │ ├── api-deploy-ecs │ │ └── action.yml │ ├── docker-build-report-to-pr │ │ └── action.yml │ ├── e2e-tests │ │ └── action.yml │ └── task-processor-deploy-ecs │ │ └── action.yml ├── dependabot.yml ├── docker_build_comment_template.md ├── labeler.yml ├── pull_request_template.md └── workflows │ ├── .reusable-deploy-ecs.yml │ ├── .reusable-docker-build.yml │ ├── .reusable-docker-e2e-tests.yml │ ├── .reusable-docker-publish.yml │ ├── .reusable-frontend-deploy.yml │ ├── api-deploy-production-ecs.yml │ ├── api-deploy-staging-ecs.yml │ ├── api-pull-request.yml │ ├── api-tests-with-private-packages.yml │ ├── conventional-commit.yml │ ├── docs-cron-vercel-deploy.yml │ ├── docs-pull-request.yml │ ├── frontend-deploy-production.yml │ ├── frontend-test-staging.yml │ ├── github-labeler.yml │ ├── manual-e2e-tests.yml │ ├── platform-docker-build-e2e-image.yml │ ├── platform-docker-build-test-publish.yml │ ├── platform-docker-trivy-scan.yml │ ├── platform-pull-request.yml │ ├── platform-release-please.yml │ └── update-flagsmith-environment.yml ├── .gitignore ├── .husky └── pre-commit ├── .pre-commit-config.yaml ├── .prettierignore ├── .prettierrc.json ├── .release-please-manifest.json ├── CHANGELOG.md ├── CODEOWNERS ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE.md ├── Makefile ├── README.md ├── SECURITY.md ├── api ├── .ebextensions │ ├── 00__packages.config │ ├── 01__upgrade_pip.config │ ├── 02__collectstatic.config │ ├── 03__django.config │ └── 04__wsgi_custom.config ├── .ebignore ├── .env-ci ├── .env-local ├── .gitignore ├── Makefile ├── Procfile ├── api │ ├── __init__.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20170619_1243.py │ │ ├── 0003_auto_20170619_1255.py │ │ ├── 0004_identity_uuid.py │ │ ├── 0005_auto_20180514_1557.py │ │ ├── 0006_auto_20180514_1622.py │ │ ├── 0007_auto_20180517_1011.py │ │ ├── 0008_auto_20180517_1104.py │ │ ├── 0009_auto_20180517_1418.py │ │ ├── 0010_remove_identity_hash.py │ │ ├── 0011_auto_20180517_1646.py │ │ ├── 0012_delete_ffadminuser.py │ │ ├── 0013_featurestate_value.py │ │ ├── 0014_auto_20180522_0928.py │ │ ├── 0015_auto_20180522_0931.py │ │ ├── 0016_auto_20180522_1311.py │ │ ├── 0017_feature_description.py │ │ ├── 0018_auto_20180524_1521.py │ │ ├── 0019_auto_20180525_1436.py │ │ ├── 0020_auto_20180525_1541.py │ │ ├── 0021_auto_20180525_1651.py │ │ └── __init__.py │ ├── models.py │ ├── openapi.py │ ├── serializers.py │ └── urls │ │ ├── __init__.py │ │ ├── deprecated.py │ │ ├── v1.py │ │ └── v2.py ├── api_keys │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── authentication.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_soft_delete_api_keys.py │ │ ├── 0003_masterapikey_is_admin.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── user.py │ └── views.py ├── app │ ├── __init__.py │ ├── exceptions.py │ ├── handlers.py │ ├── pagination.py │ ├── routers.py │ ├── settings │ │ ├── __init__.py │ │ ├── common.py │ │ ├── develop.py │ │ ├── local.py │ │ ├── production.py │ │ └── test.py │ ├── templates │ │ ├── .gitignore │ │ ├── robots.txt │ │ └── webpack │ │ │ └── .gitkeep │ ├── urls.py │ ├── utils.py │ ├── views.py │ └── wsgi.py ├── app_analytics │ ├── __init__.py │ ├── analytics_db_service.py │ ├── apps.py │ ├── cache.py │ ├── constants.py │ ├── dataclasses.py │ ├── influxdb_schema.py │ ├── influxdb_wrapper.py │ ├── management │ │ └── commands │ │ │ ├── migrate_analytics.py │ │ │ ├── populate_buckets.py │ │ │ └── sendapiusagetoinflux.py │ ├── middleware.py │ ├── migrate_to_pg.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_featureevaluationraw_identifier_and_index_feature.py │ │ ├── 0003_add_feature_name_index.py │ │ ├── 0004_apiusageraw_count.py │ │ ├── 0005_featureevaluationraw_created_at_idx.py │ │ └── __init__.py │ ├── models.py │ ├── permissions.py │ ├── query.py │ ├── serializers.py │ ├── services.py │ ├── tasks.py │ ├── track.py │ ├── types.py │ └── views.py ├── audit │ ├── __init__.py │ ├── apps.py │ ├── constants.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20190909_1153.py │ │ ├── 0003_auto_20190910_1545.py │ │ ├── 0004_auto_20200504_1322.py │ │ ├── 0005_auditlog_skip_signals.py │ │ ├── 0006_auditlog_master_api_key.py │ │ ├── 0007_auditlog_is_system_event.py │ │ ├── 0008_attach_historical_record_to_audit_log.py │ │ ├── 0010_do_nothing_on_project_or_environment_delete.py │ │ ├── 0011_auditlog_related_object_uuid.py │ │ ├── 0012_auto_20230517_1006.py │ │ ├── 0013_allow_manual_override_of_created_date.py │ │ └── __init__.py │ ├── models.py │ ├── permissions.py │ ├── related_object_type.py │ ├── serializers.py │ ├── services.py │ ├── signals.py │ ├── tasks.py │ ├── urls.py │ └── views.py ├── conftest.py ├── core │ ├── __init__.py │ ├── apps.py │ ├── constants.py │ ├── custom_admin │ │ ├── __init__.py │ │ ├── admin.py │ │ └── apps.py │ ├── helpers.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ ├── __init__.py │ │ │ ├── bootstrap.py │ │ │ ├── makemigrations.py │ │ │ ├── rollbackmigrationsappliedafter.py │ │ │ └── waitfordb.py │ ├── middleware │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── axes.py │ │ └── cache_control.py │ ├── migration_helpers.py │ ├── models.py │ ├── redis_cluster.py │ ├── request_origin.py │ ├── signals.py │ ├── signing.py │ ├── throttling.py │ └── workflows_services.py ├── custom_auth │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── constants.py │ ├── jwt_cookie │ │ ├── __init__.py │ │ ├── authentication.py │ │ ├── constants.py │ │ ├── services.py │ │ ├── signals.py │ │ └── views.py │ ├── mfa │ │ ├── __init__.py │ │ ├── backends │ │ │ ├── __init__.py │ │ │ └── application.py │ │ └── trench │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── apps.py │ │ │ ├── backends │ │ │ └── __init__.py │ │ │ ├── command │ │ │ ├── __init__.py │ │ │ ├── activate_mfa_method.py │ │ │ ├── authenticate_second_factor.py │ │ │ ├── create_mfa_method.py │ │ │ ├── create_secret.py │ │ │ ├── deactivate_mfa_method.py │ │ │ ├── generate_backup_codes.py │ │ │ ├── remove_backup_code.py │ │ │ ├── replace_mfa_method_backup_codes.py │ │ │ └── validate_backup_code.py │ │ │ ├── exceptions.py │ │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20190111_1403.py │ │ │ ├── 0003_auto_20190213_2330.py │ │ │ ├── 0004_add_created_at_and_updated_at.py │ │ │ └── __init__.py │ │ │ ├── models.py │ │ │ ├── responses.py │ │ │ ├── serializers.py │ │ │ ├── urls │ │ │ ├── __init__.py │ │ │ └── base.py │ │ │ ├── utils.py │ │ │ └── views │ │ │ ├── __init__.py │ │ │ └── base.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── oauth │ │ ├── __init__.py │ │ ├── exceptions.py │ │ ├── github.py │ │ ├── google.py │ │ ├── helpers │ │ │ ├── __init__.py │ │ │ └── github_helpers.py │ │ ├── serializers.py │ │ ├── urls.py │ │ └── views.py │ ├── permissions.py │ ├── serializers.py │ ├── tasks.py │ ├── urls.py │ └── views.py ├── e2etests │ ├── __init__.py │ ├── e2e_seed_data.py │ ├── middleware.py │ ├── permissions.py │ ├── urls.py │ └── views.py ├── edge_api │ ├── __init__.py │ ├── apps.py │ ├── identities │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── edge_identity_service.py │ │ ├── edge_request_forwarder.py │ │ ├── events.py │ │ ├── exceptions.py │ │ ├── export.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── search.py │ │ ├── serializers.py │ │ ├── tasks.py │ │ ├── types.py │ │ ├── utils.py │ │ └── views.py │ └── management │ │ └── commands │ │ ├── __init__.py │ │ ├── ensure_identity_traits_blanks.py │ │ └── migrate_to_edge_v2.py ├── environments │ ├── __init__.py │ ├── admin.py │ ├── api_keys.py │ ├── apps.py │ ├── authentication.py │ ├── constants.py │ ├── dynamodb │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── migrator.py │ │ ├── services.py │ │ ├── types.py │ │ ├── utils.py │ │ └── wrappers │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── environment_api_key_wrapper.py │ │ │ ├── environment_wrapper.py │ │ │ ├── exceptions.py │ │ │ └── identity_wrapper.py │ ├── enums.py │ ├── exceptions.py │ ├── identities │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── helpers.py │ │ ├── managers.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_alter_identity_index_together.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ ├── traits │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── constants.py │ │ │ ├── exceptions.py │ │ │ ├── fields.py │ │ │ ├── migrations │ │ │ │ ├── 0001_initial.py │ │ │ │ ├── 0002_alter_trait_boolean_value.py │ │ │ │ └── __init__.py │ │ │ ├── models.py │ │ │ ├── serializers.py │ │ │ └── views.py │ │ └── views.py │ ├── management │ │ ├── __init__.py │ │ ├── commands │ │ │ ├── __init__.py │ │ │ └── migrate_to_edge.py │ │ └── serializers.py │ ├── managers.py │ ├── metrics.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20180809_0014.py │ │ ├── 0003_auto_20180925_0915.py │ │ ├── 0004_auto_20181026_1438.py │ │ ├── 0005_auto_20181128_1013.py │ │ ├── 0006_auditlog.py │ │ ├── 0007_auto_20190827_1528.py │ │ ├── 0008_webhook.py │ │ ├── 0009_auto_20200219_1922.py │ │ ├── 0010_auto_20200219_2343.py │ │ ├── 0011_auto_20200220_0044.py │ │ ├── 0012_auto_20200504_1322.py │ │ ├── 0013_auto_20200619_1321.py │ │ ├── 0014_auto_20200917_1032.py │ │ ├── 0015_auto_20200916_1441.py │ │ ├── 0016_webhook_secret.py │ │ ├── 0017_add_environment_api_key_model.py │ │ ├── 0018_add_minimum_change_request_approvals_to_environment.py │ │ ├── 0019_allow_blank_minimum_change_request_approvals.py │ │ ├── 0020_add_uuid_field_to_environment_webhook.py │ │ ├── 0021_environment_allow_client_traits.py │ │ ├── 0022_environment_description.py │ │ ├── 0023_environment_updated_at.py │ │ ├── 0024_auto_20221206_0601.py │ │ ├── 0025_soft_delete_environments.py │ │ ├── 0026_add_auditable_base_class_to_environment_model.py │ │ ├── 0027_auto_20230106_0626.py │ │ ├── 0028_add_use_mv_v2_evaluation.py │ │ ├── 0029_auto_20230314_0443.py │ │ ├── 0030_auto_20230518_0338.py │ │ ├── 0031_alter_webhook_url.py │ │ ├── 0032_rename_use_mv_v2_evaluation_to_use_in_percentage_split_evaluation.py │ │ ├── 0033_add_environment_feature_state_version_logic.py │ │ ├── 0034_alter_environment_project.py │ │ ├── 0035_add_use_identity_overrides_in_local_eval.py │ │ ├── 0036_add_is_creating_field.py │ │ ├── 0037_add_uuid_field.py │ │ └── __init__.py │ ├── models.py │ ├── permissions │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── managers.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_update_feature_state_permission.py │ │ │ ├── 0003_add_manage_identities_permission.py │ │ │ ├── 0004_add_change_request_permissions.py │ │ │ ├── 0005_add_view_identity_permissions.py │ │ │ ├── 0006_merge_duplicate_permissions.py │ │ │ ├── 0007_add_unique_permission_constraint.py │ │ │ ├── 0008_add_manage_segment_overrides_permission.py │ │ │ ├── 0009_add_environment_feature_state_version_logic.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ └── views.py │ ├── sdk │ │ ├── __init__.py │ │ ├── schemas.py │ │ ├── serializers.py │ │ ├── serializers_mixins.py │ │ ├── services.py │ │ ├── types.py │ │ └── views.py │ ├── serializers.py │ ├── tasks.py │ ├── urls.py │ └── views.py ├── features │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── audit_helpers.py │ ├── constants.py │ ├── custom_lifecycle.py │ ├── dataclasses.py │ ├── exceptions.py │ ├── feature_external_resources │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_featureexternalresource_feature_ext_type_2b2068_idx.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ └── views.py │ ├── feature_health │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── constants.py │ │ ├── mappers.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_featurehealthevent_add_external_id_alter_created_at.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── providers │ │ │ ├── __init__.py │ │ │ ├── grafana │ │ │ │ ├── __init__.py │ │ │ │ ├── constants.py │ │ │ │ ├── mappers.py │ │ │ │ ├── services.py │ │ │ │ └── types.py │ │ │ ├── sample │ │ │ │ ├── __init__.py │ │ │ │ ├── mappers.py │ │ │ │ ├── services.py │ │ │ │ └── types.py │ │ │ └── services.py │ │ ├── serializers.py │ │ ├── services.py │ │ ├── tasks.py │ │ ├── types.py │ │ └── views.py │ ├── feature_segments │ │ ├── __init__.py │ │ ├── limits.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ └── views.py │ ├── feature_states │ │ ├── __init__.py │ │ └── models.py │ ├── feature_types.py │ ├── features_service.py │ ├── fields.py │ ├── helpers.py │ ├── import_export │ │ ├── apps.py │ │ ├── constants.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_status_and_data_featureexport.py │ │ │ ├── 0003_flagsmithonflagsmithfeatureexport.py │ │ │ ├── 0004_convert_data_fields_to_text_field.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ ├── tasks.py │ │ └── views.py │ ├── managers.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20180530_0724.py │ │ ├── 0003_auto_20180601_1038.py │ │ ├── 0004_auto_20180604_1259.py │ │ ├── 0005_auto_20180604_1348.py │ │ ├── 0006_featurestate_type.py │ │ ├── 0007_feature_default_enabled.py │ │ ├── 0008_auto_20180608_1328.py │ │ ├── 0009_auto_20180809_0014.py │ │ ├── 0009_auto_20180815_1011.py │ │ ├── 0010_merge_20180816_1531.py │ │ ├── 0011_historicalfeature_squashed_0012_historicalfeaturestate_historicalfeaturestatevalue.py │ │ ├── 0012_auto_20190424_1555.py │ │ ├── 0013_auto_20190607_1109.py │ │ ├── 0014_auto_20190607_1642.py │ │ ├── 0015_auto_20190916_1338.py │ │ ├── 0016_auto_20190916_1717.py │ │ ├── 0017_auto_20200607_1005.py │ │ ├── 0018_auto_20200607_1057.py │ │ ├── 0019_auto_20200607_1059.py │ │ ├── 0020_auto_20200615_1300.py │ │ ├── 0021_historicalfeaturesegment.py │ │ ├── 0022_auto_20200630_2115.py │ │ ├── 0023_auto_20200717_1515.py │ │ ├── 0024_auto_20200917_1032.py │ │ ├── 0025_alter_unique_constraints_for_feature_states.py │ │ ├── 0025_enable_all_remote_config_feature_states.py │ │ ├── 0026_auto_20210110_1300.py │ │ ├── 0027_merge_20210215_1059.py │ │ ├── 0028_auto_20210216_1600.py │ │ ├── 0028_auto_20210223_2039.py │ │ ├── 0029_auto_20210223_2106.py │ │ ├── 0030_auto_20210401_1552.py │ │ ├── 0030_merge_20210305_1622.py │ │ ├── 0031_merge_20210409_1621.py │ │ ├── 0032_update_feature_type.py │ │ ├── 0033_auto_20210918_1048.py │ │ ├── 0033_feature_owners.py │ │ ├── 0034_merge_20210930_0502.py │ │ ├── 0035_auto_20211109_0603.py │ │ ├── 0036_alter_feature_options.py │ │ ├── 0036_remove_existing_constraints.py │ │ ├── 0037_add_feature_state_versioning_fields.py │ │ ├── 0038_remove_old_versions_and_drafts.py │ │ ├── 0039_allow_null_version.py │ │ ├── 0039_merge_20220329_1252.py │ │ ├── 0040_add_change_request_to_feature_state.py │ │ ├── 0041_merge_20220406_0806.py │ │ ├── 0042_default_type_to_STANDARD.py │ │ ├── 0043_add_uuid_field_to_feature.py │ │ ├── 0044_add_uuid_field_to_feature_state.py │ │ ├── 0045_add_uuid_field_to_feature_state_value.py │ │ ├── 0046_add_uuid_field_to_feature_segment.py │ │ ├── 0047_prevent_null_feature_type.py │ │ ├── 0048_add_master_api_key_to_historical_records.py │ │ ├── 0049_safe_delete_feature_models.py │ │ ├── 0050_remove_unique_indexes.py │ │ ├── 0051_permanently_delete_soft_deleted_features.py │ │ ├── 0052_add_feature_state_value_audit.py │ │ ├── 0053_delete_historical_feature_segment.py │ │ ├── 0054_add_missing_migration.py │ │ ├── 0055_add_feature_segment_audit_log_for_delete.py │ │ ├── 0056_alter_featurestate_change_request.py │ │ ├── 0057_add_feature_is_server_key_only.py │ │ ├── 0058_alter_boolean_values.py │ │ ├── 0059_fix_feature_type.py │ │ ├── 0060_feature_group_owners.py │ │ ├── 0061_add_environment_feature_state_version_logic.py │ │ ├── 0062_alter_feature_segment_unique_together.py │ │ ├── 0063_detach_feature_from_project_cascade_delete.py │ │ ├── 0064_fix_feature_help_text_typo.py │ │ ├── 0065_make_feature_value_size_configurable.py │ │ └── __init__.py │ ├── models.py │ ├── multivariate │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_unique_constraint_for_mv_feature_states.py │ │ │ ├── 0002_auto_20220124_0722.py │ │ │ ├── 0003_merge_20220131_1532.py │ │ │ ├── 0004_alter_multivariatefeatureoption_string_value.py │ │ │ ├── 0005_add_uuid_fields.py │ │ │ ├── 0006_add_audit_log_events_form_multivariate_models.py │ │ │ ├── 0007_alter_boolean_values.py │ │ │ ├── 0008_make_feature_value_size_configurable.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ ├── urls.py │ │ └── views.py │ ├── permissions.py │ ├── serializers.py │ ├── signals.py │ ├── tasks.py │ ├── templates │ │ └── features │ │ │ └── webhook_failure.txt │ ├── urls.py │ ├── utils.py │ ├── value_types.py │ ├── versioning │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── constants.py │ │ ├── dataclasses.py │ │ ├── exceptions.py │ │ ├── managers.py │ │ ├── migrations │ │ │ ├── 0001_add_environment_feature_state_version_logic.py │ │ │ ├── 0002_add_api_key_for_creation_and_publish.py │ │ │ ├── 0003_cascade_delete_versions_on_cr_delete.py │ │ │ ├── 0004_add_version_change_set.py │ │ │ ├── 0005_fix_scheduled_fs_data_issue_caused_by_enabling_versioning.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── receivers.py │ │ ├── schemas.py │ │ ├── serializers.py │ │ ├── signals.py │ │ ├── sql │ │ │ └── get_latest_versions.sql │ │ ├── tasks.py │ │ ├── templates │ │ │ └── versioning │ │ │ │ └── scheduled_change_failed_conflict_email.txt │ │ ├── urls.py │ │ ├── versioning_service.py │ │ └── views.py │ ├── views.py │ └── workflows │ │ ├── __init__.py │ │ └── core │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── exceptions.py │ │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_add_uuid_field.py │ │ ├── 0003_add_historical_change_request.py │ │ ├── 0004_add_historical_change_request_approvals.py │ │ ├── 0005_soft_delete_change_requests.py │ │ ├── 0006_auto_20230518_1036.py │ │ ├── 0007_add_change_request_group_assignment.py │ │ ├── 0008_remove_redundant_column.py │ │ ├── 0009_prevent_cascade_delete_from_user_delete.py │ │ ├── 0010_add_ignore_conflicts_option.py │ │ ├── 0011_add_project_to_change_requests.py │ │ ├── 0012_alter_changerequest_options.py │ │ └── __init__.py │ │ ├── models.py │ │ └── templates │ │ └── workflows_core │ │ ├── change_request_approved_author_notification.html │ │ ├── change_request_approved_author_notification.txt │ │ ├── change_request_assignee_notification.html │ │ └── change_request_assignee_notification.txt ├── import_export │ ├── __init__.py │ ├── export.py │ ├── import_.py │ ├── json_serializers_with_metadata_support.py │ └── management │ │ ├── __init__.py │ │ └── commands │ │ ├── __init__.py │ │ ├── dumporganisationtolocalfs.py │ │ ├── dumporganisationtos3.py │ │ └── importorganisationfroms3.py ├── integrations │ ├── __init__.py │ ├── amplitude │ │ ├── __init__.py │ │ ├── amplitude.py │ │ ├── apps.py │ │ ├── constants.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20210325_1414.py │ │ │ ├── 0003_amplitudeconfiguration_uuid.py │ │ │ ├── 0004_make_uuid_not_editable.py │ │ │ ├── 0005_amplitudeconfiguration_deleted_at.py │ │ │ ├── 0006_add_default_base_url.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ └── views.py │ ├── common │ │ ├── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ ├── views.py │ │ └── wrapper.py │ ├── datadog │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── datadog.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_uuid_field.py │ │ │ ├── 0003_datadogconfiguration_deleted_at.py │ │ │ ├── 0004_add_use_custom_source.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ └── views.py │ ├── dynatrace │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── dynatrace.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_uuid_field.py │ │ │ ├── 0003_dynatraceconfiguration_deleted_at.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ └── views.py │ ├── flagsmith │ │ ├── __init__.py │ │ ├── client.py │ │ ├── data │ │ │ └── environment.json │ │ ├── exceptions.py │ │ ├── flagsmith_service.py │ │ └── management │ │ │ ├── __init__.py │ │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── updateflagsmithenvironment.py │ ├── github │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── client.py │ │ ├── constants.py │ │ ├── dataclasses.py │ │ ├── exceptions.py │ │ ├── github.py │ │ ├── helpers.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20240502_1949.py │ │ │ ├── 0003_auto_20240528_0640.py │ │ │ ├── 0004_githubrepository_tagging_enabled.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ ├── tasks.py │ │ └── views.py │ ├── grafana │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── grafana.py │ │ ├── mappers.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_grafana_organisation_configuration.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ ├── types.py │ │ └── views.py │ ├── heap │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── heap.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_uuid_field.py │ │ │ ├── 0003_heapconfiguration_deleted_at.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ └── views.py │ ├── integration.py │ ├── launch_darkly │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── client.py │ │ ├── constants.py │ │ ├── exceptions.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_importrequest_unique_project_ld_project_key_status_result_null.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ ├── services.py │ │ ├── tasks.py │ │ ├── types.py │ │ └── views.py │ ├── lead_tracking │ │ ├── __init__.py │ │ ├── hubspot │ │ │ ├── client.py │ │ │ ├── constants.py │ │ │ ├── lead_tracker.py │ │ │ ├── services.py │ │ │ └── tasks.py │ │ ├── lead_tracking.py │ │ └── pipedrive │ │ │ ├── __init__.py │ │ │ ├── client.py │ │ │ ├── constants.py │ │ │ ├── exceptions.py │ │ │ ├── lead_tracker.py │ │ │ ├── models.py │ │ │ └── schemas.py │ ├── mixpanel │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_uuid_field.py │ │ │ ├── 0003_mixpanelconfiguration_deleted_at.py │ │ │ └── __init__.py │ │ ├── mixpanel.py │ │ ├── models.py │ │ ├── serializers.py │ │ └── views.py │ ├── new_relic │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20210325_1414.py │ │ │ ├── 0003_add_uuid_field.py │ │ │ ├── 0004_newrelicconfiguration_deleted_at.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── new_relic.py │ │ ├── serializers.py │ │ └── views.py │ ├── opencensus │ │ ├── __init__.py │ │ ├── middleware.py │ │ └── querylogger.py │ ├── rudderstack │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_uuid_field.py │ │ │ ├── 0003_rudderstackconfiguration_deleted_at.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── rudderstack.py │ │ ├── serializers.py │ │ └── views.py │ ├── segment │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── constants.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20210325_1414.py │ │ │ ├── 0003_add_uuid_field.py │ │ │ ├── 0004_segmentconfiguration_deleted_at.py │ │ │ ├── 0005_set_base_url_to_default.py │ │ │ ├── 0006_set_base_url_to_default_again.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── segment.py │ │ ├── serializers.py │ │ └── views.py │ ├── sentry │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── middleware.py │ │ └── samplers.py │ ├── slack │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── authentication.py │ │ ├── exceptions.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_uuid_fields.py │ │ │ ├── 0003_slackconfiguration_deleted_at.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ ├── slack.py │ │ └── views.py │ └── webhook │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_add_uuid_field.py │ │ ├── 0003_webhookconfiguration_deleted_at.py │ │ ├── 0004_alter_webhookconfiguration_url.py │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ ├── views.py │ │ └── webhook.py ├── jmeter-tests │ └── Home Page.jmx ├── manage.py ├── metadata │ ├── __init__.py │ ├── apps.py │ ├── fields.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── permissions.py │ ├── serializers.py │ ├── urls.py │ └── views.py ├── onboarding │ ├── __init__.py │ ├── apps.py │ ├── serializers.py │ ├── tasks.py │ ├── throttling.py │ ├── urls.py │ └── views.py ├── openapi-filter-grafana.yaml ├── openapi-filter-launchdarkly.yaml ├── organisations │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── chargebee │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── cache.py │ │ ├── chargebee.py │ │ ├── constants.py │ │ ├── metadata.py │ │ ├── serializers.py │ │ ├── tasks.py │ │ ├── webhook_event_types.py │ │ └── webhook_handlers.py │ ├── constants.py │ ├── exceptions.py │ ├── invites │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── exceptions.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20210118_2026.py │ │ │ ├── 0003_auto_20220323_1455.py │ │ │ ├── 0004_remove_invite_frontend_base_url.py │ │ │ ├── 0005_add_uuid_field.py │ │ │ ├── 0006_invite_permission_groups.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── serializers.py │ │ └── views.py │ ├── management │ │ └── commands │ │ │ ├── check_if_organisations_over_plan_limit.py │ │ │ └── createinitialorganisation.py │ ├── managers.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_organisation_has_requested_features.py │ │ ├── 0003_organisation_webhook_notification_email.py │ │ ├── 0004_organisation_created_date.py │ │ ├── 0005_auto_20181025_1611.py │ │ ├── 0006_auto_20181030_1438.py │ │ ├── 0007_organisation_pending_cancellation.py │ │ ├── 0008_auto_20181108_1259.py │ │ ├── 0009_auto_20181108_1306.py │ │ ├── 0010_subscription.py │ │ ├── 0011_subscription_max_seats.py │ │ ├── 0012_auto_20190912_1538.py │ │ ├── 0013_organisation_alerted_over_plan_limit.py │ │ ├── 0014_organisation_stop_serving_flags.py │ │ ├── 0014_userorganisation.py │ │ ├── 0015_auto_20190924_1641.py │ │ ├── 0016_auto_20190924_1716.py │ │ ├── 0017_subscription_cancellation_date.py │ │ ├── 0018_merge_20191003_1249.py │ │ ├── 0019_subscription_customer_id.py │ │ ├── 0020_auto_20200222_1159.py │ │ ├── 0021_auto_20200619_1555.py │ │ ├── 0022_organisation_persist_trait_data.py │ │ ├── 0023_organisation_block_access_to_admin.py │ │ ├── 0024_organisation_feature_analytics.py │ │ ├── 0025_auto_20210223_1603.py │ │ ├── 0026_auto_20210907_1232.py │ │ ├── 0027_organisation_restrict_project_create_to_admin.py │ │ ├── 0028_organisationwebhook_secret.py │ │ ├── 0029_add_max_api_calls_to_subscription_model.py │ │ ├── 0030_alter_userorganisation_role.py │ │ ├── 0031_alter_subscription_plan.py │ │ ├── 0032_add_uuid_fields.py │ │ ├── 0033_allow_blank_payment_method.py │ │ ├── 0034_alter_subscription_payment_method.py │ │ ├── 0035_add_organisation_subscription_information_cache.py │ │ ├── 0036_alter_subscription_plan.py │ │ ├── 0037_add_default_subscription_to_existing_organisations.py │ │ ├── 0038_soft_delete_organisations.py │ │ ├── 0039_subscription_deleted_at.py │ │ ├── 0040_alter_organisationwebhook_url.py │ │ ├── 0040_organisationsubscriptioninformationcache_chargebee_email.py │ │ ├── 0041_merge_20230621_0946.py │ │ ├── 0042_alter_subscription_payment_method.py │ │ ├── 0043_add_created_at_and_updated_at_to_organisationwebhook.py │ │ ├── 0044_organisationsubscriptioninformationcache_allowed_projects.py │ │ ├── 0045_auto_20230802_1956.py │ │ ├── 0046_allow_allowed_projects_to_be_null.py │ │ ├── 0047_organisation_force_2fa.py │ │ ├── 0048_add_default_subscription_to_orphaned_organisations.py │ │ ├── 0049_subscription_billing_status.py │ │ ├── 0050_add_historical_subscription.py │ │ ├── 0051_create_org_api_usage_notification.py │ │ ├── 0052_create_hubspot_organisation.py │ │ ├── 0053_create_api_limit_access_block.py │ │ ├── 0054_create_api_billing.py │ │ ├── 0055_alter_percent_usage.py │ │ ├── 0056_create_organisation_breached_grace_period.py │ │ ├── 0057_limit_audit_and_version_history.py │ │ ├── 0058_update_audit_and_history_limits_in_sub_cache.py │ │ └── __init__.py │ ├── models.py │ ├── permissions │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_add_related_query_name.py │ │ │ ├── 0003_merge_duplicate_permissions.py │ │ │ ├── 0004_add_unique_permission_constraint.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ └── views.py │ ├── serializers.py │ ├── subscription_info_cache.py │ ├── subscriptions │ │ ├── __init__.py │ │ ├── constants.py │ │ ├── decorators.py │ │ ├── exceptions.py │ │ ├── metadata.py │ │ ├── serializers │ │ │ ├── __init__.py │ │ │ └── mixins.py │ │ └── xero │ │ │ ├── __init__.py │ │ │ └── metadata.py │ ├── task_helpers.py │ ├── tasks.py │ ├── templates │ │ └── organisations │ │ │ ├── api_flags_blocked_notification.html │ │ │ ├── api_flags_blocked_notification.txt │ │ │ ├── api_usage_notification.html │ │ │ ├── api_usage_notification.txt │ │ │ ├── api_usage_notification_limit.html │ │ │ └── api_usage_notification_limit.txt │ ├── urls.py │ └── views.py ├── permissions │ ├── __init__.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20200221_2126.py │ │ ├── 0003_add_organisation_permission_type.py │ │ ├── 0004_add_create_project_permission.py │ │ ├── 0005_orphan_permission_cleanup.py │ │ ├── 0006_add_manage_segments_permission.py │ │ ├── 0007_add_invite_users_and_manage_user_groups_org_permissions.py │ │ ├── 0008_add_view_audit_log_permission.py │ │ ├── 0009_move_view_audit_log_permission.py │ │ ├── 0010_add_manage_tags_permission.py │ │ └── __init__.py │ ├── models.py │ ├── permission_service.py │ ├── permissions_calculator.py │ ├── rbac_wrapper.py │ └── serializers.py ├── poetry.lock ├── projects │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── exceptions.py │ ├── management │ │ └── commands │ │ │ └── createinitialproject.py │ ├── managers.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_projectpermission_userpermissiongroupprojectpermission_userprojectpermission.py │ │ ├── 0003_auto_20200216_2050.py │ │ ├── 0004_auto_20200220_0044.py │ │ ├── 0005_auto_20200221_2317.py │ │ ├── 0006_auto_20200224_2106.py │ │ ├── 0007_auto_20200504_1322.py │ │ ├── 0008_project_hide_disabled_flags.py │ │ ├── 0009_project_enable_dynamo_db.py │ │ ├── 0010_auto_20211208_1050.py │ │ ├── 0011_add_uuid_field.py │ │ ├── 0012_add_prevent_flag_defaults_to_project.py │ │ ├── 0013_project_enable_realtime_updates.py │ │ ├── 0014_project_only_allow_lower_case_feature_names.py │ │ ├── 0015_project_feature_name_regex.py │ │ ├── 0016_soft_delete_projects.py │ │ ├── 0017_merge_duplicate_permissions.py │ │ ├── 0018_add_unique_permission_constraint.py │ │ ├── 0019_add_limits.py │ │ ├── 0020_add_environment_feature_state_version_logic.py │ │ ├── 0021_add_identity_overrides_migration_status.py │ │ ├── 0022_add_stale_flags_threshold_to_project.py │ │ ├── 0023_rename_identity_overrides_migration_status_keeping_db_column.py │ │ ├── 0024_add_project_edge_v2_migration_read_capacity_budget.py │ │ ├── 0025_add_change_request_project_permissions.py │ │ ├── 0026_add_change_request_approval_limit_to_projects.py │ │ ├── 0027_add_create_project_level_change_requests_permission.py │ │ └── __init__.py │ ├── models.py │ ├── permissions.py │ ├── serializers.py │ ├── services.py │ ├── tags │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20210223_1603.py │ │ │ ├── 0003_allow_null_tag_description.py │ │ │ ├── 0004_add_uuid_field.py │ │ │ ├── 0005_add_tag_fields_for_stale_flags_logic.py │ │ │ ├── 0006_alter_tag_type.py │ │ │ ├── 0007_alter_tag_color.py │ │ │ ├── 0008_alter_tag_type.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── permissions.py │ │ ├── serializers.py │ │ └── views.py │ ├── tasks.py │ ├── urls.py │ └── views.py ├── pyproject.toml ├── readme.md ├── sales_dashboard │ ├── __init__.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ └── __init__.py │ ├── templates │ │ └── sales_dashboard │ │ │ ├── base.html │ │ │ ├── home.html │ │ │ ├── nav.html │ │ │ ├── organisation.html │ │ │ └── usage.html │ ├── templatetags │ │ ├── __init__.py │ │ └── sales_dashboard_extras.py │ ├── urls.py │ └── views.py ├── scripts │ ├── healthcheck.py │ ├── run-docker-dev.sh │ └── run-docker.sh ├── segments │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── managers.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20190515_1113.py │ │ ├── 0003_segment_project.py │ │ ├── 0004_auto_20190523_1325.py │ │ ├── 0005_auto_20190529_1426.py │ │ ├── 0006_auto_20190828_0907.py │ │ ├── 0007_auto_20190906_1416.py │ │ ├── 0008_auto_20210223_1603.py │ │ ├── 0010_add_uuid_fields.py │ │ ├── 0011_segment_feature.py │ │ ├── 0012_alter_condition_operator.py │ │ ├── 0013_add_is_set_and_is_not_set_operators.py │ │ ├── 0014_add_description_to_segment_condition.py │ │ ├── 0015_remove_max_length_from_condition_description.py │ │ ├── 0016_add_historical_records_to_segment.py │ │ ├── 0017_update_historical_segment_with_missing_changes.py │ │ ├── 0018_soft_delete_segments.py │ │ ├── 0019_add_audit_to_condition.py │ │ ├── 0020_detach_segment_from_project_cascade_delete.py │ │ ├── 0021_create_whitelisted_segments.py │ │ ├── 0022_add_soft_delete_to_segment_rules_and_conditions.py │ │ ├── 0023_add_versioning_to_segments.py │ │ ├── 0024_add_timestamps_to_segments.py │ │ ├── 0025_set_default_version_on_segment.py │ │ ├── 0026_add_change_request_to_segments.py │ │ ├── 0027_historicalsegmentrule.py │ │ ├── __init__.py │ │ └── sql │ │ │ ├── 0023_add_versioning_to_segments.sql │ │ │ └── 0023_add_versioning_to_segments_reverse.sql │ ├── models.py │ ├── permissions.py │ ├── serializers.py │ ├── services.py │ ├── tasks.py │ ├── urls.py │ └── views.py ├── sse │ ├── __init__.py │ ├── dataclasses.py │ ├── exceptions.py │ ├── sse_service.py │ └── tasks.py ├── static │ └── .gitkeep ├── telemetry │ ├── __init__.py │ ├── apps.py │ ├── models.py │ ├── serializers.py │ └── telemetry.py ├── templates │ └── admin │ │ ├── base_site.html │ │ └── login.html ├── tests │ ├── __init__.py │ ├── conftest.py │ ├── integration │ │ ├── __init__.py │ │ ├── api_keys │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ └── test_viewset.py │ │ ├── audit │ │ │ └── test_audit_logs.py │ │ ├── conftest.py │ │ ├── core │ │ │ ├── test_commands.py │ │ │ └── test_user_rate_throttle.py │ │ ├── custom_auth │ │ │ └── end_to_end │ │ │ │ └── test_custom_auth_integration.py │ │ ├── e2etests │ │ │ └── end_to_end │ │ │ │ └── test_integration_e2e_tests.py │ │ ├── edge_api │ │ │ └── identities │ │ │ │ ├── conftest.py │ │ │ │ ├── test_edge_identity_featurestates_viewset.py │ │ │ │ └── test_edge_identity_viewset.py │ │ ├── environments │ │ │ ├── __init__.py │ │ │ ├── identities │ │ │ │ ├── __init__.py │ │ │ │ ├── test_integration_identities.py │ │ │ │ └── test_integration_identities_feature_states.py │ │ │ └── test_integration_environments.py │ │ ├── features │ │ │ ├── __init__.py │ │ │ ├── feature_health │ │ │ │ ├── __init__.py │ │ │ │ ├── conftest.py │ │ │ │ └── test_views.py │ │ │ ├── featurestate │ │ │ │ ├── __init__.py │ │ │ │ ├── test_environment_featurestate_viewset.py │ │ │ │ └── test_simple_featurestate_viewset.py │ │ │ ├── multivariate │ │ │ │ ├── __init__.py │ │ │ │ └── test_integration_multivariate.py │ │ │ ├── test_integration_features.py │ │ │ └── versioning │ │ │ │ ├── __init__.py │ │ │ │ ├── test_integration_v2_versioning.py │ │ │ │ └── types.py │ │ ├── helpers.py │ │ ├── projects │ │ │ ├── __init__.py │ │ │ └── test_integration_projects.py │ │ ├── sales_dashboard │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ └── test_integration_sales_dashboard.py │ │ ├── slack │ │ │ ├── conftest.py │ │ │ ├── test_slack_environment_viewset.py │ │ │ ├── test_slack_get_channels.py │ │ │ └── test_slack_token_flow.py │ │ ├── test_integration_api_version_header.py │ │ └── users │ │ │ └── test_init_config.py │ ├── test_helpers.py │ ├── types.py │ └── unit │ │ ├── __init__.py │ │ ├── api │ │ ├── __init__.py │ │ ├── test_unit_api.py │ │ └── test_unit_openapi.py │ │ ├── api_keys │ │ ├── __init__.py │ │ ├── test_authentication.py │ │ └── test_user.py │ │ ├── app │ │ ├── __init__.py │ │ ├── test_unit_app_routers.py │ │ └── test_unit_app_utils.py │ │ ├── app_analytics │ │ ├── __init__.py │ │ ├── test_analytics_db_service.py │ │ ├── test_commands.py │ │ ├── test_middleware.py │ │ ├── test_migrate_to_pg.py │ │ ├── test_models.py │ │ ├── test_tasks.py │ │ ├── test_unit_app_analytics_cache.py │ │ ├── test_unit_app_analytics_influxdb_wrapper.py │ │ ├── test_unit_app_analytics_track.py │ │ └── test_unit_app_analytics_views.py │ │ ├── audit │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_unit_audit_models.py │ │ ├── test_unit_audit_permissions.py │ │ ├── test_unit_audit_services.py │ │ ├── test_unit_audit_signals.py │ │ ├── test_unit_audit_tasks.py │ │ └── test_unit_audit_views.py │ │ ├── conftest.py │ │ ├── core │ │ ├── management │ │ │ ├── __init__.py │ │ │ └── test_unit_core_management_makemigrations.py │ │ ├── middleware │ │ │ ├── test_unit_core_middleware_admin.py │ │ │ └── test_unit_core_middleware_cache_control.py │ │ ├── test_helpers.py │ │ ├── test_redis_cluster.py │ │ ├── test_unit_core_management.py │ │ └── test_unit_core_migration_helpers.py │ │ ├── custom_auth │ │ ├── conftest.py │ │ ├── jwt_cookie │ │ │ └── test_unit_jwt_cookie_authentication.py │ │ ├── mfa │ │ │ └── trench │ │ │ │ ├── __init__.py │ │ │ │ ├── conftest.py │ │ │ │ └── test_views.py │ │ ├── oauth │ │ │ ├── helpers │ │ │ │ └── test_unit_oauth_github_helpers.py │ │ │ ├── test_unit_oauth_github.py │ │ │ ├── test_unit_oauth_google.py │ │ │ ├── test_unit_oauth_serializers.py │ │ │ └── test_unit_oauth_views.py │ │ ├── test_tasks.py │ │ ├── test_unit_custom_auth_serializer.py │ │ └── test_unit_custom_auth_views.py │ │ ├── edge_api │ │ ├── identities │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_edge_api_identities_serializers.py │ │ │ ├── test_edge_api_identities_views.py │ │ │ ├── test_edge_identity_featurestate_view.py │ │ │ ├── test_edge_identity_models.py │ │ │ ├── test_edge_request_forwarder.py │ │ │ ├── test_events.py │ │ │ ├── test_permissions.py │ │ │ └── test_unit_edge_api_identities_tasks.py │ │ └── test_unit_edge_api_commands.py │ │ ├── environments │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── dynamodb │ │ │ ├── test_unit_migrator.py │ │ │ ├── test_unit_services.py │ │ │ ├── types │ │ │ │ └── test_unit_dynamodb_project_metadata.py │ │ │ └── wrappers │ │ │ │ ├── __init__.py │ │ │ │ ├── test_unit_dynamo_environment_wrapper.py │ │ │ │ ├── test_unit_dynamodb_environment_api_key_wrapper.py │ │ │ │ ├── test_unit_dynamodb_environment_v2_wrapper.py │ │ │ │ └── test_unit_dynamodb_identity_wrapper.py │ │ ├── helpers.py │ │ ├── identities │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── helpers.py │ │ │ ├── test_unit_identities_feature_states_views.py │ │ │ ├── test_unit_identities_helpers.py │ │ │ ├── test_unit_identities_models.py │ │ │ ├── test_unit_identities_views.py │ │ │ └── traits │ │ │ │ ├── __init__.py │ │ │ │ ├── test_traits_views.py │ │ │ │ ├── test_unit_traits_models.py │ │ │ │ └── test_unit_traits_serializers.py │ │ ├── management │ │ │ └── commands │ │ │ │ └── test_unit_environments_management_commands_migrate_to_edge.py │ │ ├── permissions │ │ │ ├── __init__.py │ │ │ ├── test_unit_environments_permissions.py │ │ │ ├── test_unit_environments_permissions_migrations.py │ │ │ └── test_unit_environments_views.py │ │ ├── sdk │ │ │ ├── __init__.py │ │ │ └── test_unit_sdk_serializers.py │ │ ├── test_unit_environments_admin.py │ │ ├── test_unit_environments_authentication.py │ │ ├── test_unit_environments_feature_states_views.py │ │ ├── test_unit_environments_migrations.py │ │ ├── test_unit_environments_models.py │ │ ├── test_unit_environments_permissions.py │ │ ├── test_unit_environments_tasks.py │ │ ├── test_unit_environments_views.py │ │ └── test_unit_environments_views_sdk_environment.py │ │ ├── features │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── feature_health │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_admin.py │ │ │ ├── test_models.py │ │ │ └── test_services.py │ │ ├── feature_segments │ │ │ ├── __init__.py │ │ │ ├── test_unit_feature_segments_limits.py │ │ │ ├── test_unit_feature_segments_models.py │ │ │ ├── test_unit_feature_segments_serializers.py │ │ │ └── test_unit_feature_segments_views.py │ │ ├── import_export │ │ │ ├── test_unit_features_import_export_tasks.py │ │ │ └── test_unit_features_import_export_views.py │ │ ├── multivariate │ │ │ ├── __init__.py │ │ │ ├── test_migrations.py │ │ │ ├── test_unit_multivariate_models.py │ │ │ └── test_unit_multivariate_views.py │ │ ├── test_migrations.py │ │ ├── test_unit_feature_external_resources_views.py │ │ ├── test_unit_features_audit_helpers.py │ │ ├── test_unit_features_features_service.py │ │ ├── test_unit_features_helpers.py │ │ ├── test_unit_features_models.py │ │ ├── test_unit_features_permissions.py │ │ ├── test_unit_features_serializers.py │ │ ├── test_unit_features_tasks.py │ │ ├── test_unit_features_utils.py │ │ ├── test_unit_features_views.py │ │ ├── versioning │ │ │ ├── __init__.py │ │ │ ├── test_unit_versioning_dataclasses.py │ │ │ ├── test_unit_versioning_migrations.py │ │ │ ├── test_unit_versioning_models.py │ │ │ ├── test_unit_versioning_tasks.py │ │ │ ├── test_unit_versioning_versioning_service.py │ │ │ └── test_unit_versioning_views.py │ │ └── workflows │ │ │ ├── __init__.py │ │ │ └── core │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_unit_workflows_migrations.py │ │ │ └── test_unit_workflows_models.py │ │ ├── import_export │ │ ├── __init__.py │ │ ├── test_unit_import_export_export.py │ │ └── test_unit_import_export_import.py │ │ ├── integrations │ │ ├── __init__.py │ │ ├── amplitude │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_unit_amplitude.py │ │ │ ├── test_unit_amplitude_models.py │ │ │ └── test_unit_amplitude_views.py │ │ ├── common │ │ │ ├── __init__.py │ │ │ └── test_unit_integrations_common_serializers.py │ │ ├── datadog │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_unit_datadog.py │ │ │ └── test_unit_datadog_views.py │ │ ├── dynatrace │ │ │ ├── test_unit_dynatrace.py │ │ │ └── test_unit_dynatrace_views.py │ │ ├── flagsmith │ │ │ ├── __init__.py │ │ │ ├── test_unit_flagsmith_client.py │ │ │ └── test_unit_flagsmith_service.py │ │ ├── github │ │ │ ├── __init__.py │ │ │ ├── client_responses │ │ │ │ ├── get_issues.json │ │ │ │ ├── get_pulls.json │ │ │ │ └── get_repos.json │ │ │ ├── test_unit_github_github.py │ │ │ └── test_unit_github_views.py │ │ ├── grafana │ │ │ ├── __init__.py │ │ │ ├── test_grafana.py │ │ │ ├── test_mappers.py │ │ │ └── test_views.py │ │ ├── heap │ │ │ ├── __init__.py │ │ │ ├── test_unit_heap.py │ │ │ └── test_unit_heap_views.py │ │ ├── launch_darkly │ │ │ ├── __init__.py │ │ │ ├── client_responses │ │ │ │ ├── get_environments.json │ │ │ │ ├── get_flags.json │ │ │ │ ├── get_project.json │ │ │ │ └── get_segments.json │ │ │ ├── conftest.py │ │ │ ├── example_api_responses │ │ │ │ ├── getEnvironmentsByProject_1.json │ │ │ │ ├── getEnvironmentsByProject_2.json │ │ │ │ ├── getFeatureFlags_1.json │ │ │ │ ├── getFeatureFlags_2.json │ │ │ │ ├── getProject.json │ │ │ │ └── getTags.json │ │ │ ├── test_client.py │ │ │ ├── test_services.py │ │ │ ├── test_tasks.py │ │ │ └── test_views.py │ │ ├── lead_tracking │ │ │ ├── __init__.py │ │ │ ├── hubspot │ │ │ │ ├── _hubspot_responses.py │ │ │ │ ├── test_services.py │ │ │ │ ├── test_unit_hubspot_client.py │ │ │ │ ├── test_unit_hubspot_lead_tracking.py │ │ │ │ └── test_unit_hubspot_tasks.py │ │ │ └── pipedrive │ │ │ │ ├── __init__.py │ │ │ │ ├── conftest.py │ │ │ │ ├── example_api_responses │ │ │ │ ├── __init__.py │ │ │ │ ├── create_deal_field.json │ │ │ │ ├── create_lead.json │ │ │ │ ├── create_organization.json │ │ │ │ ├── create_organization_field.json │ │ │ │ ├── create_person.json │ │ │ │ ├── list_lead_labels.json │ │ │ │ ├── search_organizations.json │ │ │ │ └── search_persons.json │ │ │ │ ├── test_unit_pipedrive_client.py │ │ │ │ ├── test_unit_pipedrive_lead_tracker.py │ │ │ │ └── test_unit_pipedrive_models.py │ │ ├── mixpanel │ │ │ ├── test_unit_mixpanel.py │ │ │ └── test_unit_mixpanel_views.py │ │ ├── new_relic │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_unit_new_relic.py │ │ │ └── test_unit_new_relic_views.py │ │ ├── opencensus │ │ │ ├── test_unit_opencensus_middleware.py │ │ │ └── test_unit_opencensus_querylogger.py │ │ ├── rudderstack │ │ │ ├── test_unit_rudderstack.py │ │ │ └── test_unit_rudderstack_views.py │ │ ├── segment │ │ │ ├── __init__.py │ │ │ ├── test_unit_segment.py │ │ │ └── test_unit_segment_views.py │ │ ├── sentry │ │ │ ├── test_unit_sentry_middleware.py │ │ │ └── test_unit_sentry_sampler.py │ │ ├── slack │ │ │ ├── conftest.py │ │ │ ├── test_unit_slack.py │ │ │ ├── test_unit_slack_authentication.py │ │ │ └── test_unit_slack_permissions.py │ │ ├── test_unit_integration.py │ │ └── webhook │ │ │ ├── conftest.py │ │ │ ├── test_unit_webhook.py │ │ │ ├── test_unit_webhook_models.py │ │ │ ├── test_unit_webhook_serializers.py │ │ │ └── test_unit_webhook_views.py │ │ ├── metadata │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_serializers.py │ │ └── test_views.py │ │ ├── onboarding │ │ ├── conftest.py │ │ └── test_views.py │ │ ├── organisations │ │ ├── __init__.py │ │ ├── chargebee │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_unit_chargebee_cache.py │ │ │ ├── test_unit_chargebee_chargebee.py │ │ │ ├── test_unit_chargebee_metadata.py │ │ │ └── test_unit_chargebee_tasks.py │ │ ├── invites │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_unit_invites_models.py │ │ │ └── test_unit_invites_views.py │ │ ├── permissions │ │ │ ├── __init__.py │ │ │ ├── test_unit_organisations_migrations.py │ │ │ ├── test_unit_organisations_permissions.py │ │ │ └── test_unit_organisations_views.py │ │ ├── subscriptions │ │ │ ├── __init__.py │ │ │ ├── serializers │ │ │ │ ├── __init__.py │ │ │ │ └── test_unit_subscriptions_serializers_mixins.py │ │ │ ├── test_unit_subscriptions_dataclasses.py │ │ │ └── test_unit_subscriptions_decorators.py │ │ ├── test_unit_organisations_migrations.py │ │ ├── test_unit_organisations_models.py │ │ ├── test_unit_organisations_permissions.py │ │ ├── test_unit_organisations_subscription_info_cache.py │ │ ├── test_unit_organisations_tasks.py │ │ └── test_unit_organisations_views.py │ │ ├── permissions │ │ ├── permission_service │ │ │ ├── conftest.py │ │ │ ├── test_get_permitted_environments_for_user.py │ │ │ ├── test_get_permitted_projects_for_user.py │ │ │ ├── test_is_user_environment_admin.py │ │ │ ├── test_is_user_project_admin.py │ │ │ ├── test_master_api_key_permission_service.py │ │ │ └── test_user_has_organisation_permissions.py │ │ ├── test_migrations.py │ │ └── test_unit_permissions_calculator.py │ │ ├── projects │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── tags │ │ │ ├── test_unit_projects_tags_permissions.py │ │ │ └── test_unit_projects_tags_views.py │ │ ├── test_migrations.py │ │ ├── test_unit_projects_admin.py │ │ ├── test_unit_projects_models.py │ │ ├── test_unit_projects_permissions.py │ │ ├── test_unit_projects_serializers.py │ │ ├── test_unit_projects_tasks.py │ │ └── test_unit_projects_views.py │ │ ├── sales_dashboard │ │ ├── __init__.py │ │ ├── conftest.py │ │ └── test_unit_sales_dashboard_views.py │ │ ├── segments │ │ ├── __init__.py │ │ ├── test_unit_segments_migrations.py │ │ ├── test_unit_segments_models.py │ │ ├── test_unit_segments_permissions.py │ │ ├── test_unit_segments_services.py │ │ └── test_unit_segments_views.py │ │ ├── sse │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_sse_service.py │ │ └── test_tasks.py │ │ ├── telemetry │ │ ├── __init__.py │ │ ├── helpers.py │ │ ├── test_unit_telemetry_models.py │ │ ├── test_unit_telemetry_serializers.py │ │ └── test_unit_telemetry_telemetry.py │ │ ├── users │ │ ├── __init__.py │ │ ├── test_unit_users_forms.py │ │ ├── test_unit_users_models.py │ │ ├── test_unit_users_serializers.py │ │ ├── test_unit_users_signals.py │ │ ├── test_unit_users_tasks.py │ │ ├── test_unit_users_views.py │ │ └── utils │ │ │ └── __init__.py │ │ ├── util │ │ ├── mappers │ │ │ ├── test_unit_mappers_dynamodb.py │ │ │ ├── test_unit_mappers_engine.py │ │ │ └── test_unit_mappers_sdk.py │ │ ├── test_logging.py │ │ ├── test_queryset.py │ │ └── test_util.py │ │ └── webhooks │ │ ├── test_unit_webhooks.py │ │ └── test_unit_webhooks_permissions.py ├── users │ ├── __init__.py │ ├── abc.py │ ├── admin.py │ ├── apps.py │ ├── auth_type.py │ ├── constants.py │ ├── emails.py │ ├── exceptions.py │ ├── forms.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── createinitialadminuser.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_ffadminuser_organisation.py │ │ ├── 0003_auto_20180518_1045.py │ │ ├── 0004_auto_20180518_1655.py │ │ ├── 0005_auto_20180518_1659.py │ │ ├── 0006_auto_20180522_0928.py │ │ ├── 0007_invite.py │ │ ├── 0008_auto_20180522_1302.py │ │ ├── 0009_auto_20180522_1342.py │ │ ├── 0010_auto_20180522_1350.py │ │ ├── 0011_remove_ffadminuser_organisation.py │ │ ├── 0012_invite_frontend_base_url.py │ │ ├── 0013_auto_20180524_1521.py │ │ ├── 0014_invite_invited_by.py │ │ ├── 0015_auto_20180809_0014.py │ │ ├── 0016_auto_20180910_1341.py │ │ ├── 0017_auto_20180913_1116.py │ │ ├── 0018_auto_20180920_1234.py │ │ ├── 0019_auto_20181025_1611.py │ │ ├── 0020_auto_20181128_1012.py │ │ ├── 0021_auto_20190918_1040.py │ │ ├── 0022_invite_role.py │ │ ├── 0023_auto_20191122_1039.py │ │ ├── 0024_auto_20200216_1924.py │ │ ├── 0025_auto_20200509_1326.py │ │ ├── 0026_ffadminuser_google_user_id.py │ │ ├── 0027_ffadminuser_github_user_id.py │ │ ├── 0028_delete_invite.py │ │ ├── 0029_auto_20210223_1603.py │ │ ├── 0030_ffadminuser_marketing_consent_given.py │ │ ├── 0031_userpermissiongroup_is_default.py │ │ ├── 0032_auto_20221107_0425.py │ │ ├── 0033_ffadminuser_sign_up_type.py │ │ ├── 0034_add_user_permission_group_membership_through_model.py │ │ ├── 0035_add_ldap_dn.py │ │ ├── 0036_create_hubspot_lead.py │ │ ├── 0037_add_uuid_field_to_user_model.py │ │ ├── 0038_create_hubspot_tracker.py │ │ ├── 0039_alter_ffadminuser_first_name.py │ │ ├── 0040_default_marketing_consent_given_true.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── services.py │ ├── signals.py │ ├── static │ │ └── sales_dashboard │ │ │ └── css │ │ │ └── bootstrap.min.css │ ├── tasks.py │ ├── templates │ │ └── users │ │ │ ├── activation.html │ │ │ ├── confirmation.html │ │ │ ├── email_updated.txt │ │ │ ├── invite_to_org.html │ │ │ ├── invite_to_org.txt │ │ │ └── onboard.html │ ├── urls.py │ └── views.py ├── util │ ├── __init__.py │ ├── drf_writable_nested │ │ └── serializers.py │ ├── history │ │ ├── __init__.py │ │ └── custom_simple_history.py │ ├── logging.py │ ├── mappers │ │ ├── __init__.py │ │ ├── dynamodb.py │ │ ├── engine.py │ │ └── sdk.py │ ├── migrations.py │ ├── pydantic.py │ ├── queryset.py │ ├── renderers.py │ ├── tests.py │ ├── util.py │ └── views.py └── webhooks │ ├── __init__.py │ ├── apps.py │ ├── constants.py │ ├── exceptions.py │ ├── models.py │ ├── permissions.py │ ├── serializers.py │ ├── tasks.py │ ├── urls.py │ ├── views.py │ └── webhooks.py ├── depot.json ├── docker-compose.pgpool.yml ├── docker-compose.yml ├── docker ├── api │ ├── docker-compose.datadog.yml │ └── docker-compose.local.yml └── common │ └── db │ └── .pgpool.yml ├── docs ├── .gitignore ├── .nvmrc ├── Makefile ├── README.md ├── docs │ ├── advanced-use │ │ ├── _category_.json │ │ ├── ab-testing.md │ │ ├── change-requests.md │ │ ├── custom-fields.md │ │ ├── edge-api.md │ │ ├── edge-proxy.md │ │ ├── feature-health.md │ │ ├── flag-analytics.md │ │ ├── flag-management.md │ │ ├── real-time-flags.md │ │ ├── scheduled-flags.md │ │ └── transient-traits.md │ ├── basic-features │ │ ├── _category_.json │ │ ├── index.md │ │ ├── managing-features.md │ │ ├── managing-identities.md │ │ └── segments.md │ ├── billing │ │ ├── index.mdx │ │ └── usage-graph.png │ ├── clients │ │ ├── 3rd-party.md │ │ ├── CLI.md │ │ ├── _category_.json │ │ ├── client-side │ │ │ ├── _category_.json │ │ │ ├── android.md │ │ │ ├── flutter.md │ │ │ ├── ios.mdx │ │ │ ├── javascript.md │ │ │ ├── nextjs-and-ssr.md │ │ │ └── react.md │ │ ├── index.md │ │ ├── openfeature.md │ │ ├── rest.md │ │ └── server-side.mdx │ ├── deployment │ │ ├── _category_.json │ │ ├── configuration │ │ │ ├── _category_.json │ │ │ ├── authentication │ │ │ │ └── _category_.json │ │ │ ├── django-admin.md │ │ │ ├── enterprise-edition.md │ │ │ ├── sizing-and-scaling.md │ │ │ ├── task-processor.md │ │ │ ├── troubleshooting.md │ │ │ ├── usage-report-example.png │ │ │ └── usage-reports.mdx │ │ ├── hosting │ │ │ ├── _category_.json │ │ │ ├── aptible.md │ │ │ ├── aws.md │ │ │ ├── docker.md │ │ │ ├── google-cloud.md │ │ │ ├── kubernetes.md │ │ │ ├── locally-api.md │ │ │ ├── locally-edge-proxy.md │ │ │ ├── locally-frontend.md │ │ │ └── openshift.md │ │ └── index.md │ ├── diagrams │ │ ├── Architecture.drawio │ │ ├── Edge-proxy.drawio.xml │ │ ├── ecs-overview.drawio │ │ ├── edge-api.drawio │ │ ├── flagsmith_model.drawio │ │ └── local-remote-sdk-modes.drawio │ ├── edge-api │ │ ├── Overview.md │ │ ├── _category_.yaml │ │ ├── bulk-insert-identities-overwrite.api.mdx │ │ ├── bulk-insert-identities-update.api.mdx │ │ ├── edge-api.info.mdx │ │ ├── get-flags.api.mdx │ │ ├── get-identity-flags-and-traits.api.mdx │ │ ├── identify-user.api.mdx │ │ └── sidebar.ts │ ├── guides-and-examples │ │ ├── _category_.json │ │ ├── defensive-coding.md │ │ ├── efficient-api-usage.md │ │ ├── flag-lifecycle.md │ │ ├── integration-approaches.md │ │ ├── micro-service-architectures.md │ │ ├── mobile-app-versioning.md │ │ ├── staged-feature-rollouts.md │ │ └── testing-push-notifications.md │ ├── index.md │ ├── integrations │ │ ├── _category_.json │ │ ├── analytics │ │ │ ├── _category_.json │ │ │ ├── adobe.md │ │ │ ├── amplitude.md │ │ │ ├── heap.md │ │ │ ├── mixpanel.md │ │ │ ├── rudderstack.md │ │ │ └── segment.md │ │ ├── apm │ │ │ ├── _category_.json │ │ │ ├── appdynamics.md │ │ │ ├── datadog.md │ │ │ ├── dynatrace.md │ │ │ ├── grafana.md │ │ │ └── newrelic.md │ │ ├── importers │ │ │ └── _category_.json │ │ ├── index.md │ │ ├── project-management │ │ │ ├── _category_.json │ │ │ ├── github.md │ │ │ ├── jira.md │ │ │ ├── servicenow.md │ │ │ └── slack.md │ │ ├── terraform.md │ │ └── webhook.md │ ├── platform │ │ ├── _category_.json │ │ ├── contributing.md │ │ ├── releases.md │ │ └── roadmap.md │ ├── quickstart.md │ ├── support │ │ └── index.mdx │ ├── system-administration │ │ ├── _category_.json │ │ ├── api-usage.md │ │ ├── architecture.md │ │ ├── audit-logs.md │ │ ├── authentication │ │ │ ├── 01-SAML │ │ │ │ ├── _category_.json │ │ │ │ └── index.mdx │ │ │ ├── 02-Okta.md │ │ │ ├── 03-OAuth.md │ │ │ ├── 04-LDAP.md │ │ │ ├── 05-ADFS.md │ │ │ ├── _category_.json │ │ │ └── index.md │ │ ├── environment-settings.md │ │ ├── importing-and-exporting │ │ │ ├── _category_.json │ │ │ ├── django-admin.png │ │ │ ├── features.md │ │ │ ├── index.md │ │ │ ├── launchdarkly.md │ │ │ └── organisations.md │ │ ├── metrics.md │ │ ├── rbac.md │ │ ├── security.md │ │ ├── system-limits.md │ │ └── webhooks.md │ └── version-comparison.md ├── docusaurus.config.ts ├── logo.png ├── package-lock.json ├── package.json ├── plugins │ ├── amplitude.js │ ├── crisp-chat-links.js │ ├── flagsmith-versions │ │ └── index.js │ └── reo.js ├── sidebars.ts ├── src │ ├── components │ │ └── SdkVersions.js │ ├── css │ │ └── custom.css │ ├── pages │ │ └── index.module.css │ └── theme │ │ └── Footer │ │ └── Copyright │ │ └── index.js ├── static │ ├── .nojekyll │ ├── fonts │ │ ├── bitter-bold.woff │ │ ├── bitter-bold.woff2 │ │ ├── bitter-extra-bold.woff │ │ ├── bitter-extra-bold.woff2 │ │ ├── open-sans-bold.woff │ │ ├── open-sans-bold.woff2 │ │ ├── open-sans-italic.woff │ │ ├── open-sans-italic.woff2 │ │ ├── open-sans-regular.woff │ │ ├── open-sans-regular.woff2 │ │ ├── open-sans-semi-bold-italic.woff │ │ ├── open-sans-semi-bold-italic.woff2 │ │ ├── open-sans-semi-bold.woff │ │ └── open-sans-semi-bold.woff2 │ ├── img │ │ ├── Flagsmith_GitHub_SignUp.png │ │ ├── ab-test-paypal-example.png │ │ ├── add-webhook.png │ │ ├── api-key.png │ │ ├── api-usage.png │ │ ├── architecture.svg │ │ ├── banner-logo-dark.png │ │ ├── core-api-now.svg │ │ ├── docusaurus.png │ │ ├── dynatrace_1.png │ │ ├── dynatrace_2.png │ │ ├── dynatrace_3.png │ │ ├── ecs-overview.svg │ │ ├── edge-api-enabled.png │ │ ├── edge-api-now.svg │ │ ├── edge-proxy-existing.svg │ │ ├── edge-proxy-proxy.svg │ │ ├── favicon.ico │ │ ├── flag-analytics.png │ │ ├── flagsmith-model.svg │ │ ├── guides │ │ │ ├── fcm-segment.png │ │ │ ├── fcm-subscribed.png │ │ │ └── fcm-user-override.png │ │ ├── identity-details.png │ │ ├── integrations │ │ │ ├── adobe │ │ │ │ └── adobe-logo.svg │ │ │ ├── amplitude │ │ │ │ ├── amplitude-integration-1.png │ │ │ │ ├── amplitude-integration-2.png │ │ │ │ └── amplitude-logo.svg │ │ │ ├── appdynamics │ │ │ │ └── appdynamics-logo.svg │ │ │ ├── datadog │ │ │ │ ├── datadog-3.png │ │ │ │ ├── datadog-dashboard-widget.png │ │ │ │ └── datadog-logo.svg │ │ │ ├── dynatrace │ │ │ │ ├── dynatrace-events-panel.png │ │ │ │ └── dynatrace-logo.svg │ │ │ ├── github │ │ │ │ ├── github-integration-1.png │ │ │ │ └── github-logo.svg │ │ │ ├── grafana │ │ │ │ └── grafana-logo.svg │ │ │ ├── heap │ │ │ │ ├── heap-integration-1.png │ │ │ │ ├── heap-integration-2.png │ │ │ │ ├── heap-logo.svg │ │ │ │ ├── heap-mv-step-1.png │ │ │ │ ├── heap-mv-step-2.png │ │ │ │ └── heap-mv-step-3.png │ │ │ ├── jira │ │ │ │ ├── associate-flag.png │ │ │ │ ├── flag-states.png │ │ │ │ ├── jira-logo.svg │ │ │ │ └── select-flagsmith.png │ │ │ ├── mixpanel │ │ │ │ ├── mixpanel-integration-1.png │ │ │ │ ├── mixpanel-integration-2.png │ │ │ │ └── mixpanel-logo.svg │ │ │ ├── newrelic │ │ │ │ └── newrelic-logo.svg │ │ │ ├── oauth │ │ │ │ └── oauth-logo.svg │ │ │ ├── rudderstack │ │ │ │ ├── rudderstack-integration-1.png │ │ │ │ └── rudderstack-logo.svg │ │ │ ├── segment │ │ │ │ ├── segment-integration-1.png │ │ │ │ ├── segment-integration-2.png │ │ │ │ └── segment-logo.svg │ │ │ ├── servicenow │ │ │ │ └── servicenow-logo.svg │ │ │ ├── slack │ │ │ │ └── slack-logo.svg │ │ │ ├── terraform │ │ │ │ └── terraform-logo.svg │ │ │ └── webhook │ │ │ │ └── webhook-logo.svg │ │ ├── json-view.png │ │ ├── languages │ │ │ └── java.png │ │ ├── logo.svg │ │ ├── logos │ │ │ └── fly.io.svg │ │ ├── metadata │ │ │ └── metadata-example.png │ │ ├── multi-variate-flags.png │ │ ├── organisation-permissions.png │ │ ├── organisations-admin.png │ │ ├── percent-rollout.png │ │ ├── project-permissions.png │ │ ├── quickstart │ │ │ ├── demo_create_1.png │ │ │ ├── demo_create_10.png │ │ │ ├── demo_create_2.png │ │ │ ├── demo_create_3.png │ │ │ ├── demo_create_4.png │ │ │ ├── demo_create_5.png │ │ │ ├── demo_create_6.png │ │ │ ├── demo_create_7.png │ │ │ ├── demo_create_8.png │ │ │ └── demo_create_9.png │ │ ├── roles │ │ │ ├── role-create.png │ │ │ ├── role-list.png │ │ │ ├── role-project-permissions.png │ │ │ └── role-user-assigned-list.png │ │ ├── saas-architecture.svg │ │ ├── saml-auth-setup.png │ │ ├── saml-group-mapping.png │ │ ├── saml-group-sync-external-id.png │ │ ├── saml-mapping-configuration.png │ │ ├── scheduled-flag-create.png │ │ ├── scheduled-flag-list.png │ │ ├── sdk-local-evaluation.svg │ │ ├── sdk-remote-evaluation.svg │ │ ├── self-hosted-architecture.svg │ │ ├── square-icon.png │ │ └── user-features.png │ ├── js │ │ └── crisp-chat.js │ └── openapi │ │ └── edge-api.yaml └── vercel.json ├── fly.toml ├── frontend ├── .babelrc ├── .dockerignore ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierrc ├── .testcaferc.js ├── Dockerfile-base.e2e ├── Dockerfile.e2e ├── Makefile ├── README.md ├── api │ ├── index.js │ ├── middleware │ │ ├── single-page-middleware.js │ │ └── webpack-middleware.js │ └── slack-client.js ├── bin │ ├── env.js │ └── upload-file.js ├── common │ ├── .watchmanconfig │ ├── Component.js │ ├── ES6Component.js │ ├── base │ │ ├── format-base.js │ │ └── utils-base.js │ ├── code-help │ │ ├── create-user │ │ │ ├── create-user-curl.js │ │ │ ├── create-user-dotnet.js │ │ │ ├── create-user-flutter.js │ │ │ ├── create-user-go.js │ │ │ ├── create-user-ios.js │ │ │ ├── create-user-java.js │ │ │ ├── create-user-js.js │ │ │ ├── create-user-next.js │ │ │ ├── create-user-node.js │ │ │ ├── create-user-php.js │ │ │ ├── create-user-python.js │ │ │ ├── create-user-react.js │ │ │ ├── create-user-ruby.js │ │ │ └── create-user-rust.js │ │ ├── init │ │ │ ├── init-curl.js │ │ │ ├── init-dotnet.js │ │ │ ├── init-flutter.js │ │ │ ├── init-go.js │ │ │ ├── init-ios.js │ │ │ ├── init-java.js │ │ │ ├── init-js.js │ │ │ ├── init-next-app-router.js │ │ │ ├── init-next-pages-router.js │ │ │ ├── init-node.js │ │ │ ├── init-php.js │ │ │ ├── init-python.js │ │ │ ├── init-react.js │ │ │ ├── init-ruby.js │ │ │ └── init-rust.js │ │ ├── install │ │ │ ├── install-curl.js │ │ │ ├── install-dotnet.js │ │ │ ├── install-flutter.js │ │ │ ├── install-go.js │ │ │ ├── install-ios.js │ │ │ ├── install-java.js │ │ │ ├── install-js.js │ │ │ ├── install-node.js │ │ │ ├── install-php.js │ │ │ ├── install-python.js │ │ │ ├── install-ruby.js │ │ │ └── install-rust.js │ │ ├── offline_client │ │ │ ├── offline-client-cli.js │ │ │ └── offline-client-curl.js │ │ ├── offline_server │ │ │ ├── offline-server-cli.js │ │ │ └── offline-server-curl.js │ │ └── traits │ │ │ ├── traits-curl.js │ │ │ ├── traits-dotnet.js │ │ │ ├── traits-flutter.js │ │ │ ├── traits-go.js │ │ │ ├── traits-ios.js │ │ │ ├── traits-java.js │ │ │ ├── traits-js.js │ │ │ ├── traits-next.js │ │ │ ├── traits-node.js │ │ │ ├── traits-php.js │ │ │ ├── traits-python.js │ │ │ ├── traits-react.js │ │ │ ├── traits-ruby.js │ │ │ └── traits-rust.js │ ├── constants.ts │ ├── data │ │ └── base │ │ │ └── _data.js │ ├── dispatcher │ │ ├── action-constants.js │ │ ├── app-actions.js │ │ ├── base │ │ │ ├── _action-constants.js │ │ │ └── _app-actions.js │ │ └── dispatcher.js │ ├── loadCrisp.ts │ ├── providers │ │ ├── AccountProvider.js │ │ ├── ConfigProvider.js │ │ ├── FeatureListProvider.js │ │ ├── IdentityProvider.js │ │ ├── OrganisationProvider.tsx │ │ ├── Permission.tsx │ │ ├── ProjectProvider.tsx │ │ └── withSegmentOverrides.js │ ├── service.ts │ ├── services │ │ ├── useAccount.ts │ │ ├── useAuditLog.ts │ │ ├── useAuditLogItem.ts │ │ ├── useAuditLogWebhook.ts │ │ ├── useAvailablePermissions.ts │ │ ├── useBuildVersion.ts │ │ ├── useChangeRequest.ts │ │ ├── useConversionEvent.ts │ │ ├── useEnableFeatureVersioning.ts │ │ ├── useEnvironment.ts │ │ ├── useExternalResource.ts │ │ ├── useFeatureExport.ts │ │ ├── useFeatureImport.ts │ │ ├── useFeatureSegment.ts │ │ ├── useFeatureState.ts │ │ ├── useFeatureVersion.ts │ │ ├── useFlagsmithProjectImport.ts │ │ ├── useGithub.ts │ │ ├── useGithubIntegration.ts │ │ ├── useGithubRepository.ts │ │ ├── useGroup.ts │ │ ├── useGroupSummary.ts │ │ ├── useGroupWithRole.ts │ │ ├── useHealthEvents.ts │ │ ├── useHealthProvider.ts │ │ ├── useIdentity.ts │ │ ├── useIdentityFeatureState.ts │ │ ├── useIdentitySegment.ts │ │ ├── useIdentityTrait.ts │ │ ├── useInvites.ts │ │ ├── useLaunchDarklyProjectImport.ts │ │ ├── useMasterAPIKeyWithMasterAPIKeyRole.ts │ │ ├── useMetadataField.ts │ │ ├── useMetadataModelField.ts │ │ ├── useMyGroup.ts │ │ ├── useOnboarding.ts │ │ ├── useOnboardingSupportOptIn.ts │ │ ├── useOrganisation.ts │ │ ├── useOrganisationLicensing.ts │ │ ├── useOrganisationUsage.ts │ │ ├── usePermission.ts │ │ ├── useProject.ts │ │ ├── useProjectFlag.ts │ │ ├── useRole.ts │ │ ├── useRoleMasterApiKey.ts │ │ ├── useRolePermission.ts │ │ ├── useRolePermissionGroup.ts │ │ ├── useRolesUser.ts │ │ ├── useSamlAttributeMapping.ts │ │ ├── useSamlConfiguration.ts │ │ ├── useSegment.ts │ │ ├── useSegmentOverride.ts │ │ ├── useSegmentPriority.ts │ │ ├── useServersideEnvironmentKey.ts │ │ ├── useSplitTest.ts │ │ ├── useSubscriptionMetadata.ts │ │ ├── useSupportedContentType.ts │ │ ├── useTag.ts │ │ ├── useUser.ts │ │ ├── useUserEmail.ts │ │ ├── useUserGroupPermission.ts │ │ ├── useUserPermissions.ts │ │ ├── useUserWithRole.ts │ │ ├── useVersionFeatureState.ts │ │ └── useWebhooks.ts │ ├── store.ts │ ├── stores │ │ ├── account-store.js │ │ ├── base │ │ │ └── _store.js │ │ ├── change-requests-store.js │ │ ├── config-store.js │ │ ├── default-flags.ts │ │ ├── feature-list-store.ts │ │ ├── identity-store.js │ │ ├── organisation-store.js │ │ └── project-store.js │ ├── transformCorePaging.ts │ ├── types │ │ ├── requests.ts │ │ └── responses.ts │ ├── useInfiniteScroll.ts │ ├── useOutsideClick.ts │ ├── useSearchThrottle.ts │ ├── useThrottle.ts │ ├── useViewMode.ts │ └── utils │ │ ├── base │ │ └── _utils.js │ │ ├── calculateListPosition.ts │ │ ├── format.js │ │ ├── isFreeEmailDomain.ts │ │ ├── toFormData.ts │ │ ├── useProtectedTags.ts │ │ └── utils.tsx ├── docker-compose-e2e-tests.yml ├── e2e │ ├── .gitignore │ ├── add-error-logs.js │ ├── config.ts │ ├── helpers.cafe.ts │ ├── index.cafe.js │ ├── init.cafe.js │ ├── tests │ │ ├── environment-permission-test.ts │ │ ├── environment-test.ts │ │ ├── flag-tests.ts │ │ ├── initialise-tests.ts │ │ ├── invite-test.ts │ │ ├── organisation-permission-test.ts │ │ ├── project-permission-test.ts │ │ ├── project-test.ts │ │ ├── roles-test.ts │ │ ├── segment-test.ts │ │ └── versioning-tests.ts │ └── tsconfig.json ├── env │ ├── project_dev.js │ ├── project_e2e.js │ ├── project_local.js │ ├── project_prod.js │ ├── project_selfhosted.js │ └── project_staging.js ├── environment.js ├── global.d.ts ├── next.config.js ├── package-lock.json ├── package.json ├── tsconfig.json ├── vercel.json ├── web │ ├── components │ │ ├── ActionButton.tsx │ │ ├── AdminAPIKeys.js │ │ ├── Announcement.tsx │ │ ├── AnnouncementPerPage.tsx │ │ ├── App.js │ │ ├── AppLoader.js │ │ ├── AsideProjectButton.js │ │ ├── AsideTitleLink.js │ │ ├── AuditLog.tsx │ │ ├── Blocked.js │ │ ├── BlockedOrgInfo.tsx │ │ ├── BooleanDotIndicator.tsx │ │ ├── Breadcrumb.tsx │ │ ├── BreadcrumbSeparator.tsx │ │ ├── BuildVersion.tsx │ │ ├── ButterBar.tsx │ │ ├── Card.tsx │ │ ├── ChipInput.tsx │ │ ├── ClearFilters.tsx │ │ ├── CodeHelp.js │ │ ├── Collapsible.js │ │ ├── CompareEnvironments.js │ │ ├── CompareFeatures.js │ │ ├── CompareIdentities.tsx │ │ ├── CondensedFeatureRow.tsx │ │ ├── CondensedRow.tsx │ │ ├── Confidence.tsx │ │ ├── ConnectedGroupSelect.tsx │ │ ├── ConversionEventSelect.tsx │ │ ├── DateList.tsx │ │ ├── DateSelect.tsx │ │ ├── DeleteGithubIntegration.tsx │ │ ├── EditHealthProvider.tsx │ │ ├── EditIdentity.tsx │ │ ├── EditPermissions.tsx │ │ ├── EnvironmentDocumentCodeHelp.tsx │ │ ├── EnvironmentDropdown.js │ │ ├── EnvironmentFilter.tsx │ │ ├── EnvironmentReadyChecker.tsx │ │ ├── EnvironmentSelect.tsx │ │ ├── ErrorMessage.js │ │ ├── ExistingChangeRequestAlert.tsx │ │ ├── ExternalResourcesLinkTab.tsx │ │ ├── ExternalResourcesTable.tsx │ │ ├── Feature.js │ │ ├── FeatureAction.tsx │ │ ├── FeatureHistory.tsx │ │ ├── FeatureRow.tsx │ │ ├── FeatureValue.tsx │ │ ├── FeatureVersion.tsx │ │ ├── FlagOwnerGroups.js │ │ ├── FlagOwners.js │ │ ├── FlagSelect.js │ │ ├── GitHubRepositoriesSelect.tsx │ │ ├── GitHubResourcesSelect.tsx │ │ ├── GithubRepositoriesTable.tsx │ │ ├── GithubStar.tsx │ │ ├── GoogleButton.tsx │ │ ├── GroupSelect.tsx │ │ ├── Headway.js │ │ ├── Highlight.js │ │ ├── HistoryIcon.js │ │ ├── Icon.tsx │ │ ├── IdentifierString.tsx │ │ ├── IdentityOverridesIcon.tsx │ │ ├── IdentitySelect.tsx │ │ ├── IdentityTraits.tsx │ │ ├── InfoMessage.tsx │ │ ├── InlineModal.tsx │ │ ├── IntegrationList.tsx │ │ ├── JSONReference.tsx │ │ ├── JSONUpload.tsx │ │ ├── LicensingTabContent.tsx │ │ ├── Logo.tsx │ │ ├── Maintenance.js │ │ ├── MyGitHubRepositoriesComponent.tsx │ │ ├── MyGroupsSelect.tsx │ │ ├── MyRepositoriesSelect.tsx │ │ ├── MyRoleSelect.tsx │ │ ├── NavSubLink.tsx │ │ ├── NewVersionWarning.tsx │ │ ├── OrgEnvironmentSelect.tsx │ │ ├── OrganisationLimit.tsx │ │ ├── OrganisationSelect.js │ │ ├── OrganisationUsage.tsx │ │ ├── PageTitle.tsx │ │ ├── Paging.js │ │ ├── PanelSearch.tsx │ │ ├── PasswordRequirements.js │ │ ├── PermissionControl.tsx │ │ ├── PermissionRow.tsx │ │ ├── PermissionsSummaryList.tsx │ │ ├── PermissionsTabs.tsx │ │ ├── PlanBasedAccess.tsx │ │ ├── ProjectFilter.tsx │ │ ├── ProjectManageWidget.tsx │ │ ├── ProjectSelect.js │ │ ├── ProjectUsage.tsx │ │ ├── ProjectsPage.tsx │ │ ├── RebrandBanner.js │ │ ├── RegexTester.tsx │ │ ├── RemoveUserOverride.tsx │ │ ├── RemoveViewPermissionModal.tsx │ │ ├── RepositoriesSelect.tsx │ │ ├── Resources.tsx │ │ ├── RolePermissionsList.tsx │ │ ├── RolesSelect.tsx │ │ ├── RolesTable.tsx │ │ ├── SAMLAttributeMappingTable.tsx │ │ ├── SDKKeysPage.tsx │ │ ├── SamlForm.js │ │ ├── SamlTab.tsx │ │ ├── ScrollToTop.tsx │ │ ├── SegmentOverrideActions.tsx │ │ ├── SegmentOverrideLimit.tsx │ │ ├── SegmentOverrides.js │ │ ├── SegmentOverridesIcon.tsx │ │ ├── SegmentSelect.tsx │ │ ├── ServerSideSDKKeys.js │ │ ├── Setting.tsx │ │ ├── SettingsButton.tsx │ │ ├── SimpleTwoFactor │ │ │ ├── index.js │ │ │ └── prompt.js │ │ ├── StaleFlagWarning.tsx │ │ ├── SuccessMessage.js │ │ ├── Switch.js │ │ ├── TagUsage.tsx │ │ ├── TestWebhook.tsx │ │ ├── ToggleChip.js │ │ ├── Token.js │ │ ├── Tooltip.tsx │ │ ├── TryIt.js │ │ ├── TwoFactor.js │ │ ├── UnhealthyFlagWarning.tsx │ │ ├── UserAction.tsx │ │ ├── UserGroupList.tsx │ │ ├── UserSelect.js │ │ ├── UsersGroups.tsx │ │ ├── ValueEditor.js │ │ ├── ViewDocs.tsx │ │ ├── WarningMessage.tsx │ │ ├── XMLUpload.tsx │ │ ├── base │ │ │ ├── Popover.tsx │ │ │ ├── forms │ │ │ │ ├── Button.tsx │ │ │ │ ├── Checkbox.tsx │ │ │ │ ├── GhostInput.tsx │ │ │ │ ├── Input.js │ │ │ │ ├── InputGroup.js │ │ │ │ ├── Radio.tsx │ │ │ │ ├── TabItem.tsx │ │ │ │ └── Tabs.js │ │ │ ├── grid │ │ │ │ ├── Column.js │ │ │ │ ├── Flex.js │ │ │ │ ├── FormGroup.js │ │ │ │ ├── Panel.tsx │ │ │ │ └── Row.js │ │ │ └── higher-order │ │ │ │ ├── FocusMonitor.tsx │ │ │ │ └── ParameterizedRoute.tsx │ │ ├── datadog-client.ts │ │ ├── derived-permissions │ │ │ ├── DerivedPermissionsList.tsx │ │ │ └── DerivedTag.tsx │ │ ├── diff │ │ │ ├── DiffChangeRequest.tsx │ │ │ ├── DiffEnabled.tsx │ │ │ ├── DiffFeature.tsx │ │ │ ├── DiffSegments.tsx │ │ │ ├── DiffString.tsx │ │ │ ├── DiffVariations.tsx │ │ │ └── diff-utils.ts │ │ ├── hooks │ │ │ └── useFormNotSavedModal.tsx │ │ ├── import-export │ │ │ ├── FeatureExport.tsx │ │ │ ├── FeatureExportItem.tsx │ │ │ ├── FeatureImport.tsx │ │ │ └── ImportPage.tsx │ │ ├── inspect-permissions │ │ │ ├── EnvironmentPermissions.tsx │ │ │ ├── ExpandablePermissionsList.tsx │ │ │ ├── InspectPermissions.tsx │ │ │ ├── Permissions.tsx │ │ │ └── ProjectPermissions.tsx │ │ ├── metadata │ │ │ ├── AddMetadataToEntity.tsx │ │ │ ├── ContentTypesMetadataFieldTable.tsx │ │ │ ├── ContentTypesValues.tsx │ │ │ ├── MetadataPage.tsx │ │ │ ├── MetadataTitle.tsx │ │ │ └── SupportedContentTypesSelect.tsx │ │ ├── modals │ │ │ ├── AssociatedSegmentOverrides.js │ │ │ ├── AuditLogWebhooks.tsx │ │ │ ├── ChangeEmailAddress.tsx │ │ │ ├── ChangeRequestModal.tsx │ │ │ ├── ConfirmCloneSegment.tsx │ │ │ ├── ConfirmDeleteAccount.tsx │ │ │ ├── ConfirmDeleteRole.tsx │ │ │ ├── ConfirmHideFlags.tsx │ │ │ ├── ConfirmRemoveAuditWebhook.tsx │ │ │ ├── ConfirmRemoveEnvironment.tsx │ │ │ ├── ConfirmRemoveFeature.tsx │ │ │ ├── ConfirmRemoveOrganisation.tsx │ │ │ ├── ConfirmRemoveProject.tsx │ │ │ ├── ConfirmRemoveSegment.tsx │ │ │ ├── ConfirmRemoveTrait.tsx │ │ │ ├── ConfirmRemoveWebhook.tsx │ │ │ ├── ConfirmToggleEnvFeature.tsx │ │ │ ├── ConfirmToggleFeature.tsx │ │ │ ├── CreateAuditLogWebhook.tsx │ │ │ ├── CreateEditIntegrationModal.tsx │ │ │ ├── CreateFlag.js │ │ │ ├── CreateGroup.tsx │ │ │ ├── CreateMetadataField.tsx │ │ │ ├── CreateOrganisation.tsx │ │ │ ├── CreateProject.js │ │ │ ├── CreateRole.tsx │ │ │ ├── CreateSAML.tsx │ │ │ ├── CreateSegment.tsx │ │ │ ├── CreateSegmentRulesTabForm.tsx │ │ │ ├── CreateSegmentUsersTabContent.tsx │ │ │ ├── CreateTrait.tsx │ │ │ ├── CreateUser.tsx │ │ │ ├── CreateWebhook.tsx │ │ │ ├── FeatureHealthTabContent.tsx │ │ │ ├── ForgotPasswordModal.tsx │ │ │ ├── InviteUsers.tsx │ │ │ ├── ModalHR.tsx │ │ │ ├── Payment.js │ │ │ ├── Rule.tsx │ │ │ ├── RuleInputValue.tsx │ │ │ └── base │ │ │ │ ├── Modal.tsx │ │ │ │ ├── ModalAlert.tsx │ │ │ │ ├── ModalClose.tsx │ │ │ │ ├── ModalConfirm.tsx │ │ │ │ ├── ModalDefault.tsx │ │ │ │ └── ModalHeader.tsx │ │ ├── mv │ │ │ ├── AddVariationButton.js │ │ │ ├── VariationOptions.js │ │ │ └── VariationValue.js │ │ ├── onboarding │ │ │ ├── OnboardingAccountForm.tsx │ │ │ ├── OnboardingOrganisationForm.tsx │ │ │ └── OnboardingStep.tsx │ │ ├── pages │ │ │ ├── AccountSettingsPage.js │ │ │ ├── AuditLogItemPage.tsx │ │ │ ├── AuditLogPage.tsx │ │ │ ├── BrokenPage.tsx │ │ │ ├── ChangeRequestPage.js │ │ │ ├── ChangeRequestsPage.js │ │ │ ├── ComingSoonPage.js │ │ │ ├── ComparePage.js │ │ │ ├── ConfirmEmailPage.js │ │ │ ├── CreateEnvironmentPage.tsx │ │ │ ├── CreateOrganisationPage.js │ │ │ ├── EnvironmentSettingsPage.tsx │ │ │ ├── FeatureHistoryDetailPage.tsx │ │ │ ├── FeaturesPage.js │ │ │ ├── GitHubSetupPage.tsx │ │ │ ├── HomeAside.tsx │ │ │ ├── HomePage.js │ │ │ ├── HomePage.tsx │ │ │ ├── IntegrationsPage.tsx │ │ │ ├── InvitePage.js │ │ │ ├── NotFoundErrorPage.js │ │ │ ├── NotFoundPage.tsx │ │ │ ├── OnboardingPage.tsx │ │ │ ├── OrganisationIntegrationsPage.tsx │ │ │ ├── OrganisationSettingsPage.js │ │ │ ├── OrganisationSettingsRedirectPage.tsx │ │ │ ├── OrganisationUsagePage.tsx │ │ │ ├── OrganisationsPage.tsx │ │ │ ├── PasswordResetPage.js │ │ │ ├── ProjectRedirectPage.tsx │ │ │ ├── ProjectSettingsPage.js │ │ │ ├── ScheduledChangesPage.js │ │ │ ├── SegmentsPage.tsx │ │ │ ├── SplitTestPage.tsx │ │ │ ├── UserIdPage.js │ │ │ ├── UserPage.tsx │ │ │ ├── UsersAndPermissionsPage.tsx │ │ │ ├── UsersPage.tsx │ │ │ └── WidgetPage.tsx │ │ ├── saveFeatureWithValidation.ts │ │ ├── segments │ │ │ └── SegmentRow │ │ │ │ ├── SegmentRow.tsx │ │ │ │ └── components │ │ │ │ └── SegmentAction.tsx │ │ ├── shared │ │ │ └── ActionItem.tsx │ │ ├── svg │ │ │ ├── ArrowUpIcon.tsx │ │ │ ├── AuditLogIcon.tsx │ │ │ ├── CaretDownIcon.tsx │ │ │ ├── CaretRightIcon.tsx │ │ │ ├── DocumentationIcon.tsx │ │ │ ├── DropIcon.tsx │ │ │ ├── EnvironmentSettingsIcon.tsx │ │ │ ├── FeaturesIcon.tsx │ │ │ ├── LogoutIcon.tsx │ │ │ ├── NavIconSmall.tsx │ │ │ ├── OrgSettingsIcon.tsx │ │ │ ├── PlayIcon.tsx │ │ │ ├── PlusIcon.tsx │ │ │ ├── ProjectSettingsIcon.tsx │ │ │ ├── SegmentsIcon.tsx │ │ │ ├── SettingsIcon.tsx │ │ │ ├── SparklesIcon.tsx │ │ │ ├── UpgradeIcon.tsx │ │ │ ├── UserSettingsIcon.tsx │ │ │ └── UsersIcon.tsx │ │ ├── tables │ │ │ ├── TableFilter.tsx │ │ │ ├── TableFilterItem.tsx │ │ │ ├── TableFilterOptions.tsx │ │ │ ├── TableGroupsFilter.tsx │ │ │ ├── TableOwnerFilter.tsx │ │ │ ├── TableSearchFilter.tsx │ │ │ ├── TableSortFilter.tsx │ │ │ ├── TableTagFilter.tsx │ │ │ └── TableValueFilter.tsx │ │ ├── tags │ │ │ ├── AddEditTags.tsx │ │ │ ├── ColourSelect.tsx │ │ │ ├── CreateEditTag.tsx │ │ │ ├── Tag.tsx │ │ │ ├── TagContent.tsx │ │ │ ├── TagFilter.tsx │ │ │ └── TagValues.tsx │ │ └── useSetupCustomWidget.ts │ ├── index.handlebars │ ├── index.html │ ├── main.js │ ├── project │ │ ├── api.js │ │ ├── firstPromoter.js │ │ ├── libs.js │ │ ├── polyfil.js │ │ ├── project-components.js │ │ ├── setDarkMode.ts │ │ └── toast.tsx │ ├── routes.js │ ├── static │ │ ├── .gitignore │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── OpenSans-Bold.ttf │ │ │ ├── OpenSans-Bold.woff │ │ │ ├── OpenSans-Bold.woff2 │ │ │ ├── OpenSans-Light.ttf │ │ │ ├── OpenSans-Light.woff │ │ │ ├── OpenSans-Light.woff2 │ │ │ ├── OpenSans-Regular.ttf │ │ │ ├── OpenSans-Regular.woff │ │ │ ├── OpenSans-Regular.woff2 │ │ │ ├── OpenSans-SemiBold.ttf │ │ │ ├── OpenSans-SemiBold.woff │ │ │ ├── OpenSans-SemiBold.woff2 │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ ├── images │ │ │ ├── favicon.ico │ │ │ ├── integrations │ │ │ │ ├── amplitude.svg │ │ │ │ ├── datadog.svg │ │ │ │ ├── dynatrace.svg │ │ │ │ ├── grafana.svg │ │ │ │ ├── heap.svg │ │ │ │ ├── mp.svg │ │ │ │ ├── new_relic.svg │ │ │ │ ├── rudderstack.svg │ │ │ │ ├── segment.svg │ │ │ │ ├── sentry.svg │ │ │ │ ├── slack.svg │ │ │ │ └── webhooks.svg │ │ │ └── nav-logo.png │ │ └── robots.txt │ └── styles │ │ ├── 3rdParty │ │ ├── _bootstrap.scss │ │ ├── _hljs.scss │ │ ├── _hw-badge.scss │ │ ├── _index.scss │ │ ├── _react-datepicker.scss │ │ ├── _react-diff.scss │ │ └── _react-select.scss │ │ ├── _variables.scss │ │ ├── components │ │ ├── _aside.scss │ │ ├── _chip.scss │ │ ├── _color-block.scss │ │ ├── _droparea.scss │ │ ├── _feature-change.scss │ │ ├── _index.scss │ │ ├── _input.scss │ │ ├── _list-item.scss │ │ ├── _paging.scss │ │ ├── _panel.scss │ │ ├── _switch.scss │ │ ├── _tabs.scss │ │ └── _toast.scss │ │ ├── flexbox │ │ ├── _index.scss │ │ └── _mixins.scss │ │ ├── mixins │ │ ├── box-shadow-mixin.scss │ │ ├── custom-scrollbar.scss │ │ └── transition-mixin.scss │ │ ├── project │ │ ├── _FeaturesPage.scss │ │ ├── _PricingPage.scss │ │ ├── _alert.scss │ │ ├── _base.scss │ │ ├── _buttons.scss │ │ ├── _forms.scss │ │ ├── _icons.scss │ │ ├── _index.scss │ │ ├── _layout.scss │ │ ├── _lists.scss │ │ ├── _modals.scss │ │ ├── _overlay.scss │ │ ├── _panel.scss │ │ ├── _project-nav.scss │ │ ├── _segments.scss │ │ ├── _spacing-utils.scss │ │ ├── _tags.scss │ │ ├── _tooltips.scss │ │ ├── _type.scss │ │ └── _utils.scss │ │ └── styles.scss ├── webpack.config.js └── webpack │ ├── loaders.js │ ├── pages.js │ ├── plugins.js │ ├── webpack.config.analyse.js │ ├── webpack.config.django.prod.js │ ├── webpack.config.local.js │ └── webpack.config.prod.js ├── infrastructure └── aws │ ├── production │ ├── ecs-task-definition-migration.json │ ├── ecs-task-definition-task-processor.json │ └── ecs-task-definition-web.json │ └── staging │ ├── ecs-task-definition-migration.json │ ├── ecs-task-definition-task-processor.json │ └── ecs-task-definition-web.json ├── nginx-uffizzi └── nginx.conf ├── package-lock.json ├── public └── webhooks │ └── feature-health-sample-provider.json ├── release-please-config.json ├── render.yaml ├── sdk └── evaluation-context.json ├── static-files ├── hero.png └── screenshot.png ├── trivy.yaml └── version.txt /.dockerignore: -------------------------------------------------------------------------------- 1 | */node_modules 2 | npm-debug.log 3 | .dockerignore 4 | .git 5 | docker-compose*.yml 6 | Dockerfile 7 | .tool-versions 8 | .env* 9 | .venv* 10 | .idea 11 | .elasticbeanstalk 12 | .ebignore 13 | .ebextensions 14 | .direnv 15 | .github -------------------------------------------------------------------------------- /.dokku-monorepo: -------------------------------------------------------------------------------- 1 | bullet-train=api 2 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Initial Mypy '# type: ignore' comments dump 2 | # https://github.com/Flagsmith/flagsmith/pull/5119 3 | 5de0b425b0ee16b16bfb0fb33b067fa314d040fb 4 | # Linting fixes for frontend 5 | # https://github.com/Flagsmith/flagsmith/pull/5123 6 | 1f7083636d3b163588fe9a8b45af289bd40b1a8d 7 | # Migrate to ruff 8 | # https://github.com/Flagsmith/flagsmith/pull/5150 9 | f7487ac5278d60e62067e2f4d5976ceb755f4980 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Flagsmith Community 4 | url: https://discord.gg/hFhxNtXzgm 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/docker_build_comment_template.md: -------------------------------------------------------------------------------- 1 | #### Docker builds report 2 | 3 | | Image | Build Status | Security report | 4 | | ----- | ------------ | --------------- | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/actions/labeler 2 | 3 | docs: 4 | - changed-files: 5 | - any-glob-to-any-file: docs/** 6 | 7 | front-end: 8 | - changed-files: 9 | - any-glob-to-any-file: frontend/** 10 | 11 | api: 12 | - changed-files: 13 | - any-glob-to-any-file: api/** 14 | 15 | infrastructure: 16 | - changed-files: 17 | - any-glob-to-any-file: infrastructure/** 18 | -------------------------------------------------------------------------------- /.github/workflows/api-deploy-production-ecs.yml: -------------------------------------------------------------------------------- 1 | name: API Deploy to Production ECS 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | paths: 8 | - api/** 9 | - .github/** 10 | - infrastructure/aws/production/** 11 | 12 | jobs: 13 | deploy-ecs: 14 | uses: ./.github/workflows/.reusable-deploy-ecs.yml 15 | with: 16 | environment: production 17 | secrets: inherit 18 | -------------------------------------------------------------------------------- /.github/workflows/api-deploy-staging-ecs.yml: -------------------------------------------------------------------------------- 1 | name: API Deploy to Staging ECS 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - api/** 9 | - .github/** 10 | - infrastructure/aws/staging/** 11 | workflow_dispatch: 12 | 13 | jobs: 14 | deploy-ecs: 15 | uses: ./.github/workflows/.reusable-deploy-ecs.yml 16 | with: 17 | environment: staging 18 | secrets: inherit 19 | -------------------------------------------------------------------------------- /.github/workflows/docs-cron-vercel-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Docs - update SDK versions 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | # At 12:00 on Tuesday https://crontab.guru/#0_12_*_*_2 7 | - cron: '0 12 * * 2' 8 | jobs: 9 | vercel-deploy: 10 | runs-on: depot-ubuntu-latest 11 | steps: 12 | - name: Run Vercel deploy hook 13 | run: curl -X POST "${{ secrets.VERCEL_SDK_VERSIONS_DEPLOY_HOOKS_URL }}" 14 | -------------------------------------------------------------------------------- /.github/workflows/github-labeler.yml: -------------------------------------------------------------------------------- 1 | name: Github Labeler 2 | 3 | on: 4 | - pull_request_target 5 | 6 | jobs: 7 | apply-labels: 8 | permissions: 9 | contents: read 10 | pull-requests: write 11 | runs-on: depot-ubuntu-latest 12 | 13 | steps: 14 | - name: Run labeler 15 | uses: actions/labeler@v5 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *db.sqlite3* 2 | venv 3 | .venv 4 | *.pyc 5 | .idea 6 | .vscode 7 | *.log 8 | checkstyle.txt 9 | .python-version 10 | .env* 11 | !.env-local 12 | !.env-ci 13 | .direnv 14 | .envrc 15 | .tool-versions 16 | .elasticbeanstalk/ 17 | 18 | # These get baked into the docker container on build 19 | src/CI_COMMIT_SHA 20 | 21 | 22 | # Web 23 | .DS_Store 24 | .idea 25 | *.iml 26 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | cd ./frontend && npx lint-staged --allow-empty 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .github/docker_build_comment_template.md 2 | 3 | # Frontend has it's own prettier setup 4 | frontend/ 5 | 6 | # Auto generated by open API generator 7 | docs/docs/edge-api/*.mdx 8 | docs/docs/edge-api/sidebar.ts 9 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "2.179.0" 3 | } -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | / @flagsmith/flagsmith-maintainers 2 | 3 | /api/ @flagsmith/flagsmith-back-end 4 | /docs/ @flagsmith/flagsmith-docs 5 | /frontend/ @flagsmith/flagsmith-front-end 6 | /infrastructure/ @flagsmith/flagsmith-back-end 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: install 2 | install: 3 | cd api && $(MAKE) install 4 | cd docs && $(MAKE) install 5 | 6 | .PHONY: lint 7 | lint: 8 | cd api && $(MAKE) lint 9 | cd docs && $(MAKE) lint 10 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Issues 2 | 3 | Please report any security issues you discover to support[at]flagsmith[dot]com 4 | 5 | We will assess the risk and, if required, take the following actions: 6 | 7 | - Identify the remediation. 8 | - Implement and deploy a fix to our SaaS platform, Docker images and source code. 9 | - Create a GitHub issue, labelled `Security` where appropriate. 10 | 11 | Thank you for your contribution. 12 | -------------------------------------------------------------------------------- /api/.ebextensions/00__packages.config: -------------------------------------------------------------------------------- 1 | packages: 2 | yum: 3 | git: [] 4 | xmlsec1: [] 5 | xmlsec1-openssl: [] -------------------------------------------------------------------------------- /api/.ebextensions/01__upgrade_pip.config: -------------------------------------------------------------------------------- 1 | commands: 2 | pip_upgrade: 3 | command: /opt/python/run/venv/bin/pip install --upgrade pip 4 | ignoreErrors: false -------------------------------------------------------------------------------- /api/.ebextensions/02__collectstatic.config: -------------------------------------------------------------------------------- 1 | container_commands: 2 | 01_collectstatic: 3 | command: python manage.py collectstatic --noinput -------------------------------------------------------------------------------- /api/.ebextensions/03__django.config: -------------------------------------------------------------------------------- 1 | option_settings: 2 | aws:elasticbeanstalk:container:python: 3 | WSGIPath: app/wsgi.py 4 | "aws:elasticbeanstalk:container:python:staticfiles": 5 | "/static/": "static/" -------------------------------------------------------------------------------- /api/.ebignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/.ebignore -------------------------------------------------------------------------------- /api/.env-ci: -------------------------------------------------------------------------------- 1 | DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres 2 | ANALYTICS_DATABASE_URL=postgres://postgres:postgres@localhost:5432/analytics 3 | PYTEST_ADDOPTS=--cov . --cov-report xml -n auto --ci 4 | GUNICORN_LOGGER_CLASS=util.logging.GunicornJsonCapableLogger 5 | COVERAGE_CORE=sysmon 6 | -------------------------------------------------------------------------------- /api/.env-local: -------------------------------------------------------------------------------- 1 | DATABASE_URL=postgresql://postgres:password@localhost:5432/flagsmith 2 | DJANGO_SETTINGS_MODULE=app.settings.local 3 | PYTEST_ADDOPTS=--cov . --cov-report html -n auto 4 | -------------------------------------------------------------------------------- /api/.gitignore: -------------------------------------------------------------------------------- 1 | static/* 2 | !static/.gitkeep 3 | **/staticfiles/* 4 | 5 | # SaaS only modules 6 | saml/ 7 | features/workflows/logic/ 8 | 9 | # Unit test coverage 10 | .coverage 11 | -------------------------------------------------------------------------------- /api/Procfile: -------------------------------------------------------------------------------- 1 | release: python manage.py migrate 2 | web: gunicorn --bind 0.0.0.0:${PORT:-8000} -w ${GUNICORN_WORKERS:-3} -w ${GUNICORN_THREADS:-2} app.wsgi -------------------------------------------------------------------------------- /api/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/api/__init__.py -------------------------------------------------------------------------------- /api/api/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class ApiConfig(AppConfig): 7 | name = "api" 8 | -------------------------------------------------------------------------------- /api/api/migrations/0012_delete_ffadminuser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.13 on 2018-05-18 10:42 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('api', '0011_auto_20180517_1646'), 12 | ] 13 | 14 | operations = [ 15 | migrations.DeleteModel( 16 | name='FFAdminUser', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /api/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/api/migrations/__init__.py -------------------------------------------------------------------------------- /api/api/models.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/api/models.py -------------------------------------------------------------------------------- /api/api/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class ErrorSerializer(serializers.Serializer): # type: ignore[type-arg] 5 | message = serializers.CharField() 6 | -------------------------------------------------------------------------------- /api/api/urls/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/api/urls/__init__.py -------------------------------------------------------------------------------- /api/api/urls/v2.py: -------------------------------------------------------------------------------- 1 | from django.urls import re_path 2 | 3 | from app_analytics.views import SDKAnalyticsFlagsV2 4 | 5 | app_name = "v2" 6 | 7 | urlpatterns = [ 8 | re_path( 9 | r"^analytics/flags/$", SDKAnalyticsFlagsV2.as_view(), name="analytics-flags" 10 | ) 11 | ] 12 | -------------------------------------------------------------------------------- /api/api_keys/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/api_keys/__init__.py -------------------------------------------------------------------------------- /api/api_keys/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import MasterAPIKey 4 | 5 | admin.site.register(MasterAPIKey) 6 | -------------------------------------------------------------------------------- /api/api_keys/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiKeysConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "api_keys" 7 | -------------------------------------------------------------------------------- /api/api_keys/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/api_keys/migrations/__init__.py -------------------------------------------------------------------------------- /api/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/app/__init__.py -------------------------------------------------------------------------------- /api/app/exceptions.py: -------------------------------------------------------------------------------- 1 | class ImproperlyConfiguredError(RuntimeError): 2 | pass 3 | -------------------------------------------------------------------------------- /api/app/settings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/app/settings/__init__.py -------------------------------------------------------------------------------- /api/app/settings/develop.py: -------------------------------------------------------------------------------- 1 | from app.settings.common import * # noqa 2 | -------------------------------------------------------------------------------- /api/app/settings/production.py: -------------------------------------------------------------------------------- 1 | from app.settings.common import * 2 | 3 | REST_FRAMEWORK["PAGE_SIZE"] = 999 4 | -------------------------------------------------------------------------------- /api/app/templates/.gitignore: -------------------------------------------------------------------------------- 1 | # Front-end production template builds are copied here by webpack. HTML files in this folder should not be committed to git. 2 | 3 | webpack/**.html 4 | -------------------------------------------------------------------------------- /api/app/templates/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /api/app/templates/webpack/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/app/templates/webpack/.gitkeep -------------------------------------------------------------------------------- /api/app/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for app project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings.local") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /api/app_analytics/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/app_analytics/__init__.py -------------------------------------------------------------------------------- /api/app_analytics/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AppAnalyticsConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "app_analytics" 7 | -------------------------------------------------------------------------------- /api/app_analytics/constants.py: -------------------------------------------------------------------------------- 1 | ANALYTICS_READ_BUCKET_SIZE = 15 2 | 3 | # get_usage_data() related period constants 4 | CURRENT_BILLING_PERIOD = "current_billing_period" 5 | PREVIOUS_BILLING_PERIOD = "previous_billing_period" 6 | NINETY_DAY_PERIOD = "90_day_period" 7 | -------------------------------------------------------------------------------- /api/app_analytics/dataclasses.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from datetime import date 3 | 4 | 5 | @dataclass 6 | class UsageData: 7 | day: date 8 | flags: int = 0 9 | traits: int = 0 10 | identities: int = 0 11 | environment_document: int = 0 12 | 13 | 14 | @dataclass 15 | class FeatureEvaluationData: 16 | day: date 17 | count: int = 0 18 | -------------------------------------------------------------------------------- /api/app_analytics/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/app_analytics/migrations/__init__.py -------------------------------------------------------------------------------- /api/app_analytics/types.py: -------------------------------------------------------------------------------- 1 | from typing import Literal 2 | 3 | from . import constants 4 | 5 | PERIOD_TYPE = Literal[ # type: ignore[valid-type] 6 | constants.CURRENT_BILLING_PERIOD, 7 | constants.PREVIOUS_BILLING_PERIOD, 8 | constants.NINETY_DAY_PERIOD, 9 | ] 10 | -------------------------------------------------------------------------------- /api/audit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/audit/__init__.py -------------------------------------------------------------------------------- /api/audit/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class AuditConfig(AppConfig): 7 | name = "audit" 8 | 9 | def ready(self): # type: ignore[no-untyped-def] 10 | from . import signals # noqa 11 | -------------------------------------------------------------------------------- /api/audit/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/audit/migrations/__init__.py -------------------------------------------------------------------------------- /api/audit/related_object_type.py: -------------------------------------------------------------------------------- 1 | import enum 2 | 3 | 4 | class RelatedObjectType(enum.Enum): 5 | FEATURE = "Feature" 6 | FEATURE_STATE = "Feature state" 7 | SEGMENT = "Segment" 8 | ENVIRONMENT = "Environment" 9 | CHANGE_REQUEST = "Change request" 10 | EDGE_IDENTITY = "Edge Identity" 11 | IMPORT_REQUEST = "Import request" 12 | EF_VERSION = "Environment feature version" 13 | FEATURE_HEALTH = "Feature health status" 14 | -------------------------------------------------------------------------------- /api/audit/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import include, re_path 2 | from rest_framework import routers 3 | 4 | from audit.views import AllAuditLogViewSet 5 | 6 | router = routers.DefaultRouter() 7 | router.register(r"", AllAuditLogViewSet, basename="audit") 8 | 9 | 10 | urlpatterns = [re_path(r"^", include(router.urls))] 11 | -------------------------------------------------------------------------------- /api/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/core/__init__.py -------------------------------------------------------------------------------- /api/core/constants.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | INTEGER = "int" 4 | STRING = "unicode" 5 | BOOLEAN = "bool" 6 | FLOAT = "float" 7 | 8 | FLAGSMITH_SIGNATURE_HEADER = "X-Flagsmith-Signature" 9 | 10 | FLAGSMITH_UPDATED_AT_HEADER = "X-Flagsmith-Document-Updated-At" 11 | -------------------------------------------------------------------------------- /api/core/custom_admin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/core/custom_admin/__init__.py -------------------------------------------------------------------------------- /api/core/custom_admin/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | from django.contrib.admin.apps import AdminConfig 3 | 4 | 5 | class CustomAdminConfig(AdminConfig): 6 | default_site = "core.custom_admin.admin.CustomAdminSite" 7 | 8 | 9 | class CustomAdminAppConfig(AppConfig): 10 | name = "core.custom_admin" 11 | -------------------------------------------------------------------------------- /api/core/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/core/management/__init__.py -------------------------------------------------------------------------------- /api/core/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/core/management/commands/__init__.py -------------------------------------------------------------------------------- /api/core/middleware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/core/middleware/__init__.py -------------------------------------------------------------------------------- /api/core/request_origin.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class RequestOrigin(Enum): 5 | CLIENT = "CLIENT" 6 | SERVER = "SERVER" 7 | -------------------------------------------------------------------------------- /api/core/signing.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import hmac 3 | 4 | 5 | def sign_payload(payload: str, key: str): # type: ignore[no-untyped-def] 6 | # signPayload of frontend/web/components/TestWebHook on the frontend replicates this 7 | # exact function, change the function there if this changes. 8 | return hmac.new( 9 | key=key.encode(), msg=payload.encode(), digestmod=hashlib.sha256 10 | ).hexdigest() 11 | -------------------------------------------------------------------------------- /api/core/throttling.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.core.cache import caches 3 | from rest_framework import throttling 4 | 5 | 6 | class UserRateThrottle(throttling.UserRateThrottle): 7 | cache = caches[settings.USER_THROTTLE_CACHE_NAME] 8 | -------------------------------------------------------------------------------- /api/custom_auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from rest_framework.authtoken.admin import TokenAdmin 3 | from rest_framework.authtoken.models import TokenProxy 4 | 5 | 6 | class CustomTokenAdmin(TokenAdmin): 7 | search_fields = ("user__email",) 8 | 9 | 10 | admin.site.unregister(TokenProxy) 11 | admin.site.register(TokenProxy, CustomTokenAdmin) 12 | -------------------------------------------------------------------------------- /api/custom_auth/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CustomAuthAppConfig(AppConfig): 5 | name = "custom_auth" 6 | 7 | def ready(self) -> None: 8 | from custom_auth.jwt_cookie import signals # noqa F401 9 | -------------------------------------------------------------------------------- /api/custom_auth/constants.py: -------------------------------------------------------------------------------- 1 | USER_REGISTRATION_WITHOUT_INVITE_ERROR_MESSAGE = ( 2 | "User registration without an invite is disabled for this installation." 3 | ) 4 | INVALID_PASSWORD_ERROR = "Invalid password." 5 | FIELD_BLANK_ERROR = "This field may not be blank." 6 | -------------------------------------------------------------------------------- /api/custom_auth/jwt_cookie/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/jwt_cookie/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/jwt_cookie/constants.py: -------------------------------------------------------------------------------- 1 | JWT_SLIDING_COOKIE_KEY = "jwt" 2 | -------------------------------------------------------------------------------- /api/custom_auth/mfa/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/mfa/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/mfa/backends/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/mfa/backends/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/mfa/trench/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class TrenchConfig(AppConfig): 5 | name = "custom_auth.mfa.trench" 6 | verbose_name = "django-trench" 7 | -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/backends/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/mfa/trench/backends/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/command/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/mfa/trench/command/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/command/create_secret.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from pyotp import random_base32 3 | 4 | 5 | def create_secret_command() -> str: 6 | generator = random_base32 7 | return generator(length=settings.TRENCH_AUTH["SECRET_KEY_LENGTH"]) # type: ignore[arg-type] 8 | -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/command/validate_backup_code.py: -------------------------------------------------------------------------------- 1 | from typing import Iterable, Optional 2 | 3 | from django.contrib.auth.hashers import check_password 4 | 5 | 6 | def validate_backup_code_command(value: str, backup_codes: Iterable) -> Optional[str]: # type: ignore[type-arg] 7 | for backup_code in backup_codes: 8 | if check_password(value, backup_code): 9 | return backup_code # type: ignore[no-any-return] 10 | return None 11 | -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/mfa/trench/migrations/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/urls/__init__.py: -------------------------------------------------------------------------------- 1 | from custom_auth.mfa.trench.urls.base import urlpatterns # noqa 2 | -------------------------------------------------------------------------------- /api/custom_auth/mfa/trench/views/__init__.py: -------------------------------------------------------------------------------- 1 | from custom_auth.mfa.trench.views.base import * # noqa 2 | -------------------------------------------------------------------------------- /api/custom_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/migrations/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from users.models import FFAdminUser 4 | 5 | 6 | class UserPasswordResetRequest(models.Model): 7 | user = models.ForeignKey( 8 | FFAdminUser, related_name="password_reset_requests", on_delete=models.CASCADE 9 | ) 10 | requested_at = models.DateTimeField(auto_now_add=True) 11 | -------------------------------------------------------------------------------- /api/custom_auth/oauth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/oauth/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/oauth/exceptions.py: -------------------------------------------------------------------------------- 1 | class GithubError(Exception): 2 | pass 3 | 4 | 5 | class GoogleError(Exception): 6 | pass 7 | 8 | 9 | class OAuthError(Exception): 10 | pass 11 | -------------------------------------------------------------------------------- /api/custom_auth/oauth/helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/custom_auth/oauth/helpers/__init__.py -------------------------------------------------------------------------------- /api/custom_auth/oauth/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from custom_auth.oauth.views import login_with_github, login_with_google 4 | 5 | app_name = "oauth" 6 | 7 | urlpatterns = [ 8 | path("google/", login_with_google, name="google-oauth-login"), 9 | path("github/", login_with_github, name="github-oauth-login"), 10 | ] 11 | -------------------------------------------------------------------------------- /api/e2etests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/e2etests/__init__.py -------------------------------------------------------------------------------- /api/e2etests/permissions.py: -------------------------------------------------------------------------------- 1 | from django.views import View 2 | from rest_framework.permissions import BasePermission 3 | from rest_framework.request import Request 4 | 5 | 6 | class E2ETestPermission(BasePermission): 7 | def has_permission(self, request: Request, view: View) -> bool: 8 | return getattr(request, "is_e2e", False) is True 9 | -------------------------------------------------------------------------------- /api/e2etests/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import re_path 2 | 3 | from .views import Teardown 4 | 5 | app_name = "e2etests" 6 | 7 | 8 | urlpatterns = [ 9 | re_path(r"teardown/", Teardown.as_view(), name="teardown"), 10 | ] 11 | -------------------------------------------------------------------------------- /api/edge_api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/edge_api/__init__.py -------------------------------------------------------------------------------- /api/edge_api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class EdgeAPIAppConfig(AppConfig): 5 | name = "edge_api" 6 | -------------------------------------------------------------------------------- /api/edge_api/identities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/edge_api/identities/__init__.py -------------------------------------------------------------------------------- /api/edge_api/identities/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class EdgeAPIIdentitiesAppConfig(AppConfig): 5 | name = "edge_api.identities" 6 | label = "edge_api_identities" 7 | -------------------------------------------------------------------------------- /api/edge_api/identities/exceptions.py: -------------------------------------------------------------------------------- 1 | from rest_framework import status 2 | from rest_framework.exceptions import APIException 3 | 4 | 5 | class TraitPersistenceError(APIException): 6 | status_code = status.HTTP_400_BAD_REQUEST 7 | -------------------------------------------------------------------------------- /api/edge_api/identities/types.py: -------------------------------------------------------------------------------- 1 | from typing import Any, Literal, TypedDict 2 | 3 | from typing_extensions import NotRequired 4 | 5 | ChangeType = Literal["+", "-", "~"] 6 | 7 | 8 | class FeatureStateChangeDetails(TypedDict): 9 | change_type: ChangeType 10 | old: NotRequired[dict[str, Any]] 11 | new: NotRequired[dict[str, Any]] 12 | 13 | 14 | class IdentityChangeset(TypedDict): 15 | feature_overrides: dict[str, FeatureStateChangeDetails] 16 | -------------------------------------------------------------------------------- /api/edge_api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/edge_api/management/commands/__init__.py -------------------------------------------------------------------------------- /api/environments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/__init__.py -------------------------------------------------------------------------------- /api/environments/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from core.apps import BaseAppConfig 5 | 6 | 7 | class EnvironmentsConfig(BaseAppConfig): 8 | name = "environments" 9 | default = True 10 | -------------------------------------------------------------------------------- /api/environments/constants.py: -------------------------------------------------------------------------------- 1 | IDENTITY_INTEGRATIONS_RELATION_NAMES = [ 2 | "amplitude_config", 3 | "heap_config", 4 | "mixpanel_config", 5 | "rudderstack_config", 6 | "segment_config", 7 | "webhook_config", 8 | ] 9 | -------------------------------------------------------------------------------- /api/environments/dynamodb/constants.py: -------------------------------------------------------------------------------- 1 | ENVIRONMENTS_V2_PARTITION_KEY = "environment_id" 2 | ENVIRONMENTS_V2_SORT_KEY = "document_key" 3 | 4 | ENVIRONMENTS_V2_ENVIRONMENT_META_DOCUMENT_KEY = "_META" 5 | 6 | ENVIRONMENTS_V2_SECONDARY_INDEX = "environment_api_key-index" 7 | ENVIRONMENTS_V2_SECONDARY_INDEX_PARTITION_KEY = "environment_api_key" 8 | 9 | DYNAMODB_MAX_BATCH_WRITE_ITEM_COUNT = 25 10 | IDENTITIES_PAGINATION_LIMIT = 1000 11 | -------------------------------------------------------------------------------- /api/environments/dynamodb/wrappers/__init__.py: -------------------------------------------------------------------------------- 1 | from .environment_api_key_wrapper import DynamoEnvironmentAPIKeyWrapper 2 | from .environment_wrapper import ( 3 | DynamoEnvironmentV2Wrapper, 4 | DynamoEnvironmentWrapper, 5 | ) 6 | from .identity_wrapper import DynamoIdentityWrapper 7 | 8 | __all__ = ( 9 | "DynamoEnvironmentAPIKeyWrapper", 10 | "DynamoEnvironmentV2Wrapper", 11 | "DynamoEnvironmentWrapper", 12 | "DynamoIdentityWrapper", 13 | ) 14 | -------------------------------------------------------------------------------- /api/environments/dynamodb/wrappers/exceptions.py: -------------------------------------------------------------------------------- 1 | from decimal import Decimal 2 | 3 | 4 | class CapacityBudgetExceeded(Exception): 5 | def __init__( 6 | self, 7 | capacity_budget: Decimal, 8 | capacity_spent: Decimal, 9 | ) -> None: 10 | self.capacity_budget = capacity_budget 11 | self.capacity_spent = capacity_spent 12 | -------------------------------------------------------------------------------- /api/environments/enums.py: -------------------------------------------------------------------------------- 1 | import enum 2 | 3 | 4 | class EnvironmentDocumentCacheMode(enum.Enum): 5 | PERSISTENT = "PERSISTENT" 6 | EXPIRING = "EXPIRING" 7 | -------------------------------------------------------------------------------- /api/environments/exceptions.py: -------------------------------------------------------------------------------- 1 | class EnvironmentHeaderNotPresentError(Exception): 2 | pass 3 | -------------------------------------------------------------------------------- /api/environments/identities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/identities/__init__.py -------------------------------------------------------------------------------- /api/environments/identities/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class IdentitiesConfig(AppConfig): 5 | name = "environments.identities" 6 | -------------------------------------------------------------------------------- /api/environments/identities/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/identities/migrations/__init__.py -------------------------------------------------------------------------------- /api/environments/identities/traits/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/identities/traits/__init__.py -------------------------------------------------------------------------------- /api/environments/identities/traits/constants.py: -------------------------------------------------------------------------------- 1 | from features.value_types import BOOLEAN, FLOAT, INTEGER, STRING 2 | 3 | ACCEPTED_TRAIT_VALUE_TYPES = [INTEGER, STRING, BOOLEAN, FLOAT] 4 | TRAIT_STRING_VALUE_MAX_LENGTH = 2000 5 | -------------------------------------------------------------------------------- /api/environments/identities/traits/exceptions.py: -------------------------------------------------------------------------------- 1 | class TraitPersistenceError(Exception): 2 | pass 3 | -------------------------------------------------------------------------------- /api/environments/identities/traits/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/identities/traits/migrations/__init__.py -------------------------------------------------------------------------------- /api/environments/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/management/__init__.py -------------------------------------------------------------------------------- /api/environments/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/management/commands/__init__.py -------------------------------------------------------------------------------- /api/environments/management/serializers.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/management/serializers.py -------------------------------------------------------------------------------- /api/environments/metrics.py: -------------------------------------------------------------------------------- 1 | import prometheus_client 2 | 3 | CACHE_HIT = "CACHE_HIT" 4 | CACHE_MISS = "CACHE_MISS" 5 | 6 | flagsmith_environment_document_cache_queries_total = prometheus_client.Counter( 7 | "flagsmith_environment_document_cache_queries_total", 8 | "Results of cache retrieval for environment document. `result` label is either `hit` or `miss`.", 9 | ["result"], 10 | ) 11 | -------------------------------------------------------------------------------- /api/environments/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/migrations/__init__.py -------------------------------------------------------------------------------- /api/environments/permissions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/permissions/__init__.py -------------------------------------------------------------------------------- /api/environments/permissions/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class EnvironmentPermissionsConfig(AppConfig): 5 | name = "environments.permissions" 6 | label = "environment_permissions" 7 | -------------------------------------------------------------------------------- /api/environments/permissions/managers.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from permissions.models import ENVIRONMENT_PERMISSION_TYPE 4 | 5 | 6 | class EnvironmentPermissionManager(models.Manager): # type: ignore[type-arg] 7 | def get_queryset(self): # type: ignore[no-untyped-def] 8 | return ( 9 | super(EnvironmentPermissionManager, self) 10 | .get_queryset() 11 | .filter(type=ENVIRONMENT_PERMISSION_TYPE) 12 | ) 13 | -------------------------------------------------------------------------------- /api/environments/permissions/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/permissions/migrations/__init__.py -------------------------------------------------------------------------------- /api/environments/sdk/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/environments/sdk/__init__.py -------------------------------------------------------------------------------- /api/environments/sdk/schemas.py: -------------------------------------------------------------------------------- 1 | from flag_engine.environments.models import EnvironmentModel 2 | 3 | from environments.constants import IDENTITY_INTEGRATIONS_RELATION_NAMES 4 | from util.pydantic import exclude_model_fields 5 | 6 | SDKEnvironmentDocumentModel = exclude_model_fields( 7 | EnvironmentModel, 8 | *IDENTITY_INTEGRATIONS_RELATION_NAMES, 9 | "dynatrace_config", 10 | ) 11 | -------------------------------------------------------------------------------- /api/environments/sdk/types.py: -------------------------------------------------------------------------------- 1 | import typing 2 | 3 | from typing_extensions import NotRequired 4 | 5 | 6 | class SDKTraitValueData(typing.TypedDict): 7 | type: str 8 | value: str 9 | 10 | 11 | class SDKTraitData(typing.TypedDict): 12 | trait_key: str 13 | trait_value: SDKTraitValueData | None 14 | transient: NotRequired[bool] 15 | -------------------------------------------------------------------------------- /api/features/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/__init__.py -------------------------------------------------------------------------------- /api/features/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from core.apps import BaseAppConfig 5 | 6 | 7 | class FeaturesConfig(BaseAppConfig): 8 | name = "features" 9 | default = True 10 | 11 | def ready(self): # type: ignore[no-untyped-def] 12 | super().ready() # type: ignore[no-untyped-call] 13 | 14 | # noinspection PyUnresolvedReferences 15 | import features.signals # noqa 16 | -------------------------------------------------------------------------------- /api/features/constants.py: -------------------------------------------------------------------------------- 1 | # Feature state types 2 | FEATURE_SEGMENT = "FEATURE_SEGMENT" 3 | IDENTITY = "IDENTITY" 4 | ENVIRONMENT = "ENVIRONMENT" 5 | 6 | # Feature state statuses 7 | COMMITTED = "COMMITTED" 8 | DRAFT = "DRAFT" 9 | 10 | # Tag filtering strategy 11 | UNION = "UNION" 12 | INTERSECTION = "INTERSECTION" 13 | 14 | MAX_32_BIT_INTEGER = 2_147_483_647 15 | -------------------------------------------------------------------------------- /api/features/feature_external_resources/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/feature_external_resources/__init__.py -------------------------------------------------------------------------------- /api/features/feature_external_resources/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class FeatureExternalResourcesConfig(AppConfig): 5 | name = "features.feature_external_resources" 6 | -------------------------------------------------------------------------------- /api/features/feature_external_resources/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/feature_external_resources/migrations/__init__.py -------------------------------------------------------------------------------- /api/features/feature_health/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/feature_health/__init__.py -------------------------------------------------------------------------------- /api/features/feature_health/apps.py: -------------------------------------------------------------------------------- 1 | from core.apps import BaseAppConfig 2 | 3 | 4 | class FeatureHealthConfig(BaseAppConfig): 5 | name = "features.feature_health" 6 | default = True 7 | -------------------------------------------------------------------------------- /api/features/feature_health/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/feature_health/migrations/__init__.py -------------------------------------------------------------------------------- /api/features/feature_health/providers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/feature_health/providers/__init__.py -------------------------------------------------------------------------------- /api/features/feature_health/providers/grafana/__init__.py: -------------------------------------------------------------------------------- 1 | from features.feature_health.providers.grafana.services import ( 2 | get_provider_response, 3 | ) 4 | 5 | __all__ = ("get_provider_response",) 6 | -------------------------------------------------------------------------------- /api/features/feature_health/providers/grafana/constants.py: -------------------------------------------------------------------------------- 1 | GRAFANA_FEATURE_LABEL_NAME = "flagsmith_feature" 2 | GRAFANA_ENVIRONMENT_LABEL_NAME = "flagsmith_environment" 3 | -------------------------------------------------------------------------------- /api/features/feature_health/providers/sample/__init__.py: -------------------------------------------------------------------------------- 1 | from features.feature_health.providers.sample.services import ( 2 | get_provider_response, 3 | ) 4 | 5 | __all__ = ("get_provider_response",) 6 | -------------------------------------------------------------------------------- /api/features/feature_health/providers/sample/services.py: -------------------------------------------------------------------------------- 1 | from features.feature_health.providers.sample.mappers import ( 2 | map_payload_to_provider_response, 3 | ) 4 | from features.feature_health.types import FeatureHealthProviderResponse 5 | 6 | 7 | def get_provider_response(payload: str) -> FeatureHealthProviderResponse: 8 | return map_payload_to_provider_response(payload) 9 | -------------------------------------------------------------------------------- /api/features/feature_health/tasks.py: -------------------------------------------------------------------------------- 1 | from task_processor.decorators import ( 2 | register_task_handler, 3 | ) 4 | 5 | from features.feature_health import services 6 | from features.models import Feature 7 | 8 | 9 | @register_task_handler() 10 | def update_feature_unhealthy_tag(feature_id: int) -> None: 11 | if feature := Feature.objects.filter(id=feature_id).first(): 12 | services.update_feature_unhealthy_tag(feature) 13 | -------------------------------------------------------------------------------- /api/features/feature_segments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/feature_segments/__init__.py -------------------------------------------------------------------------------- /api/features/feature_states/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/feature_states/__init__.py -------------------------------------------------------------------------------- /api/features/feature_types.py: -------------------------------------------------------------------------------- 1 | from typing import Literal 2 | 3 | FeatureType = Literal["STANDARD", "MULTIVARIATE"] 4 | 5 | MULTIVARIATE: FeatureType = "MULTIVARIATE" 6 | STANDARD: FeatureType = "STANDARD" 7 | 8 | # the following two types have been merged in terms of functionality 9 | # but kept for now until the FE is updated 10 | CONFIG = "CONFIG" 11 | FLAG = "FLAG" 12 | -------------------------------------------------------------------------------- /api/features/fields.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/fields.py -------------------------------------------------------------------------------- /api/features/helpers.py: -------------------------------------------------------------------------------- 1 | import typing 2 | 3 | from features.value_types import BOOLEAN, INTEGER 4 | 5 | 6 | def get_correctly_typed_value(value_type: str, string_value: str) -> typing.Any: 7 | if value_type == INTEGER: 8 | return int(string_value) 9 | elif value_type == BOOLEAN: 10 | return string_value == "True" 11 | 12 | return string_value 13 | -------------------------------------------------------------------------------- /api/features/import_export/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class FeaturesImportExport(AppConfig): 5 | name = "features.import_export" 6 | label = "features_import_export" 7 | -------------------------------------------------------------------------------- /api/features/import_export/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/import_export/migrations/__init__.py -------------------------------------------------------------------------------- /api/features/migrations/0010_merge_20180816_1531.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.14 on 2018-08-16 15:31 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('features', '0009_auto_20180809_0014'), 12 | ('features', '0009_auto_20180815_1011'), 13 | ] 14 | 15 | operations = [ 16 | ] 17 | -------------------------------------------------------------------------------- /api/features/migrations/0027_merge_20210215_1059.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2021-02-15 10:59 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('features', '0025_alter_unique_constraints_for_feature_states'), 10 | ('features', '0026_auto_20210110_1300'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /api/features/migrations/0028_auto_20210216_1600.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2021-02-16 16:00 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('features', '0027_merge_20210215_1059'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='feature', 15 | options={}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /api/features/migrations/0030_merge_20210305_1622.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2021-03-05 16:22 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('features', '0028_auto_20210216_1600'), 10 | ('features', '0029_auto_20210223_2106'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /api/features/migrations/0031_merge_20210409_1621.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2021-04-09 16:21 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ("features", "0030_auto_20210401_1552"), 10 | ("features", "0030_merge_20210305_1622"), 11 | ] 12 | 13 | operations = [] 14 | -------------------------------------------------------------------------------- /api/features/migrations/0034_merge_20210930_0502.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.24 on 2021-09-30 05:02 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ("features", "0033_feature_owners"), 10 | ("features", "0033_auto_20210918_1048"), 11 | ] 12 | 13 | operations = [] 14 | -------------------------------------------------------------------------------- /api/features/migrations/0036_alter_feature_options.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.12 on 2022-03-23 11:42 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('features', '0035_auto_20211109_0603'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='feature', 15 | options={'ordering': ('id',)}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /api/features/migrations/0039_merge_20220329_1252.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.12 on 2022-03-29 12:52 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('features', '0036_alter_feature_options'), 10 | ('features', '0038_remove_old_versions_and_drafts'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /api/features/migrations/0041_merge_20220406_0806.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.12 on 2022-04-06 08:06 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('features', '0039_merge_20220329_1252'), 10 | ('features', '0040_add_change_request_to_feature_state'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /api/features/migrations/0053_delete_historical_feature_segment.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.17 on 2023-02-10 11:09 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('features', '0052_add_feature_state_value_audit'), 10 | ] 11 | 12 | operations = [ 13 | migrations.DeleteModel( 14 | name='HistoricalFeatureSegment', 15 | ), 16 | ] 17 | -------------------------------------------------------------------------------- /api/features/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/migrations/__init__.py -------------------------------------------------------------------------------- /api/features/multivariate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/multivariate/__init__.py -------------------------------------------------------------------------------- /api/features/multivariate/apps.py: -------------------------------------------------------------------------------- 1 | from core.apps import BaseAppConfig 2 | 3 | 4 | class MultivariateConfig(BaseAppConfig): 5 | name = "features.multivariate" 6 | default = True 7 | -------------------------------------------------------------------------------- /api/features/multivariate/migrations/0003_merge_20220131_1532.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.26 on 2022-01-31 15:32 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('multivariate', '0002_auto_20220124_0722'), 10 | ('multivariate', '0002_add_unique_constraint_for_mv_feature_states'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /api/features/multivariate/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/multivariate/migrations/__init__.py -------------------------------------------------------------------------------- /api/features/multivariate/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from features.multivariate.views import get_mv_feature_option_by_uuid 4 | 5 | app_name = "multivariate" 6 | 7 | urlpatterns = [ 8 | path( 9 | "options/get-by-uuid//", 10 | get_mv_feature_option_by_uuid, 11 | name="get-mv-feature-option-by-uuid", 12 | ), 13 | ] 14 | -------------------------------------------------------------------------------- /api/features/value_types.py: -------------------------------------------------------------------------------- 1 | INTEGER = "int" 2 | STRING = "unicode" 3 | BOOLEAN = "bool" 4 | FLOAT = "float" 5 | FEATURE_STATE_VALUE_TYPES = ( 6 | (INTEGER, "Integer"), 7 | (STRING, "String"), 8 | (BOOLEAN, "Boolean"), 9 | ) 10 | -------------------------------------------------------------------------------- /api/features/versioning/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/versioning/__init__.py -------------------------------------------------------------------------------- /api/features/versioning/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class FeatureVersioningAppConfig(AppConfig): 5 | label = "feature_versioning" 6 | name = "features.versioning" 7 | 8 | def ready(self): # type: ignore[no-untyped-def] 9 | from . import receivers # noqa 10 | from . import signals # noqa 11 | -------------------------------------------------------------------------------- /api/features/versioning/constants.py: -------------------------------------------------------------------------------- 1 | # Constants to define how many days worth of version history should be 2 | # returned in the list endpoint based on the plan of the requesting organisation. 3 | DEFAULT_VERSION_LIMIT_DAYS = 7 4 | -------------------------------------------------------------------------------- /api/features/versioning/dataclasses.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from pydantic import BaseModel, computed_field 4 | 5 | 6 | class Conflict(BaseModel): 7 | segment_id: int | None = None 8 | original_cr_id: int | None = None 9 | published_at: datetime | None = None 10 | 11 | @computed_field # type: ignore[prop-decorator] 12 | @property 13 | def is_environment_default(self) -> bool: 14 | return self.segment_id is None 15 | -------------------------------------------------------------------------------- /api/features/versioning/exceptions.py: -------------------------------------------------------------------------------- 1 | from rest_framework import status 2 | from rest_framework.exceptions import APIException 3 | 4 | 5 | class FeatureVersioningError(APIException): 6 | pass 7 | 8 | 9 | class FeatureVersionDeleteError(FeatureVersioningError): 10 | status_code = status.HTTP_400_BAD_REQUEST 11 | 12 | 13 | class CannotModifyLiveVersionError(FeatureVersioningError): 14 | status_code = status.HTTP_400_BAD_REQUEST 15 | -------------------------------------------------------------------------------- /api/features/versioning/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/versioning/migrations/__init__.py -------------------------------------------------------------------------------- /api/features/versioning/signals.py: -------------------------------------------------------------------------------- 1 | from django.dispatch import Signal 2 | 3 | environment_feature_version_published = Signal() 4 | -------------------------------------------------------------------------------- /api/features/versioning/templates/versioning/scheduled_change_failed_conflict_email.txt: -------------------------------------------------------------------------------- 1 | Hi {{ user.first_name | default:"there" }}, 2 | 3 | Your change to feature '{{ feature.name }}' as part of change request '{{ change_request.title }}' was not published 4 | due to a conflict. 5 | 6 | Please review the change request and re-create the change. 7 | 8 | Thanks, 9 | The Flagsmith team -------------------------------------------------------------------------------- /api/features/workflows/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/workflows/__init__.py -------------------------------------------------------------------------------- /api/features/workflows/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/workflows/core/__init__.py -------------------------------------------------------------------------------- /api/features/workflows/core/apps.py: -------------------------------------------------------------------------------- 1 | from core.apps import BaseAppConfig 2 | 3 | 4 | class WorkflowsCoreAppConfig(BaseAppConfig): 5 | name = "features.workflows.core" 6 | label = "workflows_core" 7 | default = True 8 | -------------------------------------------------------------------------------- /api/features/workflows/core/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/features/workflows/core/migrations/__init__.py -------------------------------------------------------------------------------- /api/features/workflows/core/templates/workflows_core/change_request_approved_author_notification.txt: -------------------------------------------------------------------------------- 1 | Hi {{ author.full_name | default:"there" }}, 2 | 3 | Your change request has been approved{% if approver.full_name %} by {{ approver.full_name }}{% endif %}. Please click on the link below to see it. 4 | 5 | {{ url }} 6 | 7 | The Flagsmith Team -------------------------------------------------------------------------------- /api/features/workflows/core/templates/workflows_core/change_request_assignee_notification.txt: -------------------------------------------------------------------------------- 1 | Hi {{ approver.full_name | default:"there" }}, 2 | 3 | You have been assigned to a change request on Flagsmith{% if author.full_name %} created by {{ author.full_name }}{% endif %}. Click on the link below to see it. 4 | 5 | {{ url }} 6 | 7 | The Flagsmith Team -------------------------------------------------------------------------------- /api/import_export/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/import_export/__init__.py -------------------------------------------------------------------------------- /api/import_export/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/import_export/management/__init__.py -------------------------------------------------------------------------------- /api/import_export/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/import_export/management/commands/__init__.py -------------------------------------------------------------------------------- /api/integrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/amplitude/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/amplitude/__init__.py -------------------------------------------------------------------------------- /api/integrations/amplitude/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class AmplitudeIntegrationConfig(AppConfig): 6 | name = "integrations.amplitude" 7 | -------------------------------------------------------------------------------- /api/integrations/amplitude/constants.py: -------------------------------------------------------------------------------- 1 | DEFAULT_AMPLITUDE_API_URL = "https://api2.amplitude.com" 2 | -------------------------------------------------------------------------------- /api/integrations/amplitude/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/amplitude/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/amplitude/serializers.py: -------------------------------------------------------------------------------- 1 | from integrations.amplitude.models import AmplitudeConfiguration 2 | from integrations.common.serializers import ( 3 | BaseEnvironmentIntegrationModelSerializer, 4 | ) 5 | 6 | 7 | class AmplitudeConfigurationSerializer(BaseEnvironmentIntegrationModelSerializer): 8 | class Meta: 9 | model = AmplitudeConfiguration 10 | fields = ("id", "api_key", "base_url") 11 | -------------------------------------------------------------------------------- /api/integrations/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/common/__init__.py -------------------------------------------------------------------------------- /api/integrations/datadog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/datadog/__init__.py -------------------------------------------------------------------------------- /api/integrations/datadog/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class DataDogConfigurationConfig(AppConfig): 6 | name = "integrations.datadog" 7 | -------------------------------------------------------------------------------- /api/integrations/datadog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/datadog/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/datadog/serializers.py: -------------------------------------------------------------------------------- 1 | from integrations.common.serializers import ( 2 | BaseProjectIntegrationModelSerializer, 3 | ) 4 | 5 | from .models import DataDogConfiguration 6 | 7 | 8 | class DataDogConfigurationSerializer(BaseProjectIntegrationModelSerializer): 9 | class Meta: 10 | model = DataDogConfiguration 11 | fields = ("id", "base_url", "api_key", "use_custom_source") 12 | -------------------------------------------------------------------------------- /api/integrations/datadog/views.py: -------------------------------------------------------------------------------- 1 | from integrations.common.views import ProjectIntegrationBaseViewSet 2 | from integrations.datadog.models import DataDogConfiguration 3 | from integrations.datadog.serializers import DataDogConfigurationSerializer 4 | 5 | 6 | class DataDogConfigurationViewSet(ProjectIntegrationBaseViewSet): 7 | serializer_class = DataDogConfigurationSerializer # type: ignore[assignment] 8 | model_class = DataDogConfiguration # type: ignore[assignment] 9 | -------------------------------------------------------------------------------- /api/integrations/dynatrace/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/dynatrace/__init__.py -------------------------------------------------------------------------------- /api/integrations/dynatrace/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class DynatraceConfigurationConfig(AppConfig): 6 | name = "integrations.dynatrace" 7 | -------------------------------------------------------------------------------- /api/integrations/dynatrace/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/dynatrace/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/dynatrace/serializers.py: -------------------------------------------------------------------------------- 1 | from integrations.common.serializers import ( 2 | BaseEnvironmentIntegrationModelSerializer, 3 | ) 4 | 5 | from .models import DynatraceConfiguration 6 | 7 | 8 | class DynatraceConfigurationSerializer(BaseEnvironmentIntegrationModelSerializer): 9 | class Meta: 10 | model = DynatraceConfiguration 11 | fields = ("id", "base_url", "api_key", "entity_selector") 12 | -------------------------------------------------------------------------------- /api/integrations/flagsmith/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/flagsmith/__init__.py -------------------------------------------------------------------------------- /api/integrations/flagsmith/exceptions.py: -------------------------------------------------------------------------------- 1 | class FlagsmithIntegrationError(Exception): 2 | pass 3 | -------------------------------------------------------------------------------- /api/integrations/flagsmith/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/flagsmith/management/__init__.py -------------------------------------------------------------------------------- /api/integrations/flagsmith/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/flagsmith/management/commands/__init__.py -------------------------------------------------------------------------------- /api/integrations/flagsmith/management/commands/updateflagsmithenvironment.py: -------------------------------------------------------------------------------- 1 | from django.core.management import BaseCommand 2 | 3 | from integrations.flagsmith.flagsmith_service import update_environment_json 4 | 5 | 6 | class Command(BaseCommand): 7 | def handle(self, *args, **options): # type: ignore[no-untyped-def] 8 | update_environment_json() 9 | -------------------------------------------------------------------------------- /api/integrations/github/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/github/__init__.py -------------------------------------------------------------------------------- /api/integrations/github/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class GithubIntegrationConfig(AppConfig): 6 | name = "integrations.github" 7 | -------------------------------------------------------------------------------- /api/integrations/github/exceptions.py: -------------------------------------------------------------------------------- 1 | from rest_framework.exceptions import APIException 2 | 3 | 4 | class DuplicateGitHubIntegration(APIException): 5 | status_code = 400 6 | default_detail = "Duplication error. The GitHub integration already created" 7 | -------------------------------------------------------------------------------- /api/integrations/github/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/github/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/grafana/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/grafana/__init__.py -------------------------------------------------------------------------------- /api/integrations/grafana/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class GrafanaConfigurationConfig(AppConfig): 6 | name = "integrations.grafana" 7 | -------------------------------------------------------------------------------- /api/integrations/grafana/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/grafana/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/heap/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/heap/__init__.py -------------------------------------------------------------------------------- /api/integrations/heap/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class HeapIntegrationConfig(AppConfig): 6 | name = "integrations.heap" 7 | -------------------------------------------------------------------------------- /api/integrations/heap/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/heap/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/heap/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from environments.models import Environment 4 | from integrations.common.models import EnvironmentIntegrationModel 5 | 6 | 7 | class HeapConfiguration(EnvironmentIntegrationModel): 8 | environment = models.OneToOneField( 9 | Environment, related_name="heap_config", on_delete=models.CASCADE 10 | ) 11 | -------------------------------------------------------------------------------- /api/integrations/heap/serializers.py: -------------------------------------------------------------------------------- 1 | from integrations.common.serializers import ( 2 | BaseEnvironmentIntegrationModelSerializer, 3 | ) 4 | from integrations.heap.models import HeapConfiguration 5 | 6 | 7 | class HeapConfigurationSerializer(BaseEnvironmentIntegrationModelSerializer): 8 | class Meta: 9 | model = HeapConfiguration 10 | fields = ("id", "api_key") 11 | -------------------------------------------------------------------------------- /api/integrations/heap/views.py: -------------------------------------------------------------------------------- 1 | from integrations.common.views import EnvironmentIntegrationCommonViewSet 2 | from integrations.heap.models import HeapConfiguration 3 | from integrations.heap.serializers import HeapConfigurationSerializer 4 | 5 | 6 | class HeapConfigurationViewSet(EnvironmentIntegrationCommonViewSet): 7 | serializer_class = HeapConfigurationSerializer # type: ignore[assignment] 8 | model_class = HeapConfiguration # type: ignore[assignment] 9 | -------------------------------------------------------------------------------- /api/integrations/launch_darkly/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/launch_darkly/__init__.py -------------------------------------------------------------------------------- /api/integrations/launch_darkly/apps.py: -------------------------------------------------------------------------------- 1 | from core.apps import BaseAppConfig 2 | 3 | 4 | class LaunchDarklyConfigurationConfig(BaseAppConfig): 5 | name = "integrations.launch_darkly" 6 | default = True 7 | -------------------------------------------------------------------------------- /api/integrations/launch_darkly/constants.py: -------------------------------------------------------------------------------- 1 | LAUNCH_DARKLY_API_BASE_URL = "https://app.launchdarkly.com" 2 | LAUNCH_DARKLY_API_VERSION = "20220603" 3 | # Maximum limit for /api/v2/projects/ 4 | # /api/v2/flags/ seemingly not limited, but let's not get too greedy 5 | LAUNCH_DARKLY_API_ITEM_COUNT_LIMIT_PER_PAGE = 1000 6 | 7 | LAUNCH_DARKLY_IMPORTED_TAG_COLOR = "#3d4db6" 8 | LAUNCH_DARKLY_IMPORTED_DEFAULT_TAG_LABEL = "Imported" 9 | 10 | BACKOFF_MAX_RETRIES = 5 11 | -------------------------------------------------------------------------------- /api/integrations/launch_darkly/exceptions.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | 4 | class LaunchDarklyAPIError(Exception): 5 | """Base exception for LaunchDarkly integration errors.""" 6 | 7 | 8 | class LaunchDarklyRateLimitError(LaunchDarklyAPIError): 9 | """Exception raised when the LaunchDarkly API rate limit is exceeded.""" 10 | 11 | def __init__(self, retry_at: datetime): 12 | super().__init__() 13 | self.retry_at = retry_at 14 | -------------------------------------------------------------------------------- /api/integrations/launch_darkly/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/launch_darkly/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/lead_tracking/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/lead_tracking/__init__.py -------------------------------------------------------------------------------- /api/integrations/lead_tracking/hubspot/constants.py: -------------------------------------------------------------------------------- 1 | HUBSPOT_COOKIE_NAME = "hubspotutk" 2 | HUBSPOT_PORTAL_ID = "143451822" 3 | HUBSPOT_FORM_ID = "562ee023-fb3f-4645-a217-4d8c9b4e45be" 4 | HUBSPOT_ROOT_FORM_URL = "https://api.hsforms.com/submissions/v3/integration/submit" 5 | HUBSPOT_API_LEAD_SOURCE_SELF_HOSTED = "self-hosted" 6 | HUBSPOT_ACTIVE_SUBSCRIPTION_SELF_HOSTED = "free-opensource" 7 | -------------------------------------------------------------------------------- /api/integrations/lead_tracking/pipedrive/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/lead_tracking/pipedrive/__init__.py -------------------------------------------------------------------------------- /api/integrations/lead_tracking/pipedrive/constants.py: -------------------------------------------------------------------------------- 1 | class MarketingStatus: 2 | NO_CONSENT = "no_consent" 3 | SUBSCRIBED = "subscribed" 4 | UNSUBSCRIBED = "unsubscribed" 5 | ARCHIVED = "archived" 6 | 7 | 8 | MARKETING_STATUSES = ( 9 | MarketingStatus.NO_CONSENT, 10 | MarketingStatus.SUBSCRIBED, 11 | MarketingStatus.UNSUBSCRIBED, 12 | MarketingStatus.ARCHIVED, 13 | ) 14 | -------------------------------------------------------------------------------- /api/integrations/lead_tracking/pipedrive/exceptions.py: -------------------------------------------------------------------------------- 1 | class PipedriveError(Exception): 2 | pass 3 | 4 | 5 | class PipedriveAPIError(PipedriveError): 6 | pass 7 | 8 | 9 | class MultipleMatchingOrganizationsError(PipedriveError): 10 | pass 11 | 12 | 13 | class EntityNotFoundError(PipedriveError): 14 | pass 15 | -------------------------------------------------------------------------------- /api/integrations/mixpanel/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/mixpanel/__init__.py -------------------------------------------------------------------------------- /api/integrations/mixpanel/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class MixpanelIntegrationConfig(AppConfig): 6 | name = "integrations.mixpanel" 7 | -------------------------------------------------------------------------------- /api/integrations/mixpanel/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/mixpanel/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/mixpanel/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from environments.models import Environment 4 | from integrations.common.models import EnvironmentIntegrationModel 5 | 6 | 7 | class MixpanelConfiguration(EnvironmentIntegrationModel): 8 | environment = models.OneToOneField( 9 | Environment, related_name="mixpanel_config", on_delete=models.CASCADE 10 | ) 11 | -------------------------------------------------------------------------------- /api/integrations/mixpanel/serializers.py: -------------------------------------------------------------------------------- 1 | from integrations.common.serializers import ( 2 | BaseEnvironmentIntegrationModelSerializer, 3 | ) 4 | from integrations.mixpanel.models import MixpanelConfiguration 5 | 6 | 7 | class MixpanelConfigurationSerializer(BaseEnvironmentIntegrationModelSerializer): 8 | class Meta: 9 | model = MixpanelConfiguration 10 | fields = ("id", "api_key") 11 | -------------------------------------------------------------------------------- /api/integrations/new_relic/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/new_relic/__init__.py -------------------------------------------------------------------------------- /api/integrations/new_relic/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class NewRelicConfigurationConfig(AppConfig): 6 | name = "integrations.new_relic" 7 | -------------------------------------------------------------------------------- /api/integrations/new_relic/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/new_relic/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/new_relic/serializers.py: -------------------------------------------------------------------------------- 1 | from integrations.common.serializers import ( 2 | BaseProjectIntegrationModelSerializer, 3 | ) 4 | 5 | from .models import NewRelicConfiguration 6 | 7 | 8 | class NewRelicConfigurationSerializer(BaseProjectIntegrationModelSerializer): 9 | class Meta: 10 | model = NewRelicConfiguration 11 | fields = ("id", "base_url", "api_key", "app_id") 12 | -------------------------------------------------------------------------------- /api/integrations/new_relic/views.py: -------------------------------------------------------------------------------- 1 | from integrations.common.views import ProjectIntegrationBaseViewSet 2 | from integrations.new_relic.models import NewRelicConfiguration 3 | from integrations.new_relic.serializers import NewRelicConfigurationSerializer 4 | 5 | 6 | class NewRelicConfigurationViewSet(ProjectIntegrationBaseViewSet): 7 | serializer_class = NewRelicConfigurationSerializer # type: ignore[assignment] 8 | model_class = NewRelicConfiguration # type: ignore[assignment] 9 | -------------------------------------------------------------------------------- /api/integrations/opencensus/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/opencensus/__init__.py -------------------------------------------------------------------------------- /api/integrations/rudderstack/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/rudderstack/__init__.py -------------------------------------------------------------------------------- /api/integrations/rudderstack/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class RudderstackIntegrationConfig(AppConfig): 6 | name = "integrations.rudderstack" 7 | -------------------------------------------------------------------------------- /api/integrations/rudderstack/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/rudderstack/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/rudderstack/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from environments.models import Environment 4 | from integrations.common.models import EnvironmentIntegrationModel 5 | 6 | 7 | class RudderstackConfiguration(EnvironmentIntegrationModel): 8 | environment = models.OneToOneField( 9 | Environment, related_name="rudderstack_config", on_delete=models.CASCADE 10 | ) 11 | -------------------------------------------------------------------------------- /api/integrations/rudderstack/serializers.py: -------------------------------------------------------------------------------- 1 | from integrations.common.serializers import ( 2 | BaseEnvironmentIntegrationModelSerializer, 3 | ) 4 | from integrations.rudderstack.models import RudderstackConfiguration 5 | 6 | 7 | class RudderstackConfigurationSerializer(BaseEnvironmentIntegrationModelSerializer): 8 | class Meta: 9 | model = RudderstackConfiguration 10 | fields = ("id", "base_url", "api_key") 11 | -------------------------------------------------------------------------------- /api/integrations/segment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/segment/__init__.py -------------------------------------------------------------------------------- /api/integrations/segment/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class SegmentIntegrationConfig(AppConfig): 6 | name = "integrations.segment" 7 | -------------------------------------------------------------------------------- /api/integrations/segment/constants.py: -------------------------------------------------------------------------------- 1 | DEFAULT_BASE_URL = "https://api.segment.io/" 2 | DUBLIN_BASE_URL = "https://events.eu1.segmentapis.com/" 3 | -------------------------------------------------------------------------------- /api/integrations/segment/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/segment/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/segment/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from environments.models import Environment 4 | from integrations.common.models import EnvironmentIntegrationModel 5 | 6 | 7 | class SegmentConfiguration(EnvironmentIntegrationModel): 8 | environment = models.OneToOneField( 9 | Environment, related_name="segment_config", on_delete=models.CASCADE 10 | ) 11 | -------------------------------------------------------------------------------- /api/integrations/sentry/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/sentry/__init__.py -------------------------------------------------------------------------------- /api/integrations/slack/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/slack/__init__.py -------------------------------------------------------------------------------- /api/integrations/slack/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class SlackConfig(AppConfig): 5 | name = "integrations.slack" 6 | -------------------------------------------------------------------------------- /api/integrations/slack/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/slack/migrations/__init__.py -------------------------------------------------------------------------------- /api/integrations/webhook/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/webhook/__init__.py -------------------------------------------------------------------------------- /api/integrations/webhook/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.apps import AppConfig 3 | 4 | 5 | class WebhookIntegrationConfig(AppConfig): 6 | name = "integrations.webhook" 7 | -------------------------------------------------------------------------------- /api/integrations/webhook/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/integrations/webhook/migrations/__init__.py -------------------------------------------------------------------------------- /api/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | 4 | from common.core.main import main 5 | 6 | if __name__ == "__main__": 7 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings.local") 8 | 9 | main() 10 | -------------------------------------------------------------------------------- /api/metadata/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/metadata/__init__.py -------------------------------------------------------------------------------- /api/metadata/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class MetadataConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "metadata" 7 | -------------------------------------------------------------------------------- /api/metadata/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/metadata/migrations/__init__.py -------------------------------------------------------------------------------- /api/metadata/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include 2 | from django.urls import path 3 | from rest_framework_nested import routers # type: ignore[import-untyped] 4 | 5 | from .views import MetadataFieldViewSet 6 | 7 | router = routers.DefaultRouter() 8 | 9 | router.register(r"fields", MetadataFieldViewSet, basename="metadata-fields") 10 | 11 | 12 | app_name = "metadata" 13 | 14 | urlpatterns = [ 15 | path("", include(router.urls)), 16 | ] 17 | -------------------------------------------------------------------------------- /api/onboarding/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/onboarding/__init__.py -------------------------------------------------------------------------------- /api/onboarding/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OnboardingConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "onboarding" 7 | -------------------------------------------------------------------------------- /api/onboarding/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class SelfHostedOnboardingSupportSerializer(serializers.Serializer): # type: ignore[type-arg] 5 | organisation_name = serializers.CharField() 6 | first_name = serializers.CharField() 7 | last_name = serializers.CharField() 8 | email = serializers.EmailField() 9 | -------------------------------------------------------------------------------- /api/openapi-filter-grafana.yaml: -------------------------------------------------------------------------------- 1 | inverseOperationIds: 2 | # List operations used by Flagsmith's Grafana integration here. 3 | - RoutePostContactpoints 4 | - postAnnotation 5 | unusedComponents: 6 | - schemas 7 | - parameters 8 | - examples 9 | - headers 10 | - responses 11 | -------------------------------------------------------------------------------- /api/openapi-filter-launchdarkly.yaml: -------------------------------------------------------------------------------- 1 | inverseOperationIds: 2 | # List operations used by Flagsmith's LaucnhDarkly importer here. 3 | - getProject 4 | - getEnvironmentsByProject 5 | - getFeatureFlags 6 | - getTags 7 | - getSegments 8 | unusedComponents: 9 | - schemas 10 | - parameters 11 | - examples 12 | - headers 13 | - requestBodies 14 | - responses 15 | -------------------------------------------------------------------------------- /api/organisations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/__init__.py -------------------------------------------------------------------------------- /api/organisations/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.apps import AppConfig 5 | 6 | 7 | class OrganisationsConfig(AppConfig): 8 | name = "organisations" 9 | -------------------------------------------------------------------------------- /api/organisations/chargebee/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ChargebeeAppConfig(AppConfig): 5 | name = "organisations.chargebee" 6 | -------------------------------------------------------------------------------- /api/organisations/chargebee/constants.py: -------------------------------------------------------------------------------- 1 | ADDITIONAL_SEAT_ADDON_ID = "additional-team-members-scale-up-v2-monthly" 2 | 3 | ADDITIONAL_API_START_UP_ADDON_ID = "additional-api-start-up-monthly" 4 | ADDITIONAL_API_SCALE_UP_ADDON_ID = "additional-api-scale-up-monthly" 5 | -------------------------------------------------------------------------------- /api/organisations/chargebee/tasks.py: -------------------------------------------------------------------------------- 1 | from task_processor.decorators import ( 2 | register_task_handler, 3 | ) 4 | 5 | from organisations.chargebee.cache import ChargebeeCache 6 | 7 | 8 | @register_task_handler() 9 | def update_chargebee_cache(): # type: ignore[no-untyped-def] 10 | chargebee_cache = ChargebeeCache() # type: ignore[no-untyped-call] 11 | chargebee_cache.refresh() # type: ignore[no-untyped-call] 12 | -------------------------------------------------------------------------------- /api/organisations/constants.py: -------------------------------------------------------------------------------- 1 | API_USAGE_ALERT_THRESHOLDS = [75, 90, 100, 120, 200, 300, 400, 500] 2 | API_USAGE_GRACE_PERIOD = 7 3 | ALERT_EMAIL_MESSAGE = ( 4 | "Organisation %s has used %d seats which is over their plan limit of %d (plan: %s)" 5 | ) 6 | ALERT_EMAIL_SUBJECT = "Organisation over number of seats" 7 | -------------------------------------------------------------------------------- /api/organisations/exceptions.py: -------------------------------------------------------------------------------- 1 | from rest_framework.exceptions import APIException 2 | 3 | 4 | class OrganisationHasNoPaidSubscription(APIException): 5 | status_code = 400 6 | default_detail = "Organisation has no subscription" 7 | -------------------------------------------------------------------------------- /api/organisations/invites/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/invites/__init__.py -------------------------------------------------------------------------------- /api/organisations/invites/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class InvitesConfig(AppConfig): 5 | name = "organisations.invites" 6 | -------------------------------------------------------------------------------- /api/organisations/invites/exceptions.py: -------------------------------------------------------------------------------- 1 | from rest_framework.exceptions import APIException 2 | 3 | 4 | class InviteExpiredError(APIException): 5 | status_code = 400 6 | default_detail = "Invite has expired" 7 | 8 | 9 | class InviteLinksDisabledError(APIException): 10 | status_code = 400 11 | default_detail = "Invite links are disabled." 12 | -------------------------------------------------------------------------------- /api/organisations/invites/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/invites/migrations/__init__.py -------------------------------------------------------------------------------- /api/organisations/managers.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Manager 2 | 3 | from permissions.models import ORGANISATION_PERMISSION_TYPE 4 | 5 | 6 | class OrganisationPermissionManager(Manager): # type: ignore[type-arg] 7 | def get_queryset(self): # type: ignore[no-untyped-def] 8 | return super().get_queryset().filter(type=ORGANISATION_PERMISSION_TYPE) 9 | -------------------------------------------------------------------------------- /api/organisations/migrations/0041_merge_20230621_0946.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.19 on 2023-06-21 09:46 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('organisations', '0040_alter_organisationwebhook_url'), 10 | ('organisations', '0040_organisationsubscriptioninformationcache_chargebee_email'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /api/organisations/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/migrations/__init__.py -------------------------------------------------------------------------------- /api/organisations/permissions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/permissions/__init__.py -------------------------------------------------------------------------------- /api/organisations/permissions/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OrganisationPermissionsConfig(AppConfig): 5 | name = "organisations.permissions" 6 | label = "organisation_permissions" 7 | -------------------------------------------------------------------------------- /api/organisations/permissions/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/permissions/migrations/__init__.py -------------------------------------------------------------------------------- /api/organisations/subscriptions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/subscriptions/__init__.py -------------------------------------------------------------------------------- /api/organisations/subscriptions/serializers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/subscriptions/serializers/__init__.py -------------------------------------------------------------------------------- /api/organisations/subscriptions/xero/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/organisations/subscriptions/xero/__init__.py -------------------------------------------------------------------------------- /api/organisations/subscriptions/xero/metadata.py: -------------------------------------------------------------------------------- 1 | from organisations.subscriptions.constants import XERO 2 | from organisations.subscriptions.metadata import BaseSubscriptionMetadata 3 | 4 | 5 | class XeroSubscriptionMetadata(BaseSubscriptionMetadata): 6 | payment_source = XERO # type: ignore[assignment] 7 | -------------------------------------------------------------------------------- /api/permissions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/permissions/__init__.py -------------------------------------------------------------------------------- /api/permissions/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/permissions/migrations/__init__.py -------------------------------------------------------------------------------- /api/projects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/projects/__init__.py -------------------------------------------------------------------------------- /api/projects/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.apps import AppConfig 5 | 6 | 7 | class ProjectsConfig(AppConfig): 8 | name = "projects" 9 | -------------------------------------------------------------------------------- /api/projects/managers.py: -------------------------------------------------------------------------------- 1 | from softdelete.models import SoftDeleteManager # type: ignore[import-untyped] 2 | 3 | from core.models import AbstractBaseExportableModelManager 4 | 5 | 6 | class ProjectManager(SoftDeleteManager, AbstractBaseExportableModelManager): # type: ignore[misc] 7 | def get_queryset(self): # type: ignore[no-untyped-def] 8 | return super().get_queryset().select_related("organisation") 9 | -------------------------------------------------------------------------------- /api/projects/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/projects/migrations/__init__.py -------------------------------------------------------------------------------- /api/projects/tags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/projects/tags/__init__.py -------------------------------------------------------------------------------- /api/projects/tags/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from projects.tags.models import Tag 4 | 5 | 6 | # Register your models here. 7 | @admin.register(Tag) 8 | class TagAdmin(admin.ModelAdmin): # type: ignore[type-arg] 9 | list_display = ("label", "color", "project") 10 | list_select_related = ("project",) 11 | search_fields = ( 12 | "label", 13 | "project__name", 14 | ) 15 | -------------------------------------------------------------------------------- /api/projects/tags/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class TagsConfig(AppConfig): 5 | name = "projects.tags" 6 | -------------------------------------------------------------------------------- /api/projects/tags/migrations/0002_auto_20210223_1603.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2021-02-23 16:03 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('tags', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='tag', 15 | options={'ordering': ('id',)}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /api/projects/tags/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/projects/tags/migrations/__init__.py -------------------------------------------------------------------------------- /api/readme.md: -------------------------------------------------------------------------------- 1 | # We've moved 2 | 3 | API deployment and development instructions have 4 | [moved to our Docs site](https://docs.flagsmith.com/deployment/locally-api) 5 | -------------------------------------------------------------------------------- /api/sales_dashboard/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/sales_dashboard/__init__.py -------------------------------------------------------------------------------- /api/sales_dashboard/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class SalesDashboardConfig(AppConfig): 5 | name = "sales_dashboard" 6 | -------------------------------------------------------------------------------- /api/sales_dashboard/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/sales_dashboard/migrations/__init__.py -------------------------------------------------------------------------------- /api/sales_dashboard/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/sales_dashboard/templatetags/__init__.py -------------------------------------------------------------------------------- /api/scripts/healthcheck.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import sys 3 | 4 | from common.core.main import main 5 | 6 | if __name__ == "__main__": 7 | logging.getLogger(__name__).warning( 8 | f"This healthcheck, invoked by `{' '.join(sys.argv)}``, is deprecated. " 9 | "Please use one of the `flagsmith healthcheck` commands instead." 10 | ) 11 | main(["flagsmith", "healthcheck", "http"]) 12 | -------------------------------------------------------------------------------- /api/scripts/run-docker-dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | python manage.py migrate 5 | python manage.py collectstatic --no-input 6 | python manage.py runserver 0.0.0.0:8000 7 | -------------------------------------------------------------------------------- /api/segments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/segments/__init__.py -------------------------------------------------------------------------------- /api/segments/apps.py: -------------------------------------------------------------------------------- 1 | from core.apps import BaseAppConfig 2 | 3 | 4 | class SegmentsConfig(BaseAppConfig): 5 | name = "segments" 6 | default = True 7 | -------------------------------------------------------------------------------- /api/segments/migrations/0008_auto_20210223_1603.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2021-02-23 16:03 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('segments', '0007_auto_20190906_1416'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='segment', 15 | options={'ordering': ('id',)}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /api/segments/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/segments/migrations/__init__.py -------------------------------------------------------------------------------- /api/segments/migrations/sql/0023_add_versioning_to_segments.sql: -------------------------------------------------------------------------------- 1 | UPDATE segments_segment SET version_of_id = id; 2 | -------------------------------------------------------------------------------- /api/segments/migrations/sql/0023_add_versioning_to_segments_reverse.sql: -------------------------------------------------------------------------------- 1 | UPDATE segments_segment 2 | SET deleted_at = now() 3 | WHERE version_of_id <> id; 4 | -------------------------------------------------------------------------------- /api/segments/tasks.py: -------------------------------------------------------------------------------- 1 | from task_processor.decorators import ( 2 | register_task_handler, 3 | ) 4 | 5 | from segments.models import Segment 6 | 7 | 8 | @register_task_handler() 9 | def delete_segment(segment_id: int) -> None: 10 | Segment.objects.get(pk=segment_id).delete() 11 | -------------------------------------------------------------------------------- /api/segments/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from .views import get_segment_by_uuid 4 | 5 | app_name = "segments" 6 | 7 | 8 | urlpatterns = [ 9 | path("get-by-uuid//", get_segment_by_uuid, name="get-segment-by-uuid"), 10 | ] 11 | -------------------------------------------------------------------------------- /api/sse/__init__.py: -------------------------------------------------------------------------------- 1 | from .sse_service import ( # noqa 2 | send_environment_update_message_for_environment, 3 | send_environment_update_message_for_project, 4 | ) 5 | -------------------------------------------------------------------------------- /api/sse/dataclasses.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | 4 | @dataclass(eq=True) 5 | class SSEAccessLogs: 6 | generated_at: str # ISO 8601 7 | api_key: str 8 | -------------------------------------------------------------------------------- /api/sse/exceptions.py: -------------------------------------------------------------------------------- 1 | class SSEAuthTokenNotSet(Exception): 2 | pass 3 | 4 | 5 | class ViewResponseDoesNotHaveStatus(Exception): 6 | pass 7 | -------------------------------------------------------------------------------- /api/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/static/.gitkeep -------------------------------------------------------------------------------- /api/telemetry/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/telemetry/__init__.py -------------------------------------------------------------------------------- /api/templates/admin/base_site.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | {% block title %}{{ title }} | {{ site_title|default:_('NEW TITLE') }}{% endblock %} 4 | 5 | {% block branding %} 6 |

Unless instructed by Flagsmith, modifying data here is not supported and may cause issues in your installation.

7 | {% endblock %} 8 | 9 | {% block nav-global %}{% endblock %} 10 | -------------------------------------------------------------------------------- /api/templates/admin/login.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/login.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block content %} 6 | 7 | {% if show_login_form %} 8 | {{ block.super }} 9 | {% endif %} 10 | 11 | {% endblock content %} -------------------------------------------------------------------------------- /api/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/api_keys/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/api_keys/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/environments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/environments/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/environments/identities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/environments/identities/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/features/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/features/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/features/feature_health/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/features/feature_health/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/features/featurestate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/features/featurestate/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/features/multivariate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/features/multivariate/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/features/versioning/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/features/versioning/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/projects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/projects/__init__.py -------------------------------------------------------------------------------- /api/tests/integration/sales_dashboard/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/integration/sales_dashboard/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/api/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/api_keys/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/api_keys/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/app/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/app_analytics/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/app_analytics/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/audit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/audit/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/core/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/core/management/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/custom_auth/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from organisations.invites.models import InviteLink 4 | from organisations.models import Organisation 5 | 6 | 7 | @pytest.fixture() 8 | def invite_link(organisation: Organisation) -> InviteLink: 9 | return InviteLink.objects.create(organisation=organisation) # type: ignore[no-any-return] 10 | -------------------------------------------------------------------------------- /api/tests/unit/custom_auth/mfa/trench/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/custom_auth/mfa/trench/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/edge_api/identities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/edge_api/identities/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/environments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/environments/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/environments/conftest.py: -------------------------------------------------------------------------------- 1 | from unittest.mock import Mock 2 | 3 | import pytest 4 | from pytest_mock import MockerFixture 5 | 6 | 7 | @pytest.fixture() 8 | def mock_dynamo_env_wrapper(mocker: MockerFixture) -> Mock: 9 | return mocker.patch("environments.models.environment_wrapper") 10 | 11 | 12 | @pytest.fixture() 13 | def mock_dynamo_env_v2_wrapper(mocker: MockerFixture) -> Mock: 14 | return mocker.patch("environments.models.environment_v2_wrapper") 15 | -------------------------------------------------------------------------------- /api/tests/unit/environments/dynamodb/wrappers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/environments/dynamodb/wrappers/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/environments/identities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/environments/identities/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/environments/identities/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from environments.identities.models import Identity 4 | 5 | 6 | @pytest.fixture() 7 | def identity_one(organisation_one_project_one_environment_one): # type: ignore[no-untyped-def] 8 | return Identity.objects.create( 9 | identifier="identity_1", 10 | environment=organisation_one_project_one_environment_one, 11 | ) 12 | -------------------------------------------------------------------------------- /api/tests/unit/environments/identities/traits/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/environments/identities/traits/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/environments/permissions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/environments/permissions/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/environments/sdk/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/environments/sdk/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/features/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/features/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/features/feature_health/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/features/feature_health/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/features/feature_segments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/features/feature_segments/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/features/multivariate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/features/multivariate/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/features/versioning/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/features/versioning/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/features/versioning/test_unit_versioning_dataclasses.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from features.versioning.dataclasses import Conflict 4 | 5 | 6 | @pytest.mark.parametrize("segment_id, expected_result", ((None, True), (1, False))) 7 | def test_conflict_is_environment_default( 8 | segment_id: int | None, expected_result: bool 9 | ) -> None: 10 | assert Conflict(segment_id=segment_id).is_environment_default is expected_result 11 | -------------------------------------------------------------------------------- /api/tests/unit/features/workflows/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/features/workflows/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/features/workflows/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/features/workflows/core/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/import_export/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/import_export/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/amplitude/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/amplitude/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/amplitude/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from integrations.amplitude.models import AmplitudeConfiguration 4 | 5 | 6 | @pytest.fixture() 7 | def deleted_amplitude_integration(environment): # type: ignore[no-untyped-def] 8 | amplitude_configuration = AmplitudeConfiguration.objects.create( 9 | environment=environment, api_key="some-key" 10 | ) 11 | amplitude_configuration.delete() 12 | return amplitude_configuration 13 | -------------------------------------------------------------------------------- /api/tests/unit/integrations/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/common/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/datadog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/datadog/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/datadog/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from integrations.datadog.models import DataDogConfiguration 4 | 5 | 6 | @pytest.fixture() 7 | def deleted_datadog_configuration(project): # type: ignore[no-untyped-def] 8 | configuration = DataDogConfiguration.objects.create( 9 | project=project, api_key="some-key" 10 | ) 11 | configuration.delete() 12 | return configuration 13 | -------------------------------------------------------------------------------- /api/tests/unit/integrations/flagsmith/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/flagsmith/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/github/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/github/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/grafana/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/grafana/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/heap/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/heap/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/launch_darkly/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/launch_darkly/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/launch_darkly/example_api_responses/getTags.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | "testtag", 4 | "testtag2" 5 | ], 6 | "_links": { 7 | "self": { 8 | "href": "/api/v2/tags", 9 | "type": "application/json" 10 | } 11 | }, 12 | "totalCount": 2 13 | } -------------------------------------------------------------------------------- /api/tests/unit/integrations/lead_tracking/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/lead_tracking/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/lead_tracking/pipedrive/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/lead_tracking/pipedrive/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/lead_tracking/pipedrive/example_api_responses/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/lead_tracking/pipedrive/example_api_responses/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/lead_tracking/pipedrive/example_api_responses/list_lead_labels.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true, 3 | "data": [ 4 | { 5 | "id": "f08b42a0-4e75-11ea-9643-03698ef1cfd6", 6 | "name": "Hot", 7 | "color": "red", 8 | "add_time": "2020-02-13T15:31:44.000Z", 9 | "update_time": "2020-02-13T15:31:44.000Z" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /api/tests/unit/integrations/new_relic/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/new_relic/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/new_relic/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from integrations.new_relic.models import NewRelicConfiguration 4 | 5 | 6 | @pytest.fixture() 7 | def deleted_newrelic_configuration(project): # type: ignore[no-untyped-def] 8 | configuration = NewRelicConfiguration.objects.create( 9 | project=project, api_key="some-key" 10 | ) 11 | configuration.delete() 12 | return configuration 13 | -------------------------------------------------------------------------------- /api/tests/unit/integrations/segment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/integrations/segment/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/integrations/slack/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | @pytest.fixture 5 | def mocked_slack_internal_client(mocker): # type: ignore[no-untyped-def] 6 | mocked_client = mocker.MagicMock() 7 | 8 | mocker.patch( 9 | "integrations.slack.slack.SlackWrapper._client", 10 | new_callable=mocker.PropertyMock, 11 | return_value=mocked_client, 12 | ) 13 | return mocked_client 14 | -------------------------------------------------------------------------------- /api/tests/unit/integrations/webhook/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from integrations.webhook.models import WebhookConfiguration 4 | 5 | 6 | @pytest.fixture() 7 | def integration_webhook_config(environment): # type: ignore[no-untyped-def] 8 | return WebhookConfiguration.objects.create( 9 | url="https://flagsmit.com/test-webhook", 10 | environment=environment, 11 | ) 12 | -------------------------------------------------------------------------------- /api/tests/unit/metadata/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/metadata/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/organisations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/organisations/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/organisations/chargebee/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/organisations/chargebee/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/organisations/invites/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/organisations/invites/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/organisations/permissions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/organisations/permissions/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/organisations/subscriptions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/organisations/subscriptions/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/organisations/subscriptions/serializers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/organisations/subscriptions/serializers/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/projects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/projects/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/projects/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from segments.models import Segment 4 | 5 | 6 | @pytest.fixture() 7 | def segments(project): # type: ignore[no-untyped-def] 8 | segments = [] 9 | for i in range(3): 10 | segments.append( 11 | Segment.objects.create(name=f"Test Segment {i}", project=project) 12 | ) 13 | return segments 14 | -------------------------------------------------------------------------------- /api/tests/unit/sales_dashboard/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/sales_dashboard/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/segments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/segments/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/sse/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/sse/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/telemetry/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/telemetry/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/users/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/users/__init__.py -------------------------------------------------------------------------------- /api/tests/unit/users/test_unit_users_forms.py: -------------------------------------------------------------------------------- 1 | from users.forms import CustomUserAdminForm 2 | 3 | 4 | def test_custom_user_admin_form_empty_value_of_username_is_none(db): # type: ignore[no-untyped-def] 5 | # Given 6 | form = CustomUserAdminForm({"email": "test@mail.com"}) 7 | # When 8 | form.is_valid() 9 | # Then 10 | assert form.cleaned_data["username"] is None 11 | -------------------------------------------------------------------------------- /api/tests/unit/users/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/tests/unit/users/utils/__init__.py -------------------------------------------------------------------------------- /api/users/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/users/__init__.py -------------------------------------------------------------------------------- /api/users/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class UsersConfig(AppConfig): 5 | name = "users" 6 | 7 | def ready(self): # type: ignore[no-untyped-def] 8 | from . import signals # noqa 9 | -------------------------------------------------------------------------------- /api/users/auth_type.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class AuthType(Enum): 5 | GOOGLE = "GOOGLE" 6 | GITHUB = "GITHUB" 7 | EMAIL = "EMAIL" 8 | -------------------------------------------------------------------------------- /api/users/constants.py: -------------------------------------------------------------------------------- 1 | DEFAULT_DELETE_ORPHAN_ORGANISATIONS_VALUE = False 2 | -------------------------------------------------------------------------------- /api/users/exceptions.py: -------------------------------------------------------------------------------- 1 | class InvalidInviteError(BaseException): 2 | pass 3 | -------------------------------------------------------------------------------- /api/users/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/users/management/__init__.py -------------------------------------------------------------------------------- /api/users/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/users/management/commands/__init__.py -------------------------------------------------------------------------------- /api/users/migrations/0029_auto_20210223_1603.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2021-02-23 16:03 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('users', '0028_delete_invite'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name='userpermissiongroup', 15 | options={'ordering': ('id',)}, 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /api/users/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/users/migrations/__init__.py -------------------------------------------------------------------------------- /api/users/templates/users/email_updated.txt: -------------------------------------------------------------------------------- 1 | Hi {{ first_name | default:"there" }}, 2 | 3 | A change was just made to update the email associated with your Flagsmith account. 4 | If you did not request this change, please contact support@flagsmith.com as soon as possible. 5 | 6 | The Flagsmith Team -------------------------------------------------------------------------------- /api/users/templates/users/invite_to_org.txt: -------------------------------------------------------------------------------- 1 | Hi there, 2 | 3 | You have been invited to join {{ org_name|safe }} on Flagsmith. Please click on the link below to accept. 4 | 5 | {{ invite_url }} 6 | 7 | The Flagsmith Team -------------------------------------------------------------------------------- /api/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/util/__init__.py -------------------------------------------------------------------------------- /api/util/history/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/util/history/__init__.py -------------------------------------------------------------------------------- /api/util/renderers.py: -------------------------------------------------------------------------------- 1 | from json import JSONEncoder 2 | from typing import Any, Type 3 | 4 | from pydantic.json import pydantic_encoder 5 | from rest_framework.renderers import JSONRenderer 6 | 7 | 8 | class PydanticJSONEncoder(JSONEncoder): 9 | def default(self, obj: Any) -> Any: 10 | return pydantic_encoder(obj) 11 | 12 | 13 | class PydanticJSONRenderer(JSONRenderer): 14 | encoder_class: Type[JSONEncoder] = PydanticJSONEncoder # type: ignore[misc] 15 | -------------------------------------------------------------------------------- /api/util/views.py: -------------------------------------------------------------------------------- 1 | from rest_framework.generics import GenericAPIView 2 | 3 | from environments.authentication import EnvironmentKeyAuthentication 4 | from environments.permissions.permissions import EnvironmentKeyPermissions 5 | 6 | 7 | class SDKAPIView(GenericAPIView): # type: ignore[type-arg] 8 | permission_classes = (EnvironmentKeyPermissions,) 9 | authentication_classes = (EnvironmentKeyAuthentication,) 10 | -------------------------------------------------------------------------------- /api/webhooks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/api/webhooks/__init__.py -------------------------------------------------------------------------------- /api/webhooks/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class WebhooksAppConfig(AppConfig): 5 | name = "webhooks" 6 | -------------------------------------------------------------------------------- /api/webhooks/constants.py: -------------------------------------------------------------------------------- 1 | WEBHOOK_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" 2 | -------------------------------------------------------------------------------- /api/webhooks/exceptions.py: -------------------------------------------------------------------------------- 1 | class WebhookSendError(Exception): 2 | pass 3 | -------------------------------------------------------------------------------- /api/webhooks/urls.py: -------------------------------------------------------------------------------- 1 | from rest_framework import routers 2 | 3 | from . import views 4 | 5 | app_name = "webhooks" 6 | 7 | router = routers.DefaultRouter() 8 | router.register(r"", views.WebhookViewSet, basename="webhooks") 9 | 10 | urlpatterns = router.urls 11 | -------------------------------------------------------------------------------- /depot.json: -------------------------------------------------------------------------------- 1 | {"id":"qsrts2l4gr"} 2 | -------------------------------------------------------------------------------- /docs/.nvmrc: -------------------------------------------------------------------------------- 1 | v20.10.0 2 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | .EXPORT_ALL_VARIABLES: 2 | 3 | DOTENV_OVERRIDE_FILE ?= .env 4 | 5 | -include .env-local 6 | -include $(DOTENV_OVERRIDE_FILE) 7 | 8 | .PHONY: install 9 | install: 10 | npm install 11 | 12 | .PHONY: lint-prettier 13 | lint-prettier: 14 | npx prettier --check . 15 | 16 | .PHONY: lint 17 | lint: lint-prettier build 18 | 19 | .PHONY: build 20 | build: 21 | npm run build 22 | 23 | .PHONY: serve 24 | serve: 25 | npm run serve 26 | -------------------------------------------------------------------------------- /docs/docs/advanced-use/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Advanced Use", 3 | "position": 40, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/basic-features/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Basic Features", 3 | "position": 30 4 | } 5 | -------------------------------------------------------------------------------- /docs/docs/billing/usage-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/docs/billing/usage-graph.png -------------------------------------------------------------------------------- /docs/docs/clients/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "SDKs", 3 | "position": 60, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/clients/client-side/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Client Side", 3 | "position": 3, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/deployment/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Deployment", 3 | "position": 80, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/deployment/configuration/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Configuration", 3 | "position": 20, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/deployment/configuration/authentication/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Authentication", 3 | "collapsed": false 4 | } 5 | -------------------------------------------------------------------------------- /docs/docs/deployment/configuration/usage-report-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/docs/deployment/configuration/usage-report-example.png -------------------------------------------------------------------------------- /docs/docs/deployment/hosting/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Hosting", 3 | "position": 10, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/deployment/hosting/openshift.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OpenShift 3 | description: Getting Started with Flagsmith on OpenShift 4 | sidebar_label: OpenShift 5 | sidebar_position: 60 6 | --- 7 | 8 | :::tip 9 | 10 | Support for our OpenShift Operator is only available with an [Enterprise plan](https://flagsmith.com/pricing/). 11 | 12 | ::: 13 | 14 | Flagsmith runs on the OpenShift platform via our [Helm charts](kubernetes.md). 15 | -------------------------------------------------------------------------------- /docs/docs/edge-api/_category_.yaml: -------------------------------------------------------------------------------- 1 | className: hidden 2 | -------------------------------------------------------------------------------- /docs/docs/guides-and-examples/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Guides & Examples", 3 | "position": 50, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/integrations/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Integrations", 3 | "position": 60, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/integrations/analytics/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Analytics", 3 | "collapsed": false, 4 | "position": 10 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/integrations/apm/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Observability", 3 | "collapsed": false, 4 | "position": 20 5 | } -------------------------------------------------------------------------------- /docs/docs/integrations/importers/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Importers", 3 | "collapsed": false, 4 | "position": 50 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/integrations/project-management/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Project Management", 3 | "collapsed": false, 4 | "position": 70 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/platform/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Platform", 3 | "position": 90, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/platform/roadmap.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | You can view our public roadmap on [GitHub](https://github.com/orgs/Flagsmith/projects/7). 4 | -------------------------------------------------------------------------------- /docs/docs/system-administration/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "System Administration", 3 | "position": 70, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/system-administration/architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Architecture 3 | --- 4 | 5 | ## Self Hosted / On Prem 6 | 7 | ![Image](/img/architecture.svg) 8 | 9 | ## SaaS 10 | 11 | ![Image](/img/saas-architecture.svg) 12 | -------------------------------------------------------------------------------- /docs/docs/system-administration/authentication/01-SAML/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "SAML", 3 | "collapsed": true 4 | } 5 | -------------------------------------------------------------------------------- /docs/docs/system-administration/authentication/05-ADFS.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ADFS 3 | --- 4 | 5 | :::tip 6 | 7 | ADFS authentication requires an [Enterprise subscription](https://flagsmith.com/pricing). 8 | 9 | ::: 10 | 11 | Please get in touch with [Flagsmith support](mailto:support@flagsmith.com) to use ADFS for authentication. 12 | -------------------------------------------------------------------------------- /docs/docs/system-administration/authentication/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Authentication", 3 | "collapsed": true 4 | } 5 | -------------------------------------------------------------------------------- /docs/docs/system-administration/importing-and-exporting/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Importing and Exporting", 3 | "position": 70, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/docs/system-administration/importing-and-exporting/django-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/docs/system-administration/importing-and-exporting/django-admin.png -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/logo.png -------------------------------------------------------------------------------- /docs/plugins/amplitude.js: -------------------------------------------------------------------------------- 1 | import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; 2 | import * as amplitude from '@amplitude/analytics-browser'; 3 | 4 | if (ExecutionEnvironment.canUseDOM) { 5 | window.addEventListener('load', () => { 6 | amplitude.init("541e058ce750dcdeb3a39d48a85f3425", { 7 | defaultTracking: true, 8 | serverZone: 'EU' 9 | }); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /docs/plugins/reo.js: -------------------------------------------------------------------------------- 1 | import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; 2 | 3 | if (ExecutionEnvironment.canUseDOM) { 4 | !function() { 5 | var e, t, n; 6 | e = '33be044a44400f2', t = function() { 7 | Reo.init({ clientID: '33be044a44400f2' }); 8 | }, (n = document.createElement('script')).src = 'https://static.reo.dev/' + e + '/reo.js', n.defer = !0, n.onload = t, document.head.appendChild(n); 9 | }(); 10 | } 11 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/fonts/bitter-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/bitter-bold.woff -------------------------------------------------------------------------------- /docs/static/fonts/bitter-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/bitter-bold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/bitter-extra-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/bitter-extra-bold.woff -------------------------------------------------------------------------------- /docs/static/fonts/bitter-extra-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/bitter-extra-bold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-bold.woff -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-bold.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-italic.woff -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-italic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-regular.woff -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-regular.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-semi-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-semi-bold-italic.woff -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-semi-bold-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-semi-bold-italic.woff2 -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-semi-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-semi-bold.woff -------------------------------------------------------------------------------- /docs/static/fonts/open-sans-semi-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/fonts/open-sans-semi-bold.woff2 -------------------------------------------------------------------------------- /docs/static/img/Flagsmith_GitHub_SignUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/Flagsmith_GitHub_SignUp.png -------------------------------------------------------------------------------- /docs/static/img/ab-test-paypal-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/ab-test-paypal-example.png -------------------------------------------------------------------------------- /docs/static/img/add-webhook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/add-webhook.png -------------------------------------------------------------------------------- /docs/static/img/api-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/api-key.png -------------------------------------------------------------------------------- /docs/static/img/api-usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/api-usage.png -------------------------------------------------------------------------------- /docs/static/img/banner-logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/banner-logo-dark.png -------------------------------------------------------------------------------- /docs/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/docusaurus.png -------------------------------------------------------------------------------- /docs/static/img/dynatrace_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/dynatrace_1.png -------------------------------------------------------------------------------- /docs/static/img/dynatrace_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/dynatrace_2.png -------------------------------------------------------------------------------- /docs/static/img/dynatrace_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/dynatrace_3.png -------------------------------------------------------------------------------- /docs/static/img/edge-api-enabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/edge-api-enabled.png -------------------------------------------------------------------------------- /docs/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/favicon.ico -------------------------------------------------------------------------------- /docs/static/img/flag-analytics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/flag-analytics.png -------------------------------------------------------------------------------- /docs/static/img/guides/fcm-segment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/guides/fcm-segment.png -------------------------------------------------------------------------------- /docs/static/img/guides/fcm-subscribed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/guides/fcm-subscribed.png -------------------------------------------------------------------------------- /docs/static/img/guides/fcm-user-override.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/guides/fcm-user-override.png -------------------------------------------------------------------------------- /docs/static/img/identity-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/identity-details.png -------------------------------------------------------------------------------- /docs/static/img/integrations/amplitude/amplitude-integration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/amplitude/amplitude-integration-1.png -------------------------------------------------------------------------------- /docs/static/img/integrations/amplitude/amplitude-integration-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/amplitude/amplitude-integration-2.png -------------------------------------------------------------------------------- /docs/static/img/integrations/datadog/datadog-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/datadog/datadog-3.png -------------------------------------------------------------------------------- /docs/static/img/integrations/datadog/datadog-dashboard-widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/datadog/datadog-dashboard-widget.png -------------------------------------------------------------------------------- /docs/static/img/integrations/dynatrace/dynatrace-events-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/dynatrace/dynatrace-events-panel.png -------------------------------------------------------------------------------- /docs/static/img/integrations/github/github-integration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/github/github-integration-1.png -------------------------------------------------------------------------------- /docs/static/img/integrations/heap/heap-integration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/heap/heap-integration-1.png -------------------------------------------------------------------------------- /docs/static/img/integrations/heap/heap-integration-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/heap/heap-integration-2.png -------------------------------------------------------------------------------- /docs/static/img/integrations/heap/heap-mv-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/heap/heap-mv-step-1.png -------------------------------------------------------------------------------- /docs/static/img/integrations/heap/heap-mv-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/heap/heap-mv-step-2.png -------------------------------------------------------------------------------- /docs/static/img/integrations/heap/heap-mv-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/heap/heap-mv-step-3.png -------------------------------------------------------------------------------- /docs/static/img/integrations/jira/associate-flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/jira/associate-flag.png -------------------------------------------------------------------------------- /docs/static/img/integrations/jira/flag-states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/jira/flag-states.png -------------------------------------------------------------------------------- /docs/static/img/integrations/jira/select-flagsmith.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/jira/select-flagsmith.png -------------------------------------------------------------------------------- /docs/static/img/integrations/mixpanel/mixpanel-integration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/mixpanel/mixpanel-integration-1.png -------------------------------------------------------------------------------- /docs/static/img/integrations/mixpanel/mixpanel-integration-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/mixpanel/mixpanel-integration-2.png -------------------------------------------------------------------------------- /docs/static/img/integrations/rudderstack/rudderstack-integration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/rudderstack/rudderstack-integration-1.png -------------------------------------------------------------------------------- /docs/static/img/integrations/segment/segment-integration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/segment/segment-integration-1.png -------------------------------------------------------------------------------- /docs/static/img/integrations/segment/segment-integration-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/integrations/segment/segment-integration-2.png -------------------------------------------------------------------------------- /docs/static/img/json-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/json-view.png -------------------------------------------------------------------------------- /docs/static/img/languages/java.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/languages/java.png -------------------------------------------------------------------------------- /docs/static/img/metadata/metadata-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/metadata/metadata-example.png -------------------------------------------------------------------------------- /docs/static/img/multi-variate-flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/multi-variate-flags.png -------------------------------------------------------------------------------- /docs/static/img/organisation-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/organisation-permissions.png -------------------------------------------------------------------------------- /docs/static/img/organisations-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/organisations-admin.png -------------------------------------------------------------------------------- /docs/static/img/percent-rollout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/percent-rollout.png -------------------------------------------------------------------------------- /docs/static/img/project-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/project-permissions.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_1.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_10.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_2.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_3.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_4.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_5.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_6.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_7.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_8.png -------------------------------------------------------------------------------- /docs/static/img/quickstart/demo_create_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/quickstart/demo_create_9.png -------------------------------------------------------------------------------- /docs/static/img/roles/role-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/roles/role-create.png -------------------------------------------------------------------------------- /docs/static/img/roles/role-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/roles/role-list.png -------------------------------------------------------------------------------- /docs/static/img/roles/role-project-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/roles/role-project-permissions.png -------------------------------------------------------------------------------- /docs/static/img/roles/role-user-assigned-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/roles/role-user-assigned-list.png -------------------------------------------------------------------------------- /docs/static/img/saml-auth-setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/saml-auth-setup.png -------------------------------------------------------------------------------- /docs/static/img/saml-group-mapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/saml-group-mapping.png -------------------------------------------------------------------------------- /docs/static/img/saml-group-sync-external-id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/saml-group-sync-external-id.png -------------------------------------------------------------------------------- /docs/static/img/saml-mapping-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/saml-mapping-configuration.png -------------------------------------------------------------------------------- /docs/static/img/scheduled-flag-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/scheduled-flag-create.png -------------------------------------------------------------------------------- /docs/static/img/scheduled-flag-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/scheduled-flag-list.png -------------------------------------------------------------------------------- /docs/static/img/square-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/square-icon.png -------------------------------------------------------------------------------- /docs/static/img/user-features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/docs/static/img/user-features.png -------------------------------------------------------------------------------- /docs/static/js/crisp-chat.js: -------------------------------------------------------------------------------- 1 | window.$crisp = []; 2 | window.CRISP_WEBSITE_ID = '8857f89e-0eb5-4263-ab49-a293872b6c19'; 3 | (function () { 4 | d = document; 5 | s = d.createElement('script'); 6 | s.src = 'https://client.crisp.chat/l.js'; 7 | s.async = 1; 8 | d.getElementsByTagName('head')[0].appendChild(s); 9 | })(); 10 | -------------------------------------------------------------------------------- /frontend/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .dockerignore 4 | .git 5 | docker-compose*.yml 6 | Dockerfile 7 | .tool-versions 8 | .env* -------------------------------------------------------------------------------- /frontend/.eslintignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .husky 3 | node_modules 4 | reports 5 | public 6 | tests_output 7 | web/static 8 | web/project/libs.js 9 | e2e 10 | webpack 11 | api 12 | -------------------------------------------------------------------------------- /frontend/.npmrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/.npmrc -------------------------------------------------------------------------------- /frontend/.nvmrc: -------------------------------------------------------------------------------- 1 | v18.16.0 2 | -------------------------------------------------------------------------------- /frontend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "bracketSpacing": true, 4 | "insertPragma": false, 5 | "jsxSingleQuote": true, 6 | "printWidth": 80, 7 | "proseWrap": "preserve", 8 | "quoteProps": "preserve", 9 | "requirePragma": false, 10 | "semi": false, 11 | "singleQuote": true, 12 | "tabWidth": 2, 13 | "trailingComma": "all", 14 | "useTabs": false, 15 | "vueIndentScriptAndStyle": false 16 | } 17 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # We've moved 2 | 3 | Front end deployment and development instructions have 4 | [moved to our Docs site](https://docs.flagsmith.com/deployment/locally-frontend) 5 | -------------------------------------------------------------------------------- /frontend/common/.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": [] 3 | } 4 | -------------------------------------------------------------------------------- /frontend/common/base/format-base.js: -------------------------------------------------------------------------------- 1 | export default {} 2 | -------------------------------------------------------------------------------- /frontend/common/code-help/create-user/create-user-curl.js: -------------------------------------------------------------------------------- 1 | import Constants from 'common/constants' 2 | 3 | module.exports = (envId, { USER_ID }, userId) => { 4 | const url = new URL('identities/', Constants.getFlagsmithSDKUrl()) 5 | url.searchParams.append('identifier', userId || USER_ID) 6 | 7 | return `// Identify/create user 8 | 9 | curl -i '${url}' \\ 10 | -H 'X-Environment-Key: ${envId}'` 11 | } 12 | -------------------------------------------------------------------------------- /frontend/common/code-help/create-user/create-user-go.js: -------------------------------------------------------------------------------- 1 | module.exports = ( 2 | envId, 3 | { FEATURE_NAME, FEATURE_NAME_ALT, USER_ID }, 4 | userId, 5 | ) => `// The method below triggers a network request 6 | flags, _ := client.GetIdentityFlags("${userId || USER_ID}", nil) 7 | 8 | isEnabled, _ := flags.IsFeatureEnabled("${FEATURE_NAME}") 9 | featureValue, _ := flags.GetFeatureValue("${FEATURE_NAME_ALT}") 10 | ` 11 | -------------------------------------------------------------------------------- /frontend/common/code-help/init/init-curl.js: -------------------------------------------------------------------------------- 1 | import Constants from 'common/constants' 2 | 3 | module.exports = (envId) => ` 4 | curl -i '${Constants.getFlagsmithSDKUrl()}flags/' \\ 5 | -H 'X-Environment-Key: ${envId}' 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-curl.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | () => `You can access the API directly with tools like curl or httpie, 3 | or with clients for languages that we do not currently have SDKs for. 4 | 5 | You can view the API via Swagger at https://api.flagsmith.com/api/v1/docs/. 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-dotnet.js: -------------------------------------------------------------------------------- 1 | import Utils from 'common/utils/utils' 2 | 3 | module.exports = () => `// Package Manager 4 | PM> Install-Package Flagsmith -Version 4.0.0 5 | 6 | // .NET CLI 7 | dotnet add package Flagsmith --version 4.0.0 8 | 9 | // PackageReference 10 | ${Utils.escapeHtml('')} 11 | 12 | // Paket CLI 13 | paket add Flagsmith --version 4.0.0 14 | ` 15 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-flutter.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | () => `The client library is available from the https://pub.dev/packages/flagsmith: 3 | 4 | dependencies: 5 | flagsmith: 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-go.js: -------------------------------------------------------------------------------- 1 | module.exports = () => `go get github.com/flagsmith/flagsmith-go-client 2 | 3 | import ( 4 | "github.com/flagsmith/flagsmith-go-client" 5 | ) 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-ios.js: -------------------------------------------------------------------------------- 1 | module.exports = () => `// cocoapods 2 | pod 'FlagsmithClient', '~> 1.0.1' 3 | ` 4 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-js.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ NPM_CLIENT }) => `// npm 2 | npm i ${NPM_CLIENT} --save 3 | 4 | // yarn 5 | yarn add ${NPM_CLIENT} 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-node.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ NPM_NODE_CLIENT }) => `// npm 2 | npm i ${NPM_NODE_CLIENT} --save 3 | 4 | // yarn 5 | yarn add ${NPM_NODE_CLIENT} 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-php.js: -------------------------------------------------------------------------------- 1 | module.exports = () => `composer require flagsmith/flagsmith-php-client 2 | ` 3 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-python.js: -------------------------------------------------------------------------------- 1 | module.exports = () => `pip install flagsmith 2 | ` 3 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-ruby.js: -------------------------------------------------------------------------------- 1 | module.exports = () => `gem install flagsmith 2 | ` 3 | -------------------------------------------------------------------------------- /frontend/common/code-help/install/install-rust.js: -------------------------------------------------------------------------------- 1 | module.exports = () => 2 | 'The package can be found at https://crates.io/crates/flagsmith;' 3 | -------------------------------------------------------------------------------- /frontend/common/code-help/offline_client/offline-client-cli.js: -------------------------------------------------------------------------------- 1 | module.exports = (envId) => ` 2 | npm i flagsmith-cli -g 3 | export FLAGSMITH_ENVIRONMENT=${envId} 4 | flagsmith get 5 | ` 6 | -------------------------------------------------------------------------------- /frontend/common/code-help/offline_client/offline-client-curl.js: -------------------------------------------------------------------------------- 1 | import Constants from 'common/constants' 2 | 3 | module.exports = (envId) => ` 4 | curl -i '${Constants.getFlagsmithSDKUrl()}flags/' \\ 5 | -H 'X-Environment-Key: ${envId}' | tee flagsmith.json 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/offline_server/offline-server-cli.js: -------------------------------------------------------------------------------- 1 | import _data from 'common/data/base/_data' 2 | module.exports = (serversideEnvironmentKey) => ` 3 | npm i flagsmith-cli -g 4 | export FLAGSMITH_ENVIRONMENT=${serversideEnvironmentKey} 5 | flagsmith get -e document 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/offline_server/offline-server-curl.js: -------------------------------------------------------------------------------- 1 | import Constants from 'common/constants' 2 | 3 | module.exports = (serversideEnvironmentKey) => ` 4 | curl -i '${Constants.getFlagsmithSDKUrl()}environment-document/' \\ 5 | -H 'X-Environment-Key: ${serversideEnvironmentKey}' | tee flagsmith.json 6 | ` 7 | -------------------------------------------------------------------------------- /frontend/common/code-help/traits/traits-dotnet.js: -------------------------------------------------------------------------------- 1 | module.exports = (envId, { TRAIT_NAME }, userId) => `using Flagsmith; 2 | 3 | FlagsmithClient _flagsmithClient; 4 | _flagsmithClient = new("${envId}"); 5 | 6 | var traitList = new List { new Trait(${TRAIT_NAME}, 42) }; 7 | 8 | # Identify a user, set their traits and retrieve the flags 9 | var flags = _flagsmithClient.GetIdentityFlags(${userId}, traitList).Result; 10 | ` 11 | -------------------------------------------------------------------------------- /frontend/common/code-help/traits/traits-go.js: -------------------------------------------------------------------------------- 1 | module.exports = ( 2 | envId, 3 | { TRAIT_NAME, USER_ID }, 4 | userId, 5 | ) => `trait := flagsmith.Trait{TraitKey: "${TRAIT_NAME}", TraitValue: "42"} 6 | traits = []*flagsmith.Trait{&trait} 7 | 8 | // Identify a user, set their traits and retrieve the flags 9 | flags, _ := client.GetIdentityFlags("${userId || USER_ID}", traits) 10 | ` 11 | -------------------------------------------------------------------------------- /frontend/common/code-help/traits/traits-ios.js: -------------------------------------------------------------------------------- 1 | module.exports = (envId, { TRAIT_NAME }, userId) => `do { 2 | let trait = Trait(key: "${TRAIT_NAME}", value: 42) 3 | try await flagsmith.setTrait(trait, forIdentity: "${userId}") 4 | } catch { 5 | print(error) 6 | } 7 | ` 8 | -------------------------------------------------------------------------------- /frontend/common/dispatcher/base/_action-constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by kyle-ssg on 10/02/15. 3 | */ 4 | module.exports = { 5 | 'LOGIN': 'LOGIN', 6 | 'LOGOUT': 'LOGOUT', 7 | 'REFRESH': 'REFRESH', 8 | 'REGISTER': 'REGISTER', 9 | 'REGISTER_NOTIFICATIONS': 'REGISTER_NOTIFICATIONS', 10 | 'RESET_PASSWORD': 'RESET_PASSWORD', 11 | 'SET_TOKEN': 'SET_TOKEN', 12 | 'SET_USER': 'SET_USER', 13 | } 14 | -------------------------------------------------------------------------------- /frontend/common/dispatcher/dispatcher.js: -------------------------------------------------------------------------------- 1 | const ReactDispatcher = require('flux-react-dispatcher') 2 | 3 | const Dispatcher = new ReactDispatcher() 4 | 5 | const theDispatcher = Object.assign(Dispatcher, { 6 | handleViewAction(action) { 7 | const payload = { 8 | action, 9 | source: 'VIEW_ACTION', 10 | } 11 | 12 | this.dispatch(payload) 13 | }, 14 | }) 15 | 16 | window.Dispatcher = Dispatcher 17 | module.exports = theDispatcher 18 | -------------------------------------------------------------------------------- /frontend/common/transformCorePaging.ts: -------------------------------------------------------------------------------- 1 | import { PagedRequest } from './types/requests' 2 | import { PagedResponse } from './types/responses' 3 | 4 | export default function (req: PagedRequest, res: PagedResponse) { 5 | return { 6 | ...res, 7 | currentPage: req.page || 1, 8 | pageSize: req.page_size, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /frontend/common/useViewMode.ts: -------------------------------------------------------------------------------- 1 | import flagsmith from 'flagsmith' 2 | 3 | export type ViewMode = 'compact' | 'default' 4 | export function getViewMode() { 5 | const viewMode = flagsmith.getTrait('view_mode') 6 | if (viewMode === 'compact') { 7 | return 'compact' as ViewMode 8 | } 9 | return 'default' as ViewMode 10 | } 11 | export function setViewMode(viewMode: ViewMode) { 12 | return flagsmith.setTrait('view_mode', viewMode) 13 | } 14 | -------------------------------------------------------------------------------- /frontend/common/utils/isFreeEmailDomain.ts: -------------------------------------------------------------------------------- 1 | import freeEmailDomains from 'free-email-domains' 2 | 3 | export default function (value: string | null | undefined) { 4 | if (!value) return false 5 | const domain = value?.split('@')?.[1] 6 | return freeEmailDomains.includes(domain) 7 | } 8 | -------------------------------------------------------------------------------- /frontend/e2e/.gitignore: -------------------------------------------------------------------------------- 1 | screenshot.png -------------------------------------------------------------------------------- /frontend/e2e/add-error-logs.js: -------------------------------------------------------------------------------- 1 | let onError = window.onError 2 | window.onerror = (message, source, lineno, colno, error) => { 3 | console.error(message + source + lineno + colno + error); 4 | } 5 | -------------------------------------------------------------------------------- /frontend/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": false, 4 | "noEmit": true, 5 | "noImplicitAny": false, 6 | "allowJs": true, 7 | "esModuleInterop": true, 8 | "baseUrl": ".", 9 | "lib": [ 10 | "dom" 11 | ], 12 | "skipLibCheck": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /frontend/env/project_selfhosted.js: -------------------------------------------------------------------------------- 1 | const globalThis = typeof window === 'undefined' ? global : window 2 | module.exports = global.Project = { 3 | env: 'selfhosted', 4 | 5 | // Self Hosted Defaults environment 6 | flagsmith: 'MXSepNNQEacBBzxAU7RagJ', 7 | flagsmithClientAPI: 'https://edge.api.flagsmith.com/api/v1/', 8 | 9 | // This is used for Sentry tracking 10 | maintenance: false, 11 | useSecureCookies: true, 12 | ...(globalThis.projectOverrides || {}), 13 | } 14 | -------------------------------------------------------------------------------- /frontend/environment.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/environment.js -------------------------------------------------------------------------------- /frontend/next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | useFileSystemPublicRoutes: false, 3 | }; 4 | -------------------------------------------------------------------------------- /frontend/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "functions": { 4 | "api/index.js": { 5 | "includeFiles": "CI_COMMIT_SHA" 6 | } 7 | }, 8 | "rewrites": [ 9 | { 10 | "source": "/(.*)", 11 | "destination": "/api" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /frontend/web/components/AppLoader.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default function AppLoader() { 4 | return ( 5 |
13 | 14 |
15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /frontend/web/components/BooleanDotIndicator.tsx: -------------------------------------------------------------------------------- 1 | const BooleanDotIndicator = ({ enabled }: { enabled: boolean }) => ( 2 |
11 | ) 12 | 13 | export default BooleanDotIndicator 14 | -------------------------------------------------------------------------------- /frontend/web/components/CondensedRow.tsx: -------------------------------------------------------------------------------- 1 | import { FC, PropsWithChildren } from 'react' // we need this to make JSX compile 2 | 3 | type CondensedColumnType = PropsWithChildren<{}> 4 | 5 | const CondensedRow: FC = ({ children }) => { 6 | return ( 7 |
8 |
{children}
9 |
10 | ) 11 | } 12 | 13 | export default CondensedRow 14 | -------------------------------------------------------------------------------- /frontend/web/components/base/forms/TabItem.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from 'react' // we need this to make JSX compile 2 | 3 | type TabItemType = { 4 | tabLabelString?: string 5 | tabLabel: ReactNode 6 | children: ReactNode 7 | className?: string 8 | } 9 | 10 | const TabItem: FC = ({ children }) => { 11 | return children || (null as any) 12 | } 13 | 14 | export default TabItem 15 | -------------------------------------------------------------------------------- /frontend/web/components/modals/ModalHR.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react' // we need this to make JSX compile 2 | 3 | type ModalHRType = { 4 | className?: string 5 | } 6 | 7 | const ModalHR: FC = ({ className }) => { 8 | return
9 | } 10 | 11 | export default ModalHR 12 | -------------------------------------------------------------------------------- /frontend/web/components/pages/HomePage.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/components/pages/HomePage.js -------------------------------------------------------------------------------- /frontend/web/components/pages/NotFoundPage.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react' 2 | 3 | type NotFoundPageType = {} 4 | 5 | const NotFoundPage: FC = ({}) => { 6 | return ( 7 |
8 |

Oops, we can't seem to find this page!

9 |

Please check the URL you are trying to visit and try again.

10 |
11 | ) 12 | } 13 | 14 | export default NotFoundPage 15 | -------------------------------------------------------------------------------- /frontend/web/project/setDarkMode.ts: -------------------------------------------------------------------------------- 1 | export const setDarkMode = (enabled: boolean) => { 2 | if (enabled) { 3 | document.body.classList.add('dark') 4 | document.documentElement.setAttribute('data-bs-theme', 'dark') 5 | } else { 6 | document.body.classList.remove('dark') 7 | document.documentElement.removeAttribute('data-bs-theme') 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /frontend/web/static/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/.gitignore -------------------------------------------------------------------------------- /frontend/web/static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Bold.woff -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Bold.woff2 -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Light.ttf -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Light.woff -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Light.woff2 -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Regular.woff -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-Regular.woff2 -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-SemiBold.ttf -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-SemiBold.woff -------------------------------------------------------------------------------- /frontend/web/static/fonts/OpenSans-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/OpenSans-SemiBold.woff2 -------------------------------------------------------------------------------- /frontend/web/static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /frontend/web/static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /frontend/web/static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /frontend/web/static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /frontend/web/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/images/favicon.ico -------------------------------------------------------------------------------- /frontend/web/static/images/nav-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/frontend/web/static/images/nav-logo.png -------------------------------------------------------------------------------- /frontend/web/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /frontend/web/styles/3rdParty/_hw-badge.scss: -------------------------------------------------------------------------------- 1 | #headway { 2 | .HW_badge_cont { 3 | width: auto; 4 | height: 40px; 5 | .HW_badge { 6 | height: 12px; 7 | width: 12px; 8 | top: 8px; 9 | right: 8px; 10 | left: auto; 11 | background: $danger; 12 | line-height: 12px; 13 | font-size: 9px; 14 | font-weight: 500; 15 | &.HW_softHidden { 16 | background: $bg-light500; 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /frontend/web/styles/3rdParty/_index.scss: -------------------------------------------------------------------------------- 1 | @import "react-select"; 2 | @import "bootstrap"; 3 | @import "hljs"; 4 | @import "react-datepicker"; 5 | @import "hw-badge"; 6 | @import "react-diff"; 7 | -------------------------------------------------------------------------------- /frontend/web/styles/components/_aside.scss: -------------------------------------------------------------------------------- 1 | .home-aside { 2 | bottom: 0; 3 | height: 100vh; 4 | max-height: 100vh; 5 | position: sticky; 6 | top: 0; 7 | width: 280px; 8 | } 9 | -------------------------------------------------------------------------------- /frontend/web/styles/components/_droparea.scss: -------------------------------------------------------------------------------- 1 | .droparea { 2 | padding: 56px; 3 | border: 1px dashed $basic-alpha-16; 4 | border-radius: $border-radius-xlg; 5 | &--condensed { 6 | padding: 8px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /frontend/web/styles/components/_feature-change.scss: -------------------------------------------------------------------------------- 1 | .faded { 2 | opacity: 0.15; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/web/styles/components/_index.scss: -------------------------------------------------------------------------------- 1 | @import 'list-item'; 2 | @import 'paging'; 3 | @import 'switch'; 4 | @import 'aside'; 5 | @import 'input'; 6 | @import 'tabs'; 7 | @import 'panel'; 8 | @import 'chip'; 9 | @import 'feature-change'; 10 | @import 'toast'; 11 | @import 'color-block'; 12 | @import 'droparea'; 13 | -------------------------------------------------------------------------------- /frontend/web/styles/mixins/box-shadow-mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow() { 2 | box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2), 0 13px 19px 2px rgba(0, 0, 0, 0.14), 0 5px 24px 4px rgba(0, 0, 0, 0.12); 3 | } -------------------------------------------------------------------------------- /frontend/web/styles/project/_base.scss: -------------------------------------------------------------------------------- 1 | body { 2 | line-height: inherit !important; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/web/styles/project/_icons.scss: -------------------------------------------------------------------------------- 1 | .icon { 2 | &--green { 3 | color: $header-color; 4 | } 5 | &--tooltip { 6 | font-size: $font-size-base; 7 | } 8 | &--new-tooltip { 9 | font-size: 19px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /frontend/web/styles/project/_index.scss: -------------------------------------------------------------------------------- 1 | @import "utils"; 2 | @import "type"; 3 | @import "lists"; 4 | @import "forms"; 5 | @import "buttons"; 6 | @import "tags"; 7 | @import "modals"; 8 | @import "project-nav"; 9 | @import "panel"; 10 | @import "FeaturesPage"; 11 | @import "PricingPage"; 12 | @import "alert"; 13 | @import "icons"; 14 | @import "layout"; 15 | @import "spacing-utils"; 16 | @import "tooltips"; 17 | @import "base"; 18 | @import "overlay"; 19 | -------------------------------------------------------------------------------- /frontend/web/styles/project/_overlay.scss: -------------------------------------------------------------------------------- 1 | .overlay { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | height: 100%; 7 | background-color: rgba(0, 0, 0, 0.544); 8 | z-index: 9999; 9 | display: flex; 10 | justify-content: center; 11 | align-items: center; 12 | .title{ 13 | color: #fff 14 | } 15 | } -------------------------------------------------------------------------------- /frontend/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | // This is the base webpack configuration used by files in /webpack 4 | module.exports = { 5 | externals: {}, 6 | resolve: { 7 | alias: { 8 | 'common': path.resolve(__dirname, '../common'), 9 | 'components': path.resolve(__dirname, '../web/components'), 10 | 'project': path.resolve(__dirname, '../web/project'), 11 | }, 12 | extensions: ['.tsx', '.ts', '.js'], 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /frontend/webpack/pages.js: -------------------------------------------------------------------------------- 1 | // 2 | module.exports = ['index']; 3 | -------------------------------------------------------------------------------- /frontend/webpack/webpack.config.analyse.js: -------------------------------------------------------------------------------- 1 | // webpack.config.analyse.js 2 | // Breaks down the bundle size of our production config using webpack-bundle-analyzer 3 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 4 | const baseConfig = require('./webpack.config.prod'); 5 | 6 | module.exports = { 7 | ...baseConfig, 8 | plugins: baseConfig.plugins.concat([new BundleAnalyzerPlugin()]), 9 | }; 10 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flagsmith", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /static-files/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/static-files/hero.png -------------------------------------------------------------------------------- /static-files/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flagsmith/flagsmith/604e5e1762a807c0417ffac38f987e6d38f5193a/static-files/screenshot.png -------------------------------------------------------------------------------- /trivy.yaml: -------------------------------------------------------------------------------- 1 | format: json 2 | exit-code: 0 3 | severity: CRITICAL,HIGH 4 | vuln-type: os,library 5 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 2.179.0 2 | --------------------------------------------------------------------------------