-module(admin_handler_reviews_by_id). -behaviour(cowboy_handler). -export([init/2]). -export([trails/0]). -include("records.hrl"). %%% cowboy_handler callback init(Req, _Opts) -> case cowboy_req:method(Req) of <<"GET">> -> get_review(Req); <<"PUT">> -> update_review(Req); _ -> handler_utils:send_error(Req, 405, <<"Method not allowed">>) end. %%% Swagger metadata trails() -> BaseParams = [#{ name => <<"id">>, in => <<"path">>, description => <<"Review ID">>, required => true, schema => #{type => string} }], [ #{ % GET by id path => <<"/v1/admin/reviews/:id">>, method => <<"GET">>, description => <<"Get review by ID (admin)">>, tags => [<<"Reviews">>], parameters => BaseParams, responses => #{ 200 => #{ description => <<"Review details">>, content => #{<<"application/json">> => #{schema => review_schema()}} } } }, #{ % PUT update path => <<"/v1/admin/reviews/:id">>, method => <<"PUT">>, description => <<"Update review (admin)">>, tags => [<<"Reviews">>], parameters => BaseParams, requestBody => #{ required => true, content => #{<<"application/json">> => #{schema => review_update_schema()}} }, responses => #{ 200 => #{description => <<"Updated review">>} } } ]. review_schema() -> #{ type => object, properties => #{ id => #{type => string}, user_id => #{type => string}, target_type => #{type => string, enum => [<<"calendar">>, <<"event">>]}, target_id => #{type => string}, rating => #{type => integer, minimum => 1, maximum => 5}, comment => #{type => string}, status => #{type => string, enum => [<<"visible">>, <<"hidden">>, <<"deleted">>]}, reason => #{type => string, nullable => true}, likes => #{type => integer}, dislikes => #{type => integer}, created_at => #{type => string, format => <<"date-time">>}, updated_at => #{type => string, format => <<"date-time">>} } }. review_update_schema() -> #{ type => object, properties => #{ status => #{type => string, enum => [<<"visible">>, <<"hidden">>, <<"deleted">>]}, reason => #{type => string}, comment => #{type => string}, rating => #{type => integer, minimum => 1, maximum => 5} } }. %%% Internal functions get_review(Req) -> case handler_utils:auth_admin(Req) of {ok, _AdminId, Req1} -> ReviewId = cowboy_req:binding(id, Req1), case logic_review:get_review_admin(ReviewId) of {ok, Review} -> handler_utils:send_json(Req1, 200, handler_utils:review_to_json(Review)); {error, not_found} -> handler_utils:send_error(Req1, 404, <<"Review not found">>); {error, _} -> handler_utils:send_error(Req1, 500, <<"Internal server error">>) end; {error, Code, Msg, Req1} -> handler_utils:send_error(Req1, Code, Msg) end. update_review(Req) -> case handler_utils:auth_admin(Req) of {ok, _AdminId, Req1} -> ReviewId = cowboy_req:binding(id, Req1), {ok, Body, Req2} = cowboy_req:read_body(Req1), try jsx:decode(Body, [return_maps]) of UpdatesMap when is_map(UpdatesMap) -> Updates = maps:to_list(UpdatesMap), case logic_review:update_review_admin(ReviewId, Updates) of {ok, Review} -> handler_utils:send_json(Req2, 200, handler_utils:review_to_json(Review)); {error, not_found} -> handler_utils:send_error(Req2, 404, <<"Review not found">>); {error, _} -> handler_utils:send_error(Req2, 500, <<"Internal server error">>) end; _ -> handler_utils:send_error(Req2, 400, <<"Invalid JSON">>) catch _:_ -> handler_utils:send_error(Req1, 400, <<"Invalid JSON format">>) end; {error, Code, Msg, Req1} -> handler_utils:send_error(Req1, Code, Msg) end.