feat(api): udpated projects to have conditions (#1793)

* feat(api): udpated projects to have conditions

* feat(api): fixed typo

* feat(api): added conditions_count to the list

* feat(api): check for null conditions

* feat(api): validate condition names
This commit is contained in:
Shekar Siri 2023-12-22 10:32:49 +01:00 committed by GitHub
parent ca374a1c82
commit 139708b64a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 2 deletions

View file

@ -1,5 +1,6 @@
import json
from typing import Optional
from typing import Optional, List
from collections import Counter
from fastapi import HTTPException, status
@ -69,7 +70,8 @@ def get_projects(tenant_id: int, gdpr: bool = False, recorded: bool = False):
query = cur.mogrify(f"""{"SELECT *, first_recorded IS NOT NULL AS recorded FROM (" if recorded else ""}
SELECT s.project_id, s.name, s.project_key, s.save_request_payloads, s.first_recorded_session_at,
s.created_at, s.sessions_last_check_at, s.sample_rate, s.platform
s.created_at, s.sessions_last_check_at, s.sample_rate, s.platform,
(SELECT count(*) FROM jsonb_array_elements_text(s.conditions)) AS conditions_count
{extra_projection}
FROM public.projects AS s
WHERE s.deleted_at IS NULL
@ -250,6 +252,71 @@ def update_capture_status(project_id, changes: schemas.SampleRateSchema):
return changes
def get_conditions(project_id):
with pg_client.PostgresClient() as cur:
query = cur.mogrify("""SELECT sample_rate AS rate, sample_rate=100 AS capture_all, conditions
FROM public.projects
WHERE project_id =%(project_id)s
AND deleted_at ISNULL;""",
{"project_id": project_id})
cur.execute(query=query)
row = cur.fetchone()
row = helper.dict_to_camel_case(row)
if row["conditions"] is None:
row["conditions"] = []
else:
row["conditions"] = [schemas.ProjectConditions(**c) for c in row["conditions"]]
return row
def validate_conditions(conditions: List[schemas.ProjectConditions]) -> List[str]:
errors = []
names = [condition.name for condition in conditions]
# Check for empty strings
if any(name.strip() == "" for name in names):
errors.append("Condition names cannot be empty strings")
# Check for duplicates
name_counts = Counter(names)
duplicates = [name for name, count in name_counts.items() if count > 1]
if duplicates:
errors.append(f"Duplicate condition names found: {duplicates}")
return errors
def update_conditions(project_id, changes: schemas.ProjectSettings):
sample_rate = changes.rate
if changes.capture_all:
sample_rate = 100
validation_errors = validate_conditions(changes.conditions)
if validation_errors:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=validation_errors)
conditions = []
for condition in changes.conditions:
conditions.append(condition.model_dump())
with pg_client.PostgresClient() as cur:
query = cur.mogrify("""UPDATE public.projects
SET
sample_rate= %(sample_rate)s,
conditions = %(conditions)s::jsonb
WHERE project_id =%(project_id)s
AND deleted_at ISNULL;""",
{
"project_id": project_id,
"sample_rate": sample_rate,
"conditions": json.dumps(conditions)
})
cur.execute(query=query)
return changes
def get_projects_ids(tenant_id):
with pg_client.PostgresClient() as cur:
query = f"""SELECT s.project_id

View file

@ -511,6 +511,17 @@ def update_capture_status(projectId: int, data: schemas.SampleRateSchema = Body(
return {"data": projects.update_capture_status(project_id=projectId, changes=data)}
@app.post('/{projectId}/conditions', tags=["projects"])
def update_conditions(projectId: int, data: schemas.ProjectSettings = Body(...),
context: schemas.CurrentContext = Depends(OR_context)):
return {"data": projects.update_conditions(project_id=projectId, changes=data)}
@app.get('/{projectId}/conditions', tags=["projects"])
def get_conditions(projectId: int, context: schemas.CurrentContext = Depends(OR_context)):
return {"data": projects.get_conditions(project_id=projectId)}
@app.get('/announcements', tags=["announcements"])
def get_all_announcements(context: schemas.CurrentContext = Depends(OR_context)):
return {"data": announcements.get_all(user_id=context.user_id)}

View file

@ -1323,6 +1323,18 @@ class SavedSearchSchema(BaseModel):
filter: SessionsSearchPayloadSchema = Field([])
class ProjectConditions(BaseModel):
name: str = Field(...)
capture_rate: int = Field(..., ge=0, le=100)
filters: List[GroupedFilterType] = Field(default=[])
class ProjectSettings(BaseModel):
rate: int = Field(..., ge=0, le=100)
capture_all: bool = Field(default=False)
conditions: List[ProjectConditions] = Field(default=[])
class CreateDashboardSchema(BaseModel):
name: str = Field(..., min_length=1)
description: Optional[str] = Field(default='')

View file

@ -29,6 +29,9 @@ UPDATE public.sessions
SET has_ut_test= TRUE
WHERE session_id IN (SELECT session_id FROM public.ut_tests_signals);
ALTER TABLE IF EXISTS public.projects
ADD COLUMN IF NOT EXISTS conditions jsonb DEFAULT NULL;
COMMIT;
\elif :is_next