@@ -18,6 +18,17 @@ defmodule Plausible.Annotations do
1818
1919 @ max_annotations 500
2020
21+ @ spec roles_with_personal_annotations ( ) :: [ atom ( ) ]
22+ def roles_with_personal_annotations ( ) , do: @ roles_with_personal_annotations
23+
24+ @ spec roles_with_maybe_site_annotations ( ) :: [ atom ( ) ]
25+ def roles_with_maybe_site_annotations ( ) , do: @ roles_with_maybe_site_annotations
26+
27+ @ spec site_annotations_available? ( Plausible.Site . t ( ) ) :: boolean ( )
28+ def site_annotations_available? ( site ) ,
29+ # this feature is bundled with SiteSegments
30+ do: Plausible.Billing.Feature.SiteSegments . check_availability ( site . team ) == :ok
31+
2132 @ spec get_all_for_site ( Plausible.Site . t ( ) , atom ( ) , User . t ( ) | nil , DateTimeRange . t ( ) ) ::
2233 { :error , error_not_enough_permissions ( ) } | { :ok , list ( Annotation . t ( ) ) }
2334 def get_all_for_site ( site , site_role , user , range_in_site_tz ) do
@@ -67,36 +78,13 @@ defmodule Plausible.Annotations do
6778 end
6879 end
6980
70- defp filter_by_range ( query , range_in_site_tz ) do
71- # Minute granularity annotations are stored for the particular UTC moment they're for,
72- # so they must be in the range of the UTC query period.
73- minute_granularity_range =
74- range_in_site_tz |> DateTimeRange . to_timezone ( "Etc/UTC" )
75-
76- # Date granularity annotations are stored for the UTC midnight of the date they're for,
77- # so the range for querying these must reflect that.
78- [ date_granularity_range_first , date_granularity_range_last ] =
79- [ range_in_site_tz . first , range_in_site_tz . last ]
80- |> Enum . map ( fn utc_datetime ->
81- utc_datetime |> DateTime . to_date ( ) |> Annotation . serialize_date_granularity_datetime ( )
82- end )
83-
84- from ( annotation in query ,
85- where:
86- ( annotation . granularity == :minute and
87- annotation . datetime >= ^ minute_granularity_range . first and
88- annotation . datetime <= ^ minute_granularity_range . last ) or
89- ( annotation . granularity == :date and
90- annotation . datetime >=
91- ^ date_granularity_range_first and
92- annotation . datetime <=
93- ^ date_granularity_range_last )
94- )
95- end
96-
97- @ spec get_one ( User . t ( ) , Plausible.Site . t ( ) , atom ( ) , pos_integer ( ) | nil ) ::
81+ @ spec get_one ( User . t ( ) | nil , Plausible.Site . t ( ) , atom ( ) , pos_integer ( ) | nil ) ::
9882 { :ok , Annotation . t ( ) }
9983 | { :error , error_not_enough_permissions ( ) | error_annotation_not_found ( ) }
84+ def get_one ( nil , _site , _site_role , _annotation_id ) do
85+ { :error , :not_enough_permissions }
86+ end
87+
10088 def get_one ( user , site , site_role , annotation_id ) do
10189 if site_role in roles_with_personal_annotations ( ) do
10290 case do_get_one ( user , site , annotation_id ) do
@@ -108,12 +96,16 @@ defmodule Plausible.Annotations do
10896 end
10997 end
11098
111- @ spec insert_one ( User . t ( ) , Plausible.Site . t ( ) , atom ( ) , map ( ) ) ::
99+ @ spec insert_one ( User . t ( ) | nil , Plausible.Site . t ( ) , atom ( ) , map ( ) ) ::
112100 { :ok , Annotation . t ( ) }
113101 | { :error ,
114102 error_not_enough_permissions ( )
115103 | error_invalid_annotation ( )
116104 | error_annotation_limit_reached ( ) }
105+ def insert_one ( nil , _site , _site_role , _params ) do
106+ { :error , :not_enough_permissions }
107+ end
108+
117109 def insert_one ( user , site , site_role , params ) do
118110 changeset = Annotation . create_changeset ( params , site , user )
119111 annotation_type = Ecto.Changeset . get_field ( changeset , :type )
@@ -130,12 +122,16 @@ defmodule Plausible.Annotations do
130122 end
131123 end
132124
133- @ spec update_one ( User . t ( ) , Plausible.Site . t ( ) , atom ( ) , pos_integer ( ) , map ( ) ) ::
125+ @ spec update_one ( User . t ( ) | nil , Plausible.Site . t ( ) , atom ( ) , pos_integer ( ) , map ( ) ) ::
134126 { :ok , Annotation . t ( ) }
135127 | { :error ,
136128 error_not_enough_permissions ( )
137129 | error_invalid_annotation ( )
138130 | error_annotation_not_found ( ) }
131+ def update_one ( nil , _site , _site_role , _annotation_id , _params ) do
132+ { :error , :not_enough_permissions }
133+ end
134+
139135 def update_one ( user , site , site_role , annotation_id , params ) do
140136 with { :ok , annotation } <- get_one ( user , site , site_role , annotation_id ) ,
141137 changeset = Annotation . update_changeset ( annotation , params , user ) ,
@@ -152,6 +148,31 @@ defmodule Plausible.Annotations do
152148 end
153149 end
154150
151+ @ spec delete_one ( User . t ( ) | nil , Plausible.Site . t ( ) , atom ( ) , pos_integer ( ) ) ::
152+ { :ok , Annotation . t ( ) }
153+ | { :error ,
154+ error_not_enough_permissions ( )
155+ | error_annotation_not_found ( ) }
156+ def delete_one ( nil , _site , _site_role , _annotation_id ) do
157+ { :error , :not_enough_permissions }
158+ end
159+
160+ def delete_one ( user , site , site_role , annotation_id ) do
161+ with { :ok , annotation } <- get_one ( user , site , site_role , annotation_id ) do
162+ cond do
163+ annotation . type == :site and site_role in roles_with_maybe_site_annotations ( ) ->
164+ { :ok , do_delete_one ( annotation ) }
165+
166+ annotation . type == :personal and site_role in roles_with_personal_annotations ( ) ->
167+ { :ok , do_delete_one ( annotation ) }
168+
169+ true ->
170+ { :error , :not_enough_permissions }
171+ end
172+ end
173+ end
174+
175+ @ spec after_user_removed_from_site ( Plausible.Site . t ( ) , User . t ( ) ) :: :ok
155176 def after_user_removed_from_site ( site , user ) do
156177 Repo . delete_all (
157178 from ( annotation in Annotation ,
@@ -170,8 +191,11 @@ defmodule Plausible.Annotations do
170191 ) ,
171192 [ ]
172193 )
194+
195+ :ok
173196 end
174197
198+ @ spec after_user_removed_from_team ( Plausible.Teams.Team . t ( ) , User . t ( ) ) :: :ok
175199 def after_user_removed_from_team ( team , user ) do
176200 team_sites_q =
177201 from (
@@ -199,8 +223,11 @@ defmodule Plausible.Annotations do
199223 ) ,
200224 [ ]
201225 )
226+
227+ :ok
202228 end
203229
230+ @ spec user_removed ( User . t ( ) ) :: :ok
204231 def user_removed ( user ) do
205232 Repo . delete_all (
206233 from ( annotation in Annotation ,
@@ -211,24 +238,37 @@ defmodule Plausible.Annotations do
211238 )
212239
213240 # Site annotations are set to owner=null via ON DELETE SET NULL
241+
242+ :ok
214243 end
215244
216- def delete_one ( user , % Plausible.Site { } = site , site_role , annotation_id ) do
217- with { :ok , annotation } <- get_one ( user , site , site_role , annotation_id ) do
218- cond do
219- annotation . type == :site and site_role in roles_with_maybe_site_annotations ( ) ->
220- { :ok , do_delete_one ( annotation ) }
245+ defp filter_by_range ( query , range_in_site_tz ) do
246+ # Minute granularity annotations are stored for the particular UTC moment they're for,
247+ # so they must be in the range of the UTC query period.
248+ minute_granularity_range =
249+ range_in_site_tz |> DateTimeRange . to_timezone ( "Etc/UTC" )
221250
222- annotation . type == :personal and site_role in roles_with_personal_annotations ( ) ->
223- { :ok , do_delete_one ( annotation ) }
251+ # Date granularity annotations are stored for the UTC midnight of the date they're for,
252+ # so the range for querying these must reflect that.
253+ [ date_granularity_range_first , date_granularity_range_last ] =
254+ [ range_in_site_tz . first , range_in_site_tz . last ]
255+ |> Enum . map ( fn utc_datetime ->
256+ utc_datetime |> DateTime . to_date ( ) |> Annotation . serialize_date_granularity_datetime ( )
257+ end )
224258
225- true ->
226- { :error , :not_enough_permissions }
227- end
228- end
259+ from ( annotation in query ,
260+ where:
261+ ( annotation . granularity == :minute and
262+ annotation . datetime >= ^ minute_granularity_range . first and
263+ annotation . datetime <= ^ minute_granularity_range . last ) or
264+ ( annotation . granularity == :date and
265+ annotation . datetime >=
266+ ^ date_granularity_range_first and
267+ annotation . datetime <=
268+ ^ date_granularity_range_last )
269+ )
229270 end
230271
231- @ spec do_get_one ( User . t ( ) , Plausible.Site . t ( ) , pos_integer ( ) | nil ) :: Annotation . t ( ) | nil
232272 defp do_get_one ( user , site , annotation_id )
233273
234274 defp do_get_one ( _user , _site , nil ) do
@@ -297,11 +337,4 @@ defmodule Plausible.Annotations do
297337 )
298338 |> Repo . aggregate ( :count , :id )
299339 end
300-
301- def roles_with_personal_annotations ( ) , do: @ roles_with_personal_annotations
302- def roles_with_maybe_site_annotations ( ) , do: @ roles_with_maybe_site_annotations
303-
304- def site_annotations_available? ( % Plausible.Site { } = site ) ,
305- # this feature is bundled with SiteSegments
306- do: Plausible.Billing.Feature.SiteSegments . check_availability ( site . team ) == :ok
307340end
0 commit comments