diff --git a/api/chalicelib/core/custom_metrics.py b/api/chalicelib/core/custom_metrics.py index d7fd8dd19..01067cac2 100644 --- a/api/chalicelib/core/custom_metrics.py +++ b/api/chalicelib/core/custom_metrics.py @@ -107,7 +107,7 @@ def __is_click_map(data: schemas.CreateCardSchema): def __get_click_map_chat(project_id, user_id, data: schemas.CreateCardSchema): if len(data.series) == 0: - return {} + return None data.series[0].filter.startDate = data.startTimestamp data.series[0].filter.endDate = data.endTimestamp return click_maps.search_short_session(project_id=project_id, user_id=user_id, diff --git a/api/routers/subs/metrics.py b/api/routers/subs/metrics.py index 378482815..43e0cea7e 100644 --- a/api/routers/subs/metrics.py +++ b/api/routers/subs/metrics.py @@ -199,6 +199,7 @@ def get_card_funnel_issues(projectId: int, metric_id: Union[int, str], return {"data": data} +@app.post('/{projectId}/cards/{metric_id}/issues/{issueId}/sessions', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}/issues/{issueId}/sessions', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/issues/{issueId}/sessions', tags=["customMetrics"]) def get_metric_funnel_issue_sessions(projectId: int, metric_id: int, issueId: str, @@ -211,6 +212,7 @@ def get_metric_funnel_issue_sessions(projectId: int, metric_id: int, issueId: st return {"data": data} +@app.post('/{projectId}/cards/{metric_id}/errors', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}/errors', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/errors', tags=["customMetrics"]) def get_custom_metric_errors_list(projectId: int, metric_id: int, @@ -233,6 +235,7 @@ def get_card_chart(projectId: int, metric_id: int, data: schemas.CardChartSchema return {"data": data} +@app.post('/{projectId}/cards/{metric_id}', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}', tags=["dashboard"]) @app.put('/{projectId}/metrics/{metric_id}', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}', tags=["customMetrics"]) @@ -245,6 +248,7 @@ def update_custom_metric(projectId: int, metric_id: int, data: schemas.UpdateCar return {"data": data} +@app.post('/{projectId}/cards/{metric_id}/status', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}/status', tags=["dashboard"]) @app.put('/{projectId}/metrics/{metric_id}/status', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/status', tags=["customMetrics"]) @@ -257,6 +261,7 @@ def update_custom_metric_state(projectId: int, metric_id: int, status=data.active)} +@app.delete('/{projectId}/cards/{metric_id}', tags=["dashboard"]) @app.delete('/{projectId}/metrics/{metric_id}', tags=["dashboard"]) @app.delete('/{projectId}/custom_metrics/{metric_id}', tags=["customMetrics"]) def delete_custom_metric(projectId: int, metric_id: int, context: schemas.CurrentContext = Depends(OR_context)): diff --git a/ee/api/chalicelib/core/custom_metrics.py b/ee/api/chalicelib/core/custom_metrics.py index 238608897..ab7c39441 100644 --- a/ee/api/chalicelib/core/custom_metrics.py +++ b/ee/api/chalicelib/core/custom_metrics.py @@ -1,10 +1,12 @@ import json from typing import Union +from fastapi import HTTPException +from starlette import status from decouple import config import schemas -from chalicelib.core import funnels, issues, metrics +from chalicelib.core import funnels, issues, metrics, click_maps from chalicelib.utils import helper, pg_client from chalicelib.utils.TimeUTC import TimeUTC @@ -147,12 +149,12 @@ def merged_live(project_id, data: schemas.CreateCardSchema, user_id=None): return results -def __merge_metric_with_data(metric, data: Union[schemas.CardChartSchema, -schemas.CardSessionsSchema]) \ - -> Union[schemas.CreateCardSchema, None]: +def __merge_metric_with_data(metric: schemas.CreateCardSchema, + data: schemas.CardChartSchema) -> schemas.CreateCardSchema: if data.series is not None and len(data.series) > 0: - metric["series"] = data.series - metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**{**data.dict(), **metric}) + metric.series = data.series + metric: schemas.CreateCardSchema = schemas.CreateCardSchema( + **{**data.dict(by_alias=True), **metric.dict(by_alias=True)}) if len(data.filters) > 0 or len(data.events) > 0: for s in metric.series: if len(data.filters) > 0: @@ -162,7 +164,7 @@ schemas.CardSessionsSchema]) \ return metric -def make_chart(project_id, user_id, metric_id, data: schemas.CardChartSchema, metric=None): +def make_chart(project_id, user_id, metric_id, data: schemas.CardChartSchema, metric: schemas.CreateCardSchema = None): if metric is None: metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) if metric is None: @@ -173,9 +175,10 @@ def make_chart(project_id, user_id, metric_id, data: schemas.CardChartSchema, me def get_sessions(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): - metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) - if metric is None: + raw_metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) + if raw_metric is None: return None + metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric) metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data) if metric is None: return None @@ -192,9 +195,10 @@ def get_sessions(project_id, user_id, metric_id, data: schemas.CardSessionsSchem def get_funnel_issues(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): - metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) - if metric is None: + raw_metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) + if raw_metric is None: return None + metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric) metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data) if metric is None: return None @@ -208,9 +212,10 @@ def get_funnel_issues(project_id, user_id, metric_id, data: schemas.CardSessions def get_errors_list(project_id, user_id, metric_id, data: schemas.CardSessionsSchema): - metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) - if metric is None: + raw_metric = get_card(metric_id=metric_id, project_id=project_id, user_id=user_id, flatten=False) + if raw_metric is None: return None + metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric) metric: schemas.CreateCardSchema = __merge_metric_with_data(metric=metric, data=data) if metric is None: return None @@ -597,12 +602,12 @@ def make_chart_from_card(project_id, user_id, metric_id, data: schemas.CardChart raw_metric = get_with_template(metric_id=metric_id, project_id=project_id, user_id=user_id, include_dashboard=False) if raw_metric is None: - return None + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="card not found") metric: schemas.CreateCardSchema = schemas.CreateCardSchema(**raw_metric) if metric.is_template: return get_predefined_metric(key=metric.metric_of, project_id=project_id, data=data.dict()) else: - return make_chart(project_id=project_id, user_id=user_id, metric_id=metric_id, data=data, metric=raw_metric) + return make_chart(project_id=project_id, user_id=user_id, metric_id=metric_id, data=data, metric=metric) PREDEFINED = {schemas.MetricOfWebVitals.count_sessions: metrics.get_processed_sessions, diff --git a/ee/api/routers/subs/metrics.py b/ee/api/routers/subs/metrics.py index 4dfc09807..24de16db3 100644 --- a/ee/api/routers/subs/metrics.py +++ b/ee/api/routers/subs/metrics.py @@ -114,7 +114,7 @@ def try_card_sessions(projectId: int, data: schemas.CardSessionsSchema = Body(.. return {"data": data} -@app.post('/{projectId}/card/try/issues', tags=["cards"]) +@app.post('/{projectId}/cards/try/issues', tags=["cards"]) @app.post('/{projectId}/metrics/try/issues', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/try/issues', tags=["customMetrics"]) def try_card_funnel_issues(projectId: int, data: schemas.CardSessionsSchema = Body(...), @@ -187,9 +187,12 @@ def get_card_sessions(projectId: int, metric_id: int, @app.post('/{projectId}/cards/{metric_id}/issues', tags=["cards"]) @app.post('/{projectId}/metrics/{metric_id}/issues', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/issues', tags=["customMetrics"]) -def get_card_funnel_issues(projectId: int, metric_id: int, +def get_card_funnel_issues(projectId: int, metric_id: Union[int, str], data: schemas.CardSessionsSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): + if not isinstance(metric_id, int): + return {"errors": [f"invalid card_id: {metric_id}"]} + data = custom_metrics.get_funnel_issues(project_id=projectId, user_id=context.user_id, metric_id=metric_id, data=data) if data is None: @@ -197,6 +200,7 @@ def get_card_funnel_issues(projectId: int, metric_id: int, return {"data": data} +@app.post('/{projectId}/cards/{metric_id}/issues/{issueId}/sessions', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}/issues/{issueId}/sessions', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/issues/{issueId}/sessions', tags=["customMetrics"]) def get_metric_funnel_issue_sessions(projectId: int, metric_id: int, issueId: str, @@ -209,6 +213,7 @@ def get_metric_funnel_issue_sessions(projectId: int, metric_id: int, issueId: st return {"data": data} +@app.post('/{projectId}/cards/{metric_id}/errors', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}/errors', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/errors', tags=["customMetrics"]) def get_custom_metric_errors_list(projectId: int, metric_id: int, @@ -228,11 +233,10 @@ def get_card_chart(projectId: int, metric_id: int, data: schemas.CardChartSchema context: schemas.CurrentContext = Depends(OR_context)): data = custom_metrics.make_chart_from_card(project_id=projectId, user_id=context.user_id, metric_id=metric_id, data=data) - if data is None: - return {"errors": ["custom metric not found"]} return {"data": data} +@app.post('/{projectId}/cards/{metric_id}', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}', tags=["dashboard"]) @app.put('/{projectId}/metrics/{metric_id}', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}', tags=["customMetrics"]) @@ -245,6 +249,7 @@ def update_custom_metric(projectId: int, metric_id: int, data: schemas.UpdateCar return {"data": data} +@app.post('/{projectId}/cards/{metric_id}/status', tags=["dashboard"]) @app.post('/{projectId}/metrics/{metric_id}/status', tags=["dashboard"]) @app.put('/{projectId}/metrics/{metric_id}/status', tags=["dashboard"]) @app.post('/{projectId}/custom_metrics/{metric_id}/status', tags=["customMetrics"]) @@ -257,6 +262,7 @@ def update_custom_metric_state(projectId: int, metric_id: int, status=data.active)} +@app.delete('/{projectId}/cards/{metric_id}', tags=["dashboard"]) @app.delete('/{projectId}/metrics/{metric_id}', tags=["dashboard"]) @app.delete('/{projectId}/custom_metrics/{metric_id}', tags=["customMetrics"]) def delete_custom_metric(projectId: int, metric_id: int, context: schemas.CurrentContext = Depends(OR_context)):