diff --git a/posthog/api/team.py b/posthog/api/team.py index c8ca32abe5ce0..d2b9ca018dbdf 100644 --- a/posthog/api/team.py +++ b/posthog/api/team.py @@ -115,6 +115,7 @@ class Meta: model = Team fields = [ "id", + "project_id", "uuid", "name", "api_token", @@ -141,6 +142,7 @@ class Meta: "heatmaps_opt_in", "capture_dead_clicks", ] + read_only_fields = fields class TeamSerializer(serializers.ModelSerializer, UserPermissionsSerializerMixin, UserAccessControlSerializerMixin): diff --git a/posthog/api/test/__snapshots__/test_early_access_feature.ambr b/posthog/api/test/__snapshots__/test_early_access_feature.ambr index d14002302aa24..652fd9e16d409 100644 --- a/posthog/api/test/__snapshots__/test_early_access_feature.ambr +++ b/posthog/api/test/__snapshots__/test_early_access_feature.ambr @@ -808,3 +808,946 @@ AND "posthog_featureflag"."team_id" = 99999) ''' # --- +# name: TestPreviewList.test_early_access_features_with_cached_team + ''' + SELECT "posthog_team"."id", + "posthog_team"."uuid", + "posthog_team"."organization_id", + "posthog_team"."project_id", + "posthog_team"."api_token", + "posthog_team"."app_urls", + "posthog_team"."name", + "posthog_team"."slack_incoming_webhook", + "posthog_team"."created_at", + "posthog_team"."updated_at", + "posthog_team"."anonymize_ips", + "posthog_team"."completed_snippet_onboarding", + "posthog_team"."has_completed_onboarding_for", + "posthog_team"."ingested_event", + "posthog_team"."autocapture_opt_out", + "posthog_team"."autocapture_web_vitals_opt_in", + "posthog_team"."autocapture_web_vitals_allowed_metrics", + "posthog_team"."autocapture_exceptions_opt_in", + "posthog_team"."autocapture_exceptions_errors_to_ignore", + "posthog_team"."person_processing_opt_out", + "posthog_team"."session_recording_opt_in", + "posthog_team"."session_recording_sample_rate", + "posthog_team"."session_recording_minimum_duration_milliseconds", + "posthog_team"."session_recording_linked_flag", + "posthog_team"."session_recording_network_payload_capture_config", + "posthog_team"."session_recording_url_trigger_config", + "posthog_team"."session_recording_url_blocklist_config", + "posthog_team"."session_recording_event_trigger_config", + "posthog_team"."session_replay_config", + "posthog_team"."survey_config", + "posthog_team"."capture_console_log_opt_in", + "posthog_team"."capture_performance_opt_in", + "posthog_team"."capture_dead_clicks", + "posthog_team"."surveys_opt_in", + "posthog_team"."heatmaps_opt_in", + "posthog_team"."session_recording_version", + "posthog_team"."signup_token", + "posthog_team"."is_demo", + "posthog_team"."access_control", + "posthog_team"."week_start_day", + "posthog_team"."inject_web_apps", + "posthog_team"."test_account_filters", + "posthog_team"."test_account_filters_default_checked", + "posthog_team"."path_cleaning_filters", + "posthog_team"."timezone", + "posthog_team"."data_attributes", + "posthog_team"."person_display_name_properties", + "posthog_team"."live_events_columns", + "posthog_team"."recording_domains", + "posthog_team"."primary_dashboard_id", + "posthog_team"."extra_settings", + "posthog_team"."modifiers", + "posthog_team"."correlation_config", + "posthog_team"."session_recording_retention_period_days", + "posthog_team"."plugins_opt_in", + "posthog_team"."opt_out_capture", + "posthog_team"."event_names", + "posthog_team"."event_names_with_usage", + "posthog_team"."event_properties", + "posthog_team"."event_properties_with_usage", + "posthog_team"."event_properties_numerical", + "posthog_team"."external_data_workspace_id", + "posthog_team"."external_data_workspace_last_synced_at" + FROM "posthog_team" + WHERE "posthog_team"."id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.1 + ''' + SELECT "posthog_team"."id", + "posthog_team"."uuid", + "posthog_team"."organization_id", + "posthog_team"."project_id", + "posthog_team"."api_token", + "posthog_team"."app_urls", + "posthog_team"."name", + "posthog_team"."slack_incoming_webhook", + "posthog_team"."created_at", + "posthog_team"."updated_at", + "posthog_team"."anonymize_ips", + "posthog_team"."completed_snippet_onboarding", + "posthog_team"."has_completed_onboarding_for", + "posthog_team"."ingested_event", + "posthog_team"."autocapture_opt_out", + "posthog_team"."autocapture_web_vitals_opt_in", + "posthog_team"."autocapture_web_vitals_allowed_metrics", + "posthog_team"."autocapture_exceptions_opt_in", + "posthog_team"."autocapture_exceptions_errors_to_ignore", + "posthog_team"."person_processing_opt_out", + "posthog_team"."session_recording_opt_in", + "posthog_team"."session_recording_sample_rate", + "posthog_team"."session_recording_minimum_duration_milliseconds", + "posthog_team"."session_recording_linked_flag", + "posthog_team"."session_recording_network_payload_capture_config", + "posthog_team"."session_recording_url_trigger_config", + "posthog_team"."session_recording_url_blocklist_config", + "posthog_team"."session_recording_event_trigger_config", + "posthog_team"."session_replay_config", + "posthog_team"."survey_config", + "posthog_team"."capture_console_log_opt_in", + "posthog_team"."capture_performance_opt_in", + "posthog_team"."capture_dead_clicks", + "posthog_team"."surveys_opt_in", + "posthog_team"."heatmaps_opt_in", + "posthog_team"."session_recording_version", + "posthog_team"."signup_token", + "posthog_team"."is_demo", + "posthog_team"."access_control", + "posthog_team"."week_start_day", + "posthog_team"."inject_web_apps", + "posthog_team"."test_account_filters", + "posthog_team"."test_account_filters_default_checked", + "posthog_team"."path_cleaning_filters", + "posthog_team"."timezone", + "posthog_team"."data_attributes", + "posthog_team"."person_display_name_properties", + "posthog_team"."live_events_columns", + "posthog_team"."recording_domains", + "posthog_team"."primary_dashboard_id", + "posthog_team"."extra_settings", + "posthog_team"."modifiers", + "posthog_team"."correlation_config", + "posthog_team"."session_recording_retention_period_days", + "posthog_team"."external_data_workspace_id", + "posthog_team"."external_data_workspace_last_synced_at" + FROM "posthog_team" + WHERE "posthog_team"."api_token" = 'token123' + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.10 + ''' + SELECT "posthog_user"."id", + "posthog_user"."password", + "posthog_user"."last_login", + "posthog_user"."first_name", + "posthog_user"."last_name", + "posthog_user"."is_staff", + "posthog_user"."date_joined", + "posthog_user"."uuid", + "posthog_user"."current_organization_id", + "posthog_user"."current_team_id", + "posthog_user"."email", + "posthog_user"."pending_email", + "posthog_user"."temporary_token", + "posthog_user"."distinct_id", + "posthog_user"."is_email_verified", + "posthog_user"."has_seen_product_intro_for", + "posthog_user"."strapi_id", + "posthog_user"."is_active", + "posthog_user"."theme_mode", + "posthog_user"."partial_notification_settings", + "posthog_user"."anonymize_data", + "posthog_user"."toolbar_mode", + "posthog_user"."hedgehog_config", + "posthog_user"."events_column_config", + "posthog_user"."email_opt_in" + FROM "posthog_user" + WHERE "posthog_user"."id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.11 + ''' + SELECT "posthog_earlyaccessfeature"."id", + "posthog_earlyaccessfeature"."team_id", + "posthog_earlyaccessfeature"."feature_flag_id", + "posthog_earlyaccessfeature"."name", + "posthog_earlyaccessfeature"."description", + "posthog_earlyaccessfeature"."stage", + "posthog_earlyaccessfeature"."documentation_url", + "posthog_earlyaccessfeature"."created_at", + "posthog_featureflag"."id", + "posthog_featureflag"."key", + "posthog_featureflag"."name", + "posthog_featureflag"."filters", + "posthog_featureflag"."rollout_percentage", + "posthog_featureflag"."team_id", + "posthog_featureflag"."created_by_id", + "posthog_featureflag"."created_at", + "posthog_featureflag"."deleted", + "posthog_featureflag"."active", + "posthog_featureflag"."rollback_conditions", + "posthog_featureflag"."performed_rollback", + "posthog_featureflag"."ensure_experience_continuity", + "posthog_featureflag"."usage_dashboard_id", + "posthog_featureflag"."has_enriched_analytics" + FROM "posthog_earlyaccessfeature" + INNER JOIN "posthog_team" ON ("posthog_earlyaccessfeature"."team_id" = "posthog_team"."id") + LEFT OUTER JOIN "posthog_featureflag" ON ("posthog_earlyaccessfeature"."feature_flag_id" = "posthog_featureflag"."id") + WHERE ("posthog_earlyaccessfeature"."stage" = 'beta' + AND "posthog_team"."project_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.2 + ''' + SELECT "posthog_featureflag"."id", + "posthog_featureflag"."key", + "posthog_featureflag"."name", + "posthog_featureflag"."filters", + "posthog_featureflag"."rollout_percentage", + "posthog_featureflag"."team_id", + "posthog_featureflag"."created_by_id", + "posthog_featureflag"."created_at", + "posthog_featureflag"."deleted", + "posthog_featureflag"."active", + "posthog_featureflag"."rollback_conditions", + "posthog_featureflag"."performed_rollback", + "posthog_featureflag"."ensure_experience_continuity", + "posthog_featureflag"."usage_dashboard_id", + "posthog_featureflag"."has_enriched_analytics" + FROM "posthog_featureflag" + WHERE ("posthog_featureflag"."active" + AND NOT "posthog_featureflag"."deleted" + AND "posthog_featureflag"."team_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.3 + ''' + SELECT "posthog_team"."id", + "posthog_team"."uuid", + "posthog_team"."organization_id", + "posthog_team"."project_id", + "posthog_team"."api_token", + "posthog_team"."app_urls", + "posthog_team"."name", + "posthog_team"."slack_incoming_webhook", + "posthog_team"."created_at", + "posthog_team"."updated_at", + "posthog_team"."anonymize_ips", + "posthog_team"."completed_snippet_onboarding", + "posthog_team"."has_completed_onboarding_for", + "posthog_team"."ingested_event", + "posthog_team"."autocapture_opt_out", + "posthog_team"."autocapture_web_vitals_opt_in", + "posthog_team"."autocapture_web_vitals_allowed_metrics", + "posthog_team"."autocapture_exceptions_opt_in", + "posthog_team"."autocapture_exceptions_errors_to_ignore", + "posthog_team"."person_processing_opt_out", + "posthog_team"."session_recording_opt_in", + "posthog_team"."session_recording_sample_rate", + "posthog_team"."session_recording_minimum_duration_milliseconds", + "posthog_team"."session_recording_linked_flag", + "posthog_team"."session_recording_network_payload_capture_config", + "posthog_team"."session_recording_url_trigger_config", + "posthog_team"."session_recording_url_blocklist_config", + "posthog_team"."session_recording_event_trigger_config", + "posthog_team"."session_replay_config", + "posthog_team"."survey_config", + "posthog_team"."capture_console_log_opt_in", + "posthog_team"."capture_performance_opt_in", + "posthog_team"."capture_dead_clicks", + "posthog_team"."surveys_opt_in", + "posthog_team"."heatmaps_opt_in", + "posthog_team"."session_recording_version", + "posthog_team"."signup_token", + "posthog_team"."is_demo", + "posthog_team"."access_control", + "posthog_team"."week_start_day", + "posthog_team"."inject_web_apps", + "posthog_team"."test_account_filters", + "posthog_team"."test_account_filters_default_checked", + "posthog_team"."path_cleaning_filters", + "posthog_team"."timezone", + "posthog_team"."data_attributes", + "posthog_team"."person_display_name_properties", + "posthog_team"."live_events_columns", + "posthog_team"."recording_domains", + "posthog_team"."primary_dashboard_id", + "posthog_team"."extra_settings", + "posthog_team"."modifiers", + "posthog_team"."correlation_config", + "posthog_team"."session_recording_retention_period_days", + "posthog_team"."external_data_workspace_id", + "posthog_team"."external_data_workspace_last_synced_at" + FROM "posthog_team" + WHERE "posthog_team"."id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.4 + ''' + SELECT "posthog_remoteconfig"."id", + "posthog_remoteconfig"."team_id", + "posthog_remoteconfig"."config", + "posthog_remoteconfig"."updated_at", + "posthog_remoteconfig"."synced_at" + FROM "posthog_remoteconfig" + WHERE "posthog_remoteconfig"."team_id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.5 + ''' + SELECT "posthog_team"."id", + "posthog_team"."uuid", + "posthog_team"."organization_id", + "posthog_team"."project_id", + "posthog_team"."api_token", + "posthog_team"."app_urls", + "posthog_team"."name", + "posthog_team"."slack_incoming_webhook", + "posthog_team"."created_at", + "posthog_team"."updated_at", + "posthog_team"."anonymize_ips", + "posthog_team"."completed_snippet_onboarding", + "posthog_team"."has_completed_onboarding_for", + "posthog_team"."ingested_event", + "posthog_team"."autocapture_opt_out", + "posthog_team"."autocapture_web_vitals_opt_in", + "posthog_team"."autocapture_web_vitals_allowed_metrics", + "posthog_team"."autocapture_exceptions_opt_in", + "posthog_team"."autocapture_exceptions_errors_to_ignore", + "posthog_team"."person_processing_opt_out", + "posthog_team"."session_recording_opt_in", + "posthog_team"."session_recording_sample_rate", + "posthog_team"."session_recording_minimum_duration_milliseconds", + "posthog_team"."session_recording_linked_flag", + "posthog_team"."session_recording_network_payload_capture_config", + "posthog_team"."session_recording_url_trigger_config", + "posthog_team"."session_recording_url_blocklist_config", + "posthog_team"."session_recording_event_trigger_config", + "posthog_team"."session_replay_config", + "posthog_team"."survey_config", + "posthog_team"."capture_console_log_opt_in", + "posthog_team"."capture_performance_opt_in", + "posthog_team"."capture_dead_clicks", + "posthog_team"."surveys_opt_in", + "posthog_team"."heatmaps_opt_in", + "posthog_team"."session_recording_version", + "posthog_team"."signup_token", + "posthog_team"."is_demo", + "posthog_team"."access_control", + "posthog_team"."week_start_day", + "posthog_team"."inject_web_apps", + "posthog_team"."test_account_filters", + "posthog_team"."test_account_filters_default_checked", + "posthog_team"."path_cleaning_filters", + "posthog_team"."timezone", + "posthog_team"."data_attributes", + "posthog_team"."person_display_name_properties", + "posthog_team"."live_events_columns", + "posthog_team"."recording_domains", + "posthog_team"."primary_dashboard_id", + "posthog_team"."extra_settings", + "posthog_team"."modifiers", + "posthog_team"."correlation_config", + "posthog_team"."session_recording_retention_period_days", + "posthog_team"."plugins_opt_in", + "posthog_team"."opt_out_capture", + "posthog_team"."event_names", + "posthog_team"."event_names_with_usage", + "posthog_team"."event_properties", + "posthog_team"."event_properties_with_usage", + "posthog_team"."event_properties_numerical", + "posthog_team"."external_data_workspace_id", + "posthog_team"."external_data_workspace_last_synced_at" + FROM "posthog_team" + WHERE "posthog_team"."id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.6 + ''' + SELECT COUNT(*) AS "__count" + FROM "posthog_featureflag" + WHERE ("posthog_featureflag"."active" + AND NOT "posthog_featureflag"."deleted" + AND "posthog_featureflag"."team_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.7 + ''' + SELECT "posthog_survey"."id", + "posthog_survey"."team_id", + "posthog_survey"."name", + "posthog_survey"."description", + "posthog_survey"."linked_flag_id", + "posthog_survey"."targeting_flag_id", + "posthog_survey"."internal_targeting_flag_id", + "posthog_survey"."internal_response_sampling_flag_id", + "posthog_survey"."type", + "posthog_survey"."conditions", + "posthog_survey"."questions", + "posthog_survey"."appearance", + "posthog_survey"."created_at", + "posthog_survey"."created_by_id", + "posthog_survey"."start_date", + "posthog_survey"."end_date", + "posthog_survey"."updated_at", + "posthog_survey"."archived", + "posthog_survey"."responses_limit", + "posthog_survey"."response_sampling_start_date", + "posthog_survey"."response_sampling_interval_type", + "posthog_survey"."response_sampling_interval", + "posthog_survey"."response_sampling_limit", + "posthog_survey"."response_sampling_daily_limits", + "posthog_survey"."iteration_count", + "posthog_survey"."iteration_frequency_days", + "posthog_survey"."iteration_start_dates", + "posthog_survey"."current_iteration", + "posthog_survey"."current_iteration_start_date", + "posthog_featureflag"."id", + "posthog_featureflag"."key", + "posthog_featureflag"."name", + "posthog_featureflag"."filters", + "posthog_featureflag"."rollout_percentage", + "posthog_featureflag"."team_id", + "posthog_featureflag"."created_by_id", + "posthog_featureflag"."created_at", + "posthog_featureflag"."deleted", + "posthog_featureflag"."active", + "posthog_featureflag"."rollback_conditions", + "posthog_featureflag"."performed_rollback", + "posthog_featureflag"."ensure_experience_continuity", + "posthog_featureflag"."usage_dashboard_id", + "posthog_featureflag"."has_enriched_analytics", + T4."id", + T4."key", + T4."name", + T4."filters", + T4."rollout_percentage", + T4."team_id", + T4."created_by_id", + T4."created_at", + T4."deleted", + T4."active", + T4."rollback_conditions", + T4."performed_rollback", + T4."ensure_experience_continuity", + T4."usage_dashboard_id", + T4."has_enriched_analytics", + T5."id", + T5."key", + T5."name", + T5."filters", + T5."rollout_percentage", + T5."team_id", + T5."created_by_id", + T5."created_at", + T5."deleted", + T5."active", + T5."rollback_conditions", + T5."performed_rollback", + T5."ensure_experience_continuity", + T5."usage_dashboard_id", + T5."has_enriched_analytics" + FROM "posthog_survey" + LEFT OUTER JOIN "posthog_featureflag" ON ("posthog_survey"."linked_flag_id" = "posthog_featureflag"."id") + LEFT OUTER JOIN "posthog_featureflag" T4 ON ("posthog_survey"."targeting_flag_id" = T4."id") + LEFT OUTER JOIN "posthog_featureflag" T5 ON ("posthog_survey"."internal_targeting_flag_id" = T5."id") + WHERE ("posthog_survey"."team_id" = 99999 + AND NOT ("posthog_survey"."archived")) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.8 + ''' + SELECT "posthog_pluginconfig"."id", + "posthog_pluginsourcefile"."transpiled", + "posthog_pluginconfig"."web_token", + "posthog_plugin"."config_schema", + "posthog_pluginconfig"."config" + FROM "posthog_pluginconfig" + INNER JOIN "posthog_plugin" ON ("posthog_pluginconfig"."plugin_id" = "posthog_plugin"."id") + INNER JOIN "posthog_pluginsourcefile" ON ("posthog_plugin"."id" = "posthog_pluginsourcefile"."plugin_id") + WHERE ("posthog_pluginconfig"."enabled" + AND "posthog_pluginsourcefile"."filename" = 'site.ts' + AND "posthog_pluginsourcefile"."status" = 'TRANSPILED' + AND "posthog_pluginconfig"."team_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_cached_team.9 + ''' + SELECT "posthog_hogfunction"."id", + "posthog_hogfunction"."team_id", + "posthog_hogfunction"."name", + "posthog_hogfunction"."description", + "posthog_hogfunction"."created_at", + "posthog_hogfunction"."created_by_id", + "posthog_hogfunction"."deleted", + "posthog_hogfunction"."updated_at", + "posthog_hogfunction"."enabled", + "posthog_hogfunction"."type", + "posthog_hogfunction"."icon_url", + "posthog_hogfunction"."hog", + "posthog_hogfunction"."bytecode", + "posthog_hogfunction"."transpiled", + "posthog_hogfunction"."inputs_schema", + "posthog_hogfunction"."inputs", + "posthog_hogfunction"."encrypted_inputs", + "posthog_hogfunction"."filters", + "posthog_hogfunction"."masking", + "posthog_hogfunction"."template_id" + FROM "posthog_hogfunction" + WHERE ("posthog_hogfunction"."enabled" + AND "posthog_hogfunction"."team_id" = 99999 + AND "posthog_hogfunction"."type" IN ('site_destination', + 'site_app')) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team + ''' + SELECT "posthog_team"."id", + "posthog_team"."uuid", + "posthog_team"."organization_id", + "posthog_team"."project_id", + "posthog_team"."api_token", + "posthog_team"."app_urls", + "posthog_team"."name", + "posthog_team"."slack_incoming_webhook", + "posthog_team"."created_at", + "posthog_team"."updated_at", + "posthog_team"."anonymize_ips", + "posthog_team"."completed_snippet_onboarding", + "posthog_team"."has_completed_onboarding_for", + "posthog_team"."ingested_event", + "posthog_team"."autocapture_opt_out", + "posthog_team"."autocapture_web_vitals_opt_in", + "posthog_team"."autocapture_web_vitals_allowed_metrics", + "posthog_team"."autocapture_exceptions_opt_in", + "posthog_team"."autocapture_exceptions_errors_to_ignore", + "posthog_team"."person_processing_opt_out", + "posthog_team"."session_recording_opt_in", + "posthog_team"."session_recording_sample_rate", + "posthog_team"."session_recording_minimum_duration_milliseconds", + "posthog_team"."session_recording_linked_flag", + "posthog_team"."session_recording_network_payload_capture_config", + "posthog_team"."session_recording_url_trigger_config", + "posthog_team"."session_recording_url_blocklist_config", + "posthog_team"."session_recording_event_trigger_config", + "posthog_team"."session_replay_config", + "posthog_team"."survey_config", + "posthog_team"."capture_console_log_opt_in", + "posthog_team"."capture_performance_opt_in", + "posthog_team"."capture_dead_clicks", + "posthog_team"."surveys_opt_in", + "posthog_team"."heatmaps_opt_in", + "posthog_team"."session_recording_version", + "posthog_team"."signup_token", + "posthog_team"."is_demo", + "posthog_team"."access_control", + "posthog_team"."week_start_day", + "posthog_team"."inject_web_apps", + "posthog_team"."test_account_filters", + "posthog_team"."test_account_filters_default_checked", + "posthog_team"."path_cleaning_filters", + "posthog_team"."timezone", + "posthog_team"."data_attributes", + "posthog_team"."person_display_name_properties", + "posthog_team"."live_events_columns", + "posthog_team"."recording_domains", + "posthog_team"."primary_dashboard_id", + "posthog_team"."extra_settings", + "posthog_team"."modifiers", + "posthog_team"."correlation_config", + "posthog_team"."session_recording_retention_period_days", + "posthog_team"."plugins_opt_in", + "posthog_team"."opt_out_capture", + "posthog_team"."event_names", + "posthog_team"."event_names_with_usage", + "posthog_team"."event_properties", + "posthog_team"."event_properties_with_usage", + "posthog_team"."event_properties_numerical", + "posthog_team"."external_data_workspace_id", + "posthog_team"."external_data_workspace_last_synced_at" + FROM "posthog_team" + WHERE "posthog_team"."id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.1 + ''' + SELECT "posthog_featureflag"."id", + "posthog_featureflag"."key", + "posthog_featureflag"."name", + "posthog_featureflag"."filters", + "posthog_featureflag"."rollout_percentage", + "posthog_featureflag"."team_id", + "posthog_featureflag"."created_by_id", + "posthog_featureflag"."created_at", + "posthog_featureflag"."deleted", + "posthog_featureflag"."active", + "posthog_featureflag"."rollback_conditions", + "posthog_featureflag"."performed_rollback", + "posthog_featureflag"."ensure_experience_continuity", + "posthog_featureflag"."usage_dashboard_id", + "posthog_featureflag"."has_enriched_analytics" + FROM "posthog_featureflag" + WHERE ("posthog_featureflag"."active" + AND NOT "posthog_featureflag"."deleted" + AND "posthog_featureflag"."team_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.10 + ''' + SELECT "posthog_earlyaccessfeature"."id", + "posthog_earlyaccessfeature"."team_id", + "posthog_earlyaccessfeature"."feature_flag_id", + "posthog_earlyaccessfeature"."name", + "posthog_earlyaccessfeature"."description", + "posthog_earlyaccessfeature"."stage", + "posthog_earlyaccessfeature"."documentation_url", + "posthog_earlyaccessfeature"."created_at", + "posthog_featureflag"."id", + "posthog_featureflag"."key", + "posthog_featureflag"."name", + "posthog_featureflag"."filters", + "posthog_featureflag"."rollout_percentage", + "posthog_featureflag"."team_id", + "posthog_featureflag"."created_by_id", + "posthog_featureflag"."created_at", + "posthog_featureflag"."deleted", + "posthog_featureflag"."active", + "posthog_featureflag"."rollback_conditions", + "posthog_featureflag"."performed_rollback", + "posthog_featureflag"."ensure_experience_continuity", + "posthog_featureflag"."usage_dashboard_id", + "posthog_featureflag"."has_enriched_analytics" + FROM "posthog_earlyaccessfeature" + INNER JOIN "posthog_team" ON ("posthog_earlyaccessfeature"."team_id" = "posthog_team"."id") + LEFT OUTER JOIN "posthog_featureflag" ON ("posthog_earlyaccessfeature"."feature_flag_id" = "posthog_featureflag"."id") + WHERE ("posthog_earlyaccessfeature"."stage" = 'beta' + AND "posthog_team"."project_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.2 + ''' + SELECT "posthog_team"."id", + "posthog_team"."uuid", + "posthog_team"."organization_id", + "posthog_team"."project_id", + "posthog_team"."api_token", + "posthog_team"."app_urls", + "posthog_team"."name", + "posthog_team"."slack_incoming_webhook", + "posthog_team"."created_at", + "posthog_team"."updated_at", + "posthog_team"."anonymize_ips", + "posthog_team"."completed_snippet_onboarding", + "posthog_team"."has_completed_onboarding_for", + "posthog_team"."ingested_event", + "posthog_team"."autocapture_opt_out", + "posthog_team"."autocapture_web_vitals_opt_in", + "posthog_team"."autocapture_web_vitals_allowed_metrics", + "posthog_team"."autocapture_exceptions_opt_in", + "posthog_team"."autocapture_exceptions_errors_to_ignore", + "posthog_team"."person_processing_opt_out", + "posthog_team"."session_recording_opt_in", + "posthog_team"."session_recording_sample_rate", + "posthog_team"."session_recording_minimum_duration_milliseconds", + "posthog_team"."session_recording_linked_flag", + "posthog_team"."session_recording_network_payload_capture_config", + "posthog_team"."session_recording_url_trigger_config", + "posthog_team"."session_recording_url_blocklist_config", + "posthog_team"."session_recording_event_trigger_config", + "posthog_team"."session_replay_config", + "posthog_team"."survey_config", + "posthog_team"."capture_console_log_opt_in", + "posthog_team"."capture_performance_opt_in", + "posthog_team"."capture_dead_clicks", + "posthog_team"."surveys_opt_in", + "posthog_team"."heatmaps_opt_in", + "posthog_team"."session_recording_version", + "posthog_team"."signup_token", + "posthog_team"."is_demo", + "posthog_team"."access_control", + "posthog_team"."week_start_day", + "posthog_team"."inject_web_apps", + "posthog_team"."test_account_filters", + "posthog_team"."test_account_filters_default_checked", + "posthog_team"."path_cleaning_filters", + "posthog_team"."timezone", + "posthog_team"."data_attributes", + "posthog_team"."person_display_name_properties", + "posthog_team"."live_events_columns", + "posthog_team"."recording_domains", + "posthog_team"."primary_dashboard_id", + "posthog_team"."extra_settings", + "posthog_team"."modifiers", + "posthog_team"."correlation_config", + "posthog_team"."session_recording_retention_period_days", + "posthog_team"."external_data_workspace_id", + "posthog_team"."external_data_workspace_last_synced_at" + FROM "posthog_team" + WHERE "posthog_team"."id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.3 + ''' + SELECT "posthog_remoteconfig"."id", + "posthog_remoteconfig"."team_id", + "posthog_remoteconfig"."config", + "posthog_remoteconfig"."updated_at", + "posthog_remoteconfig"."synced_at" + FROM "posthog_remoteconfig" + WHERE "posthog_remoteconfig"."team_id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.4 + ''' + SELECT "posthog_team"."id", + "posthog_team"."uuid", + "posthog_team"."organization_id", + "posthog_team"."project_id", + "posthog_team"."api_token", + "posthog_team"."app_urls", + "posthog_team"."name", + "posthog_team"."slack_incoming_webhook", + "posthog_team"."created_at", + "posthog_team"."updated_at", + "posthog_team"."anonymize_ips", + "posthog_team"."completed_snippet_onboarding", + "posthog_team"."has_completed_onboarding_for", + "posthog_team"."ingested_event", + "posthog_team"."autocapture_opt_out", + "posthog_team"."autocapture_web_vitals_opt_in", + "posthog_team"."autocapture_web_vitals_allowed_metrics", + "posthog_team"."autocapture_exceptions_opt_in", + "posthog_team"."autocapture_exceptions_errors_to_ignore", + "posthog_team"."person_processing_opt_out", + "posthog_team"."session_recording_opt_in", + "posthog_team"."session_recording_sample_rate", + "posthog_team"."session_recording_minimum_duration_milliseconds", + "posthog_team"."session_recording_linked_flag", + "posthog_team"."session_recording_network_payload_capture_config", + "posthog_team"."session_recording_url_trigger_config", + "posthog_team"."session_recording_url_blocklist_config", + "posthog_team"."session_recording_event_trigger_config", + "posthog_team"."session_replay_config", + "posthog_team"."survey_config", + "posthog_team"."capture_console_log_opt_in", + "posthog_team"."capture_performance_opt_in", + "posthog_team"."capture_dead_clicks", + "posthog_team"."surveys_opt_in", + "posthog_team"."heatmaps_opt_in", + "posthog_team"."session_recording_version", + "posthog_team"."signup_token", + "posthog_team"."is_demo", + "posthog_team"."access_control", + "posthog_team"."week_start_day", + "posthog_team"."inject_web_apps", + "posthog_team"."test_account_filters", + "posthog_team"."test_account_filters_default_checked", + "posthog_team"."path_cleaning_filters", + "posthog_team"."timezone", + "posthog_team"."data_attributes", + "posthog_team"."person_display_name_properties", + "posthog_team"."live_events_columns", + "posthog_team"."recording_domains", + "posthog_team"."primary_dashboard_id", + "posthog_team"."extra_settings", + "posthog_team"."modifiers", + "posthog_team"."correlation_config", + "posthog_team"."session_recording_retention_period_days", + "posthog_team"."plugins_opt_in", + "posthog_team"."opt_out_capture", + "posthog_team"."event_names", + "posthog_team"."event_names_with_usage", + "posthog_team"."event_properties", + "posthog_team"."event_properties_with_usage", + "posthog_team"."event_properties_numerical", + "posthog_team"."external_data_workspace_id", + "posthog_team"."external_data_workspace_last_synced_at" + FROM "posthog_team" + WHERE "posthog_team"."id" = 99999 + LIMIT 21 + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.5 + ''' + SELECT COUNT(*) AS "__count" + FROM "posthog_featureflag" + WHERE ("posthog_featureflag"."active" + AND NOT "posthog_featureflag"."deleted" + AND "posthog_featureflag"."team_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.6 + ''' + SELECT "posthog_survey"."id", + "posthog_survey"."team_id", + "posthog_survey"."name", + "posthog_survey"."description", + "posthog_survey"."linked_flag_id", + "posthog_survey"."targeting_flag_id", + "posthog_survey"."internal_targeting_flag_id", + "posthog_survey"."internal_response_sampling_flag_id", + "posthog_survey"."type", + "posthog_survey"."conditions", + "posthog_survey"."questions", + "posthog_survey"."appearance", + "posthog_survey"."created_at", + "posthog_survey"."created_by_id", + "posthog_survey"."start_date", + "posthog_survey"."end_date", + "posthog_survey"."updated_at", + "posthog_survey"."archived", + "posthog_survey"."responses_limit", + "posthog_survey"."response_sampling_start_date", + "posthog_survey"."response_sampling_interval_type", + "posthog_survey"."response_sampling_interval", + "posthog_survey"."response_sampling_limit", + "posthog_survey"."response_sampling_daily_limits", + "posthog_survey"."iteration_count", + "posthog_survey"."iteration_frequency_days", + "posthog_survey"."iteration_start_dates", + "posthog_survey"."current_iteration", + "posthog_survey"."current_iteration_start_date", + "posthog_featureflag"."id", + "posthog_featureflag"."key", + "posthog_featureflag"."name", + "posthog_featureflag"."filters", + "posthog_featureflag"."rollout_percentage", + "posthog_featureflag"."team_id", + "posthog_featureflag"."created_by_id", + "posthog_featureflag"."created_at", + "posthog_featureflag"."deleted", + "posthog_featureflag"."active", + "posthog_featureflag"."rollback_conditions", + "posthog_featureflag"."performed_rollback", + "posthog_featureflag"."ensure_experience_continuity", + "posthog_featureflag"."usage_dashboard_id", + "posthog_featureflag"."has_enriched_analytics", + T4."id", + T4."key", + T4."name", + T4."filters", + T4."rollout_percentage", + T4."team_id", + T4."created_by_id", + T4."created_at", + T4."deleted", + T4."active", + T4."rollback_conditions", + T4."performed_rollback", + T4."ensure_experience_continuity", + T4."usage_dashboard_id", + T4."has_enriched_analytics", + T5."id", + T5."key", + T5."name", + T5."filters", + T5."rollout_percentage", + T5."team_id", + T5."created_by_id", + T5."created_at", + T5."deleted", + T5."active", + T5."rollback_conditions", + T5."performed_rollback", + T5."ensure_experience_continuity", + T5."usage_dashboard_id", + T5."has_enriched_analytics" + FROM "posthog_survey" + LEFT OUTER JOIN "posthog_featureflag" ON ("posthog_survey"."linked_flag_id" = "posthog_featureflag"."id") + LEFT OUTER JOIN "posthog_featureflag" T4 ON ("posthog_survey"."targeting_flag_id" = T4."id") + LEFT OUTER JOIN "posthog_featureflag" T5 ON ("posthog_survey"."internal_targeting_flag_id" = T5."id") + WHERE ("posthog_survey"."team_id" = 99999 + AND NOT ("posthog_survey"."archived")) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.7 + ''' + SELECT "posthog_pluginconfig"."id", + "posthog_pluginsourcefile"."transpiled", + "posthog_pluginconfig"."web_token", + "posthog_plugin"."config_schema", + "posthog_pluginconfig"."config" + FROM "posthog_pluginconfig" + INNER JOIN "posthog_plugin" ON ("posthog_pluginconfig"."plugin_id" = "posthog_plugin"."id") + INNER JOIN "posthog_pluginsourcefile" ON ("posthog_plugin"."id" = "posthog_pluginsourcefile"."plugin_id") + WHERE ("posthog_pluginconfig"."enabled" + AND "posthog_pluginsourcefile"."filename" = 'site.ts' + AND "posthog_pluginsourcefile"."status" = 'TRANSPILED' + AND "posthog_pluginconfig"."team_id" = 99999) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.8 + ''' + SELECT "posthog_hogfunction"."id", + "posthog_hogfunction"."team_id", + "posthog_hogfunction"."name", + "posthog_hogfunction"."description", + "posthog_hogfunction"."created_at", + "posthog_hogfunction"."created_by_id", + "posthog_hogfunction"."deleted", + "posthog_hogfunction"."updated_at", + "posthog_hogfunction"."enabled", + "posthog_hogfunction"."type", + "posthog_hogfunction"."icon_url", + "posthog_hogfunction"."hog", + "posthog_hogfunction"."bytecode", + "posthog_hogfunction"."transpiled", + "posthog_hogfunction"."inputs_schema", + "posthog_hogfunction"."inputs", + "posthog_hogfunction"."encrypted_inputs", + "posthog_hogfunction"."filters", + "posthog_hogfunction"."masking", + "posthog_hogfunction"."template_id" + FROM "posthog_hogfunction" + WHERE ("posthog_hogfunction"."enabled" + AND "posthog_hogfunction"."team_id" = 99999 + AND "posthog_hogfunction"."type" IN ('site_destination', + 'site_app')) + ''' +# --- +# name: TestPreviewList.test_early_access_features_with_pre_env_cached_team.9 + ''' + SELECT "posthog_user"."id", + "posthog_user"."password", + "posthog_user"."last_login", + "posthog_user"."first_name", + "posthog_user"."last_name", + "posthog_user"."is_staff", + "posthog_user"."date_joined", + "posthog_user"."uuid", + "posthog_user"."current_organization_id", + "posthog_user"."current_team_id", + "posthog_user"."email", + "posthog_user"."pending_email", + "posthog_user"."temporary_token", + "posthog_user"."distinct_id", + "posthog_user"."is_email_verified", + "posthog_user"."has_seen_product_intro_for", + "posthog_user"."strapi_id", + "posthog_user"."is_active", + "posthog_user"."theme_mode", + "posthog_user"."partial_notification_settings", + "posthog_user"."anonymize_data", + "posthog_user"."toolbar_mode", + "posthog_user"."hedgehog_config", + "posthog_user"."events_column_config", + "posthog_user"."email_opt_in" + FROM "posthog_user" + WHERE "posthog_user"."id" = 99999 + LIMIT 21 + ''' +# --- diff --git a/posthog/api/test/test_early_access_feature.py b/posthog/api/test/test_early_access_feature.py index 311fbae3cb1d3..525490c4f949d 100644 --- a/posthog/api/test/test_early_access_feature.py +++ b/posthog/api/test/test_early_access_feature.py @@ -1,3 +1,4 @@ +import json from unittest.mock import ANY from rest_framework import status @@ -7,6 +8,7 @@ from posthog.models.early_access_feature import EarlyAccessFeature from posthog.models import FeatureFlag, Person +from posthog.models.team.team_caching import set_team_in_cache from posthog.test.base import ( APIBaseTest, BaseTest, @@ -631,6 +633,109 @@ def test_early_access_features(self): ], ) + @snapshot_postgres_queries + def test_early_access_features_with_pre_env_cached_team(self): + Person.objects.create( + team=self.team, + distinct_ids=["example_id"], + properties={"email": "example@posthog.com"}, + ) + + # This is precisely what the `set_team_in_cache()` would have set on Dec 9, 2024 + cache.set( + f"team_token:{self.team.api_token}", + json.dumps( + { + # Important: this serialization doesn't have `project_id`! It wasn't always part of CachingTeamSerializer + "id": self.team.id, + "uuid": str(self.team.uuid), + "name": self.team.name, + "api_token": self.team.api_token, + } + ), + ) + feature_flag = FeatureFlag.objects.create( + team=self.team, + name=f"Feature Flag for Feature Sprocket", + key="sprocket", + rollout_percentage=0, + created_by=self.user, + ) + feature = EarlyAccessFeature.objects.create( + team=self.team, + name="Sprocket", + description="A fancy new sprocket.", + stage="beta", + feature_flag=feature_flag, + ) + + self.client.logout() + + with self.assertNumQueries(1): + response = self._get_features() + self.assertEqual(response.status_code, 200) + self.assertEqual(response.get("access-control-allow-origin"), "http://127.0.0.1:8000") + + self.assertListEqual( + response.json()["earlyAccessFeatures"], + [ + { + "id": str(feature.id), + "name": "Sprocket", + "description": "A fancy new sprocket.", + "stage": "beta", + "documentationUrl": "", + "flagKey": "sprocket", + } + ], + ) + + @snapshot_postgres_queries + def test_early_access_features_with_cached_team(self): + Person.objects.create( + team=self.team, + distinct_ids=["example_id"], + properties={"email": "example@posthog.com"}, + ) + + # Slightly dirty to use the actual implementation of `set_team_in_cache()` here, but this tests how things are + set_team_in_cache(self.team.api_token) + feature_flag = FeatureFlag.objects.create( + team=self.team, + name=f"Feature Flag for Feature Sprocket", + key="sprocket", + rollout_percentage=0, + created_by=self.user, + ) + feature = EarlyAccessFeature.objects.create( + team=self.team, + name="Sprocket", + description="A fancy new sprocket.", + stage="beta", + feature_flag=feature_flag, + ) + + self.client.logout() + + with self.assertNumQueries(1): + response = self._get_features() + self.assertEqual(response.status_code, 200) + self.assertEqual(response.get("access-control-allow-origin"), "http://127.0.0.1:8000") + + self.assertListEqual( + response.json()["earlyAccessFeatures"], + [ + { + "id": str(feature.id), + "name": "Sprocket", + "description": "A fancy new sprocket.", + "stage": "beta", + "documentationUrl": "", + "flagKey": "sprocket", + } + ], + ) + def test_early_access_features_beta_only(self): Person.objects.create( team=self.team, diff --git a/posthog/models/team/team.py b/posthog/models/team/team.py index b87ed07c84ee0..40bea6d9e089c 100644 --- a/posthog/models/team/team.py +++ b/posthog/models/team/team.py @@ -519,7 +519,7 @@ def __str__(self): return ", ".join(self.app_urls) return str(self.pk) - __repr__ = sane_repr("uuid", "name", "api_token") + __repr__ = sane_repr("id", "uuid", "project_id", "name", "api_token") @mutable_receiver(post_save, sender=Team) diff --git a/posthog/models/team/team_caching.py b/posthog/models/team/team_caching.py index 78042111a824c..66309bd9399e2 100644 --- a/posthog/models/team/team_caching.py +++ b/posthog/models/team/team_caching.py @@ -38,6 +38,8 @@ def get_team_in_cache(token: str) -> Optional["Team"]: if team_data: try: parsed_data = json.loads(team_data) + if "project_id" not in parsed_data: + parsed_data["project_id"] = parsed_data["id"] return Team(**parsed_data) except Exception as e: capture_exception(e)