diff --git a/api/routers/core.py b/api/routers/core.py index 129ae9cc9..bbeb30bcd 100644 --- a/api/routers/core.py +++ b/api/routers/core.py @@ -108,7 +108,7 @@ def events_search(projectId: int, q: str, type: Union[schemas.FilterType, schema @app.post('/{projectId}/sessions/search2', tags=["sessions"]) -def sessions_search2(projectId: int, data: schemas.SessionsSearchPayloadSchema = Body(...), +def sessions_search2(projectId: int, data: schemas.FlatSessionsSearchPayloadSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): data = sessions.search2_pg(data, projectId, user_id=context.user_id) return {'data': data} diff --git a/api/schemas.py b/api/schemas.py index 0dfd949ac..949ab0dff 100644 --- a/api/schemas.py +++ b/api/schemas.py @@ -458,7 +458,15 @@ class IssueType(str, Enum): js_exception = 'js_exception' -class _SessionSearchEventRaw(BaseModel): +class __MixedSearchFilter(BaseModel): + is_event: bool = Field(...) + + class Config: + alias_generator = attribute_to_camel_case + + +class _SessionSearchEventRaw(__MixedSearchFilter): + is_event: bool = Field(True, const=True) custom: Optional[List[Union[int, str]]] = Field(None, min_items=1) customOperator: Optional[MathOperator] = Field(None) key: Optional[str] = Field(None) @@ -491,7 +499,8 @@ class _SessionSearchEventSchema(_SessionSearchEventRaw): value: Union[List[_SessionSearchEventRaw], str, List[str]] = Field(...) -class _SessionSearchFilterSchema(BaseModel): +class _SessionSearchFilterSchema(__MixedSearchFilter): + is_event: bool = Field(False, const=False) custom: Optional[List[str]] = Field(None) key: Optional[str] = Field(None) value: Union[Optional[Union[IssueType, PlatformType, int, str]], @@ -536,6 +545,31 @@ class SessionsSearchPayloadSchema(BaseModel): alias_generator = attribute_to_camel_case +class FlatSessionsSearchPayloadSchema(SessionsSearchPayloadSchema): + events: Optional[List[_SessionSearchEventSchema]] = Field([]) + filters: List[Union[_SessionSearchFilterSchema, _SessionSearchEventSchema]] = Field([]) + + @root_validator(pre=True) + def flat_to_original(cls, values): + # in case the old search body was passed + if len(values.get("events", [])) > 0: + for v in values["events"]: + v["isEvent"] = True + for v in values.get("filters", []): + v["isEvent"] = False + else: + n_filters = [] + n_events = [] + for v in values.get("filters", []): + if v["isEvent"]: + n_events.append(v) + else: + n_filters.append(v) + values["events"] = n_events + values["filters"] = n_filters + return values + + class SessionsSearchCountSchema(SessionsSearchPayloadSchema): sort: Optional[str] = Field(default=None) order: Optional[str] = Field(default=None)