diff --git a/plugin-server/src/types.ts b/plugin-server/src/types.ts index e8682da3b337be..47ac3764a3528d 100644 --- a/plugin-server/src/types.ts +++ b/plugin-server/src/types.ts @@ -1103,6 +1103,7 @@ export interface EventDefinitionType { volume_30_day: number | null query_usage_30_day: number | null team_id: number + project_id: number | null last_seen_at: string // DateTime created_at: string // DateTime } @@ -1142,6 +1143,7 @@ export interface PropertyDefinitionType { volume_30_day: number | null query_usage_30_day: number | null team_id: number + project_id: number | null property_type?: PropertyType type: PropertyDefinitionTypeEnum group_type_index: number | null @@ -1152,6 +1154,7 @@ export interface EventPropertyType { event: string property: string team_id: number + project_id: number | null } export type PluginFunction = 'onEvent' | 'processEvent' | 'pluginTask' diff --git a/posthog/migrations/0523_project_field_in_taxonomy.py b/posthog/migrations/0523_project_field_in_taxonomy.py new file mode 100644 index 00000000000000..9559cc011bc857 --- /dev/null +++ b/posthog/migrations/0523_project_field_in_taxonomy.py @@ -0,0 +1,66 @@ +# Generated by Django 4.2.15 on 2024-10-29 12:15 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + atomic = False # Added to support concurrent index creation + dependencies = [("posthog", "0522_datawarehouse_salesforce_opportunity")] + + operations = [ + migrations.SeparateDatabaseAndState( + state_operations=[ + migrations.AddField( + model_name="eventdefinition", + name="project", + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="posthog.project" + ), + ), + migrations.AddField( + model_name="eventproperty", + name="project", + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="posthog.project" + ), + ), + migrations.AddField( + model_name="propertydefinition", + name="project", + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="posthog.project" + ), + ), + ], + database_operations=[ + migrations.RunSQL( + """ + -- Add field project to eventdefinition + ALTER TABLE "posthog_eventdefinition" ADD COLUMN "project_id" bigint NULL CONSTRAINT "posthog_eventdefinit_project_id_f93fcbb0_fk_posthog_p" REFERENCES "posthog_project"("id") DEFERRABLE INITIALLY DEFERRED; + SET CONSTRAINTS "posthog_eventdefinit_project_id_f93fcbb0_fk_posthog_p" IMMEDIATE; + -- Add field project to eventproperty + ALTER TABLE "posthog_eventproperty" ADD COLUMN "project_id" bigint NULL CONSTRAINT "posthog_eventproperty_project_id_dd2337d2_fk_posthog_project_id" REFERENCES "posthog_project"("id") DEFERRABLE INITIALLY DEFERRED; + SET CONSTRAINTS "posthog_eventproperty_project_id_dd2337d2_fk_posthog_project_id" IMMEDIATE; + -- Add field project to propertydefinition + ALTER TABLE "posthog_propertydefinition" ADD COLUMN "project_id" bigint NULL CONSTRAINT "posthog_propertydefi_project_id_d3eb982d_fk_posthog_p" REFERENCES "posthog_project"("id") DEFERRABLE INITIALLY DEFERRED; + SET CONSTRAINTS "posthog_propertydefi_project_id_d3eb982d_fk_posthog_p" IMMEDIATE;""", + reverse_sql=""" + ALTER TABLE "posthog_eventdefinition" DROP COLUMN IF EXISTS "project_id"; + ALTER TABLE "posthog_eventproperty" DROP COLUMN IF EXISTS "project_id"; + ALTER TABLE "posthog_propertydefinition" DROP COLUMN IF EXISTS "project_id";""", + ), + # We add CONCURRENTLY to the CREATE INDEX commands + migrations.RunSQL( + """ + CREATE INDEX CONCURRENTLY "posthog_eventdefinition_project_id_f93fcbb0" ON "posthog_eventdefinition" ("project_id"); + CREATE INDEX CONCURRENTLY "posthog_eventproperty_project_id_dd2337d2" ON "posthog_eventproperty" ("project_id"); + CREATE INDEX CONCURRENTLY "posthog_propertydefinition_project_id_d3eb982d" ON "posthog_propertydefinition" ("project_id");""", + reverse_sql=""" + DROP INDEX IF EXISTS "posthog_eventdefinition_project_id_f93fcbb0"; + DROP INDEX IF EXISTS "posthog_eventproperty_project_id_dd2337d2"; + DROP INDEX IF EXISTS "posthog_propertydefinition_project_id_d3eb982d";""", + ), + ], + ) + ] diff --git a/posthog/migrations/max_migration.txt b/posthog/migrations/max_migration.txt index 334dacbdf2b211..6a909226c99e4f 100644 --- a/posthog/migrations/max_migration.txt +++ b/posthog/migrations/max_migration.txt @@ -1 +1 @@ -0522_datawarehouse_salesforce_opportunity +0523_project_field_in_taxonomy diff --git a/posthog/models/event_definition.py b/posthog/models/event_definition.py index 3f5c8d8a6f45b9..bf24bd2f45b905 100644 --- a/posthog/models/event_definition.py +++ b/posthog/models/event_definition.py @@ -13,6 +13,7 @@ class EventDefinition(UUIDModel): related_name="event_definitions", related_query_name="team", ) + project = models.ForeignKey("Project", on_delete=models.CASCADE, null=True) name = models.CharField(max_length=400) created_at = models.DateTimeField(default=timezone.now, null=True) last_seen_at = models.DateTimeField(default=None, null=True) diff --git a/posthog/models/event_property.py b/posthog/models/event_property.py index a5087c5b3f6677..f9a54827cddf41 100644 --- a/posthog/models/event_property.py +++ b/posthog/models/event_property.py @@ -6,6 +6,7 @@ class EventProperty(models.Model): team = models.ForeignKey(Team, on_delete=models.CASCADE) + project = models.ForeignKey("Project", on_delete=models.CASCADE, null=True) event = models.CharField(max_length=400, null=False) property = models.CharField(max_length=400, null=False) diff --git a/posthog/models/property_definition.py b/posthog/models/property_definition.py index e2e77eba2148c8..1719c4007e97e8 100644 --- a/posthog/models/property_definition.py +++ b/posthog/models/property_definition.py @@ -43,6 +43,7 @@ class Type(models.IntegerChoices): related_name="property_definitions", related_query_name="team", ) + project = models.ForeignKey("Project", on_delete=models.CASCADE, null=True) name = models.CharField(max_length=400) is_numerical = models.BooleanField( default=False diff --git a/rust/property-defs-rs/src/types.rs b/rust/property-defs-rs/src/types.rs index 892ddcc4b55345..e2c09c129934c9 100644 --- a/rust/property-defs-rs/src/types.rs +++ b/rust/property-defs-rs/src/types.rs @@ -133,6 +133,7 @@ impl Update { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Event { pub team_id: i32, + pub project_id: i32, pub event: String, pub properties: Option, } @@ -419,14 +420,15 @@ impl EventDefinition { { sqlx::query!( r#" - INSERT INTO posthog_eventdefinition (id, name, volume_30_day, query_usage_30_day, team_id, last_seen_at, created_at) - VALUES ($1, $2, NULL, NULL, $3, $4, NOW()) ON CONFLICT + INSERT INTO posthog_eventdefinition (id, name, volume_30_day, query_usage_30_day, team_id, project_id, last_seen_at, created_at) + VALUES ($1, $2, NULL, NULL, $3, $4, $5, NOW()) ON CONFLICT ON CONSTRAINT posthog_eventdefinition_team_id_name_80fa0b87_uniq DO UPDATE SET last_seen_at = $4 "#, Uuid::now_v7(), self.name, self.team_id, + self.project_id, Utc::now() // We floor the update datetime to the nearest day for cache purposes, but can insert the exact time we see the event ).execute(executor).await.map(|_| ()) } @@ -462,8 +464,8 @@ impl PropertyDefinition { sqlx::query!( r#" - INSERT INTO posthog_propertydefinition (id, name, type, group_type_index, is_numerical, volume_30_day, query_usage_30_day, team_id, property_type) - VALUES ($1, $2, $3, $4, $5, NULL, NULL, $6, $7) + INSERT INTO posthog_propertydefinition (id, name, type, group_type_index, is_numerical, volume_30_day, query_usage_30_day, team_id, project_id, property_type) + VALUES ($1, $2, $3, $4, $5, NULL, NULL, $6, $7, $8) ON CONFLICT (team_id, name, type, coalesce(group_type_index, -1)) DO UPDATE SET property_type=EXCLUDED.property_type WHERE posthog_propertydefinition.property_type IS NULL "#, @@ -473,6 +475,7 @@ impl PropertyDefinition { group_type_index, self.is_numerical, self.team_id, + self.project_id, self.property_type.as_ref().map(|t| t.to_string()) ).execute(executor).await.map(|_| ()) } @@ -484,10 +487,11 @@ impl EventProperty { E: Executor<'c, Database = Postgres>, { sqlx::query!( - r#"INSERT INTO posthog_eventproperty (event, property, team_id) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING"#, + r#"INSERT INTO posthog_eventproperty (event, property, team_id, project_id) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING"#, self.event, self.property, self.team_id + self.project_id ) .execute(executor) .await