Skip to content

Commit

Permalink
feat(api): tag and watch (openreplay#1834)
Browse files Browse the repository at this point in the history
  • Loading branch information
ⵄⵎⵉⵔⵓⵛ authored Jan 19, 2024
1 parent 622b189 commit 97ee6c7
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 11 deletions.
18 changes: 18 additions & 0 deletions api/chalicelib/core/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,22 @@ def get_by_session_id(session_id, project_id, group_clickrage=False, event_type:
return rows


def _search_tags(project_id, value, key=None, source=None):
with pg_client.PostgresClient() as cur:
query = f"""
SELECT public.tags.name
'{events.EventType.TAG.ui_type}' AS type
FROM public.tags
WHERE public.tags.project_id = %(project_id)s
ORDER BY SIMILARITY(public.tags.name, %(value)s) DESC
LIMIT 10
"""
query = cur.mogrify(query, {'project_id': project_id, 'value': value})
cur.execute(query)
results = helper.list_to_camel_case(cur.fetchall())
return results


class EventType:
CLICK = Event(ui_type=schemas.EventType.click, table="events.clicks", column="label")
INPUT = Event(ui_type=schemas.EventType.input, table="events.inputs", column="label")
Expand All @@ -106,6 +122,7 @@ class EventType:
REQUEST = Event(ui_type=schemas.EventType.request, table="events_common.requests", column="path")
GRAPHQL = Event(ui_type=schemas.EventType.graphql, table="events.graphql", column="name")
STATEACTION = Event(ui_type=schemas.EventType.state_action, table="events.state_actions", column="name")
TAG = Event(ui_type=schemas.EventType.tag, table="events.tags", column="tag_id")
ERROR = Event(ui_type=schemas.EventType.error, table="events.errors",
column=None) # column=None because errors are searched by name or message
METADATA = Event(ui_type=schemas.FilterType.metadata, table="public.sessions", column=None)
Expand Down Expand Up @@ -139,6 +156,7 @@ class EventType:
EventType.STATEACTION.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.STATEACTION),
query=autocomplete.__generic_query(
typename=EventType.STATEACTION.ui_type)),
EventType.TAG.ui_type: SupportedFilter(get=_search_tags, query=None),
EventType.ERROR.ui_type: SupportedFilter(get=autocomplete.__search_errors,
query=None),
EventType.METADATA.ui_type: SupportedFilter(get=autocomplete.__search_metadata,
Expand Down
5 changes: 5 additions & 0 deletions api/chalicelib/core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,11 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status,
sh.multi_conditions(f"main.{events.EventType.CLICK_IOS.column} {op} %({e_k})s", event.value,
value_key=e_k))

elif event_type == events.EventType.TAG.ui_type:
event_from = event_from % f"{events.EventType.TAG.table} AS main "
if not is_any:
event_where.append(
sh.multi_conditions(f"main.tag_id = %({e_k})s", event.value, value_key=e_k))
elif event_type == events.EventType.INPUT.ui_type:
if platform == "web":
event_from = event_from % f"{events.EventType.INPUT.table} AS main "
Expand Down
69 changes: 69 additions & 0 deletions api/chalicelib/core/tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import schemas
from chalicelib.utils import helper
from chalicelib.utils import pg_client


def create_tag(project_id: int, data: schemas.TagCreate) -> int:
query = """
INSERT INTO public.tags (project_id, name, selector, ignore_click_rage, ignore_dead_click)
VALUES (%(project_id)s, %(name)s, %(selector)s, %(ignore_click_rage)s, %(ignore_dead_click)s)
RETURNING tag_id;
"""

data = {
'project_id': project_id,
'name': data.name.strip(),
'selector': data.selector,
'ignore_click_rage': data.ignoreClickRage,
'ignore_dead_click': data.ignoreDeadClick
}

with pg_client.PostgresClient() as cur:
query = cur.mogrify(query, data)
cur.execute(query)
row = cur.fetchone()

return row['tag_id']


def list_tags(project_id: int):
query = """
SELECT tag_id, name, selector, ignore_click_rage, ignore_dead_click
FROM public.tags
WHERE project_id = %(project_id)s
AND deleted_at IS NULL
"""

with pg_client.PostgresClient() as cur:
query = cur.mogrify(query, {'project_id': project_id})
cur.execute(query)
rows = cur.fetchall()

return helper.list_to_camel_case(rows)


def update_tag(project_id: int, tag_id: int, data: schemas.TagUpdate):
query = """
UPDATE public.tags
SET name = %(name)s
WHERE tag_id = %(tag_id)s AND project_id = %(project_id)s
"""

with pg_client.PostgresClient() as cur:
query = cur.mogrify(query, {'tag_id': tag_id, 'name': data.name, 'project_id': project_id})
cur.execute(query)

return True

def delete_tag(project_id: int, tag_id: int):
query = """
UPDATE public.tags
SET deleted_at = now() at time zone 'utc'
WHERE tag_id = %(tag_id)s AND project_id = %(project_id)s
"""

with pg_client.PostgresClient() as cur:
query = cur.mogrify(query, {'tag_id': tag_id, 'project_id': project_id})
cur.execute(query)

return True
27 changes: 26 additions & 1 deletion api/routers/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
log_tool_stackdriver, reset_password, log_tool_cloudwatch, log_tool_sentry, log_tool_sumologic, log_tools, sessions, \
log_tool_newrelic, announcements, log_tool_bugsnag, weekly_report, integration_jira_cloud, integration_github, \
assist, mobile, tenants, boarding, notifications, webhook, users, \
custom_metrics, saved_search, integrations_global
custom_metrics, saved_search, integrations_global, tags
from chalicelib.core.collaboration_msteams import MSTeams
from chalicelib.core.collaboration_slack import Slack
from or_dependencies import OR_context, OR_role
Expand Down Expand Up @@ -871,3 +871,28 @@ async def check_recording_status(project_id: int):
@public_app.get('/', tags=["health"])
def health_check():
return {}

# tags

@app.post('/{projectId}/tags', tags=["tags"])
def tags_create(projectId: int, data: schemas.TagCreate = Body(), context: schemas.CurrentContext = Depends(OR_context)):
data = tags.create_tag(project_id=projectId, data=data)
return {'data': data}


@app.put('/{projectId}/tags/{tagId}', tags=["tags"])
def tags_update(projectId: int, tagId: int, data: schemas.TagUpdate = Body(), context: schemas.CurrentContext = Depends(OR_context)):
data = tags.update_tag(project_id=projectId, tag_id=tagId, data=data)
return {'data': data}


@app.get('/{projectId}/tags', tags=["tags"])
def tags_list(projectId: int, context: schemas.CurrentContext = Depends(OR_context)):
data = tags.list_tags(project_id=projectId)
return {'data': data}


@app.delete('/{projectId}/tags/{tagId}', tags=["tags"])
def tags_delete(projectId: int, tagId: int, context: schemas.CurrentContext = Depends(OR_context)):
data = tags.delete_tag(projectId, tag_id=tagId)
return {'data': data}
15 changes: 14 additions & 1 deletion api/schemas/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ class EventType(str, Enum):
graphql = "graphql"
state_action = "stateAction"
error = "error"
tag = "tag"
click_ios = "tapIos"
input_ios = "inputIos"
view_ios = "viewIos"
Expand Down Expand Up @@ -606,7 +607,7 @@ class RequestGraphqlFilterSchema(BaseModel):

class SessionSearchEventSchema2(BaseModel):
is_event: Literal[True] = True
value: List[str] = Field(...)
value: List[Union[str, int]] = Field(...)
type: Union[EventType, PerformanceEventType] = Field(...)
operator: Union[SearchEventOperator, ClickEventExtraOperator] = Field(...)
source: Optional[List[Union[ErrorSource, int, str]]] = Field(default=None)
Expand Down Expand Up @@ -1576,3 +1577,15 @@ class ModuleStatus(BaseModel):
"offline-recordings", "alerts", "assist-statts", "recommendations", "feature-flags"] = Field(...,
description="Possible values: assist, notes, bug-reports, offline-recordings, alerts, assist-statts, recommendations, feature-flags")
status: bool = Field(...)


class TagUpdate(BaseModel):
name: str = Field(..., min_length=1, max_length=100, pattern='^[a-zA-Z0-9][a-zA-Z0-9_ -]+$')


class TagCreate(TagUpdate):
selector: str = Field(..., min_length=1, max_length=255)
ignoreClickRage: bool = Field(default=False)
ignoreDeadClick: bool = Field(default=False)


1 change: 1 addition & 0 deletions ee/api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ Pipfile.lock
/chalicelib/core/socket_ios.py
/chalicelib/core/sourcemaps.py
/chalicelib/core/sourcemaps_parser.py
/chalicelib/core/tags.py
/chalicelib/saml
/chalicelib/utils/__init__.py
/chalicelib/utils/args_transformer.py
Expand Down
18 changes: 18 additions & 0 deletions ee/api/chalicelib/core/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ def get_by_session_id(session_id, project_id, group_clickrage=False, event_type:
return rows


def _search_tags(project_id, value, key=None, source=None):
with pg_client.PostgresClient() as cur:
query = f"""
SELECT public.tags.name
'{events.EventType.TAG.ui_type}' AS type
FROM public.tags
WHERE public.tags.project_id = %(project_id)s
ORDER BY SIMILARITY(public.tags.name, %(value)s) DESC
LIMIT 10
"""
query = cur.mogrify(query, {'project_id': project_id, 'value': value})
cur.execute(query)
results = helper.list_to_camel_case(cur.fetchall())
return results


class EventType:
CLICK = Event(ui_type=schemas.EventType.click, table="events.clicks", column="label")
INPUT = Event(ui_type=schemas.EventType.input, table="events.inputs", column="label")
Expand All @@ -112,6 +128,7 @@ class EventType:
REQUEST = Event(ui_type=schemas.EventType.request, table="events_common.requests", column="path")
GRAPHQL = Event(ui_type=schemas.EventType.graphql, table="events.graphql", column="name")
STATEACTION = Event(ui_type=schemas.EventType.state_action, table="events.state_actions", column="name")
TAG = Event(ui_type=schemas.EventType.tag, table="events.tags", column="tag_id")
ERROR = Event(ui_type=schemas.EventType.error, table="events.errors",
column=None) # column=None because errors are searched by name or message
METADATA = Event(ui_type=schemas.FilterType.metadata, table="public.sessions", column=None)
Expand Down Expand Up @@ -145,6 +162,7 @@ class EventType:
EventType.STATEACTION.ui_type: SupportedFilter(get=autocomplete.__generic_autocomplete(EventType.STATEACTION),
query=autocomplete.__generic_query(
typename=EventType.STATEACTION.ui_type)),
EventType.TAG.ui_type: SupportedFilter(get=_search_tags, query=None),
EventType.ERROR.ui_type: SupportedFilter(get=autocomplete.__search_errors,
query=None),
EventType.METADATA.ui_type: SupportedFilter(get=autocomplete.__search_metadata,
Expand Down
3 changes: 2 additions & 1 deletion ee/api/clean-dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ rm -rf ./chalicelib/core/socket_ios.py
rm -rf ./chalicelib/core/sourcemaps.py
rm -rf ./chalicelib/core/sourcemaps_parser.py
rm -rf ./chalicelib/core/user_testing.py
rm -rf ./chalicelib/core/tags.py
rm -rf ./chalicelib/saml
rm -rf ./chalicelib/utils/__init__.py
rm -rf ./chalicelib/utils/args_transformer.py
Expand Down Expand Up @@ -93,4 +94,4 @@ rm -rf ./schemas/overrides.py
rm -rf ./schemas/schemas.py
rm -rf ./schemas/transformers_validators.py
rm -rf ./orpy.py
rm -rf ./chalicelib/core/usability_testing/
rm -rf ./chalicelib/core/usability_testing/
4 changes: 2 additions & 2 deletions ee/scripts/schema/db/init_dbs/postgresql/1.17.0/1.17.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ CREATE TABLE IF NOT EXISTS public.projects_conditions

CREATE TABLE IF NOT EXISTS public.tags
(
tag_id bigint NOT NULL PRIMARY KEY,
tag_id serial NOT NULL PRIMARY KEY,
name text NOT NULL,
project_id integer NOT NULL REFERENCES public.projects (project_id) ON DELETE CASCADE,
selector text NOT NULL,
Expand All @@ -58,7 +58,7 @@ CREATE TABLE IF NOT EXISTS events.tags
session_id bigint NOT NULL REFERENCES public.sessions (session_id) ON DELETE CASCADE,
timestamp bigint NOT NULL,
seq_index integer NOT NULL,
tag_id bigint NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
tag_id integer NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
PRIMARY KEY (session_id, timestamp, seq_index)
);
CREATE INDEX IF NOT EXISTS tags_session_id_idx ON events.tags (session_id);
Expand Down
4 changes: 2 additions & 2 deletions ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,7 @@ $$

CREATE TABLE public.tags
(
tag_id bigint NOT NULL PRIMARY KEY,
tag_id serial NOT NULL PRIMARY KEY,
name text NOT NULL,
project_id integer NOT NULL REFERENCES public.projects (project_id) ON DELETE CASCADE,
selector text NOT NULL,
Expand All @@ -1171,7 +1171,7 @@ $$
session_id bigint NOT NULL REFERENCES public.sessions (session_id) ON DELETE CASCADE,
timestamp bigint NOT NULL,
seq_index integer NOT NULL,
tag_id bigint NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
tag_id integer NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
PRIMARY KEY (session_id, timestamp, seq_index)
);
CREATE INDEX tags_session_id_idx ON events.tags (session_id);
Expand Down
4 changes: 2 additions & 2 deletions scripts/schema/db/init_dbs/postgresql/1.17.0/1.17.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ CREATE TABLE IF NOT EXISTS public.projects_conditions

CREATE TABLE IF NOT EXISTS public.tags
(
tag_id bigint NOT NULL PRIMARY KEY,
tag_id serial NOT NULL PRIMARY KEY,
name text NOT NULL,
project_id integer NOT NULL REFERENCES public.projects (project_id) ON DELETE CASCADE,
selector text NOT NULL,
Expand All @@ -58,7 +58,7 @@ CREATE TABLE IF NOT EXISTS events.tags
session_id bigint NOT NULL REFERENCES public.sessions (session_id) ON DELETE CASCADE,
timestamp bigint NOT NULL,
seq_index integer NOT NULL,
tag_id bigint NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
tag_id integer NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
PRIMARY KEY (session_id, timestamp, seq_index)
);
CREATE INDEX IF NOT EXISTS tags_session_id_idx ON events.tags (session_id);
Expand Down
4 changes: 2 additions & 2 deletions scripts/schema/db/init_dbs/postgresql/init_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ $$

CREATE TABLE public.tags
(
tag_id bigint NOT NULL PRIMARY KEY,
tag_id serial NOT NULL PRIMARY KEY,
name text NOT NULL,
project_id integer NOT NULL REFERENCES public.projects (project_id) ON DELETE CASCADE,
selector text NOT NULL,
Expand All @@ -1132,7 +1132,7 @@ $$
session_id bigint NOT NULL REFERENCES public.sessions (session_id) ON DELETE CASCADE,
timestamp bigint NOT NULL,
seq_index integer NOT NULL,
tag_id bigint NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
tag_id integer NOT NULL REFERENCES public.tags (tag_id) ON DELETE CASCADE,
PRIMARY KEY (session_id, timestamp, seq_index)
);
CREATE INDEX tags_session_id_idx ON events.tags (session_id);
Expand Down

0 comments on commit 97ee6c7

Please sign in to comment.