asobi_ops_notifications (asobi v0.84.0)

View Source

The notifications screen: the sent-notification list, and the operator-attributed broadcast.

query/1 is the read half and it is a route, tagged read like every other list here. It answers the question a broadcast raises and nothing else could: which players actually received the last send, and how many of them have opened it.

broadcast/5 is the mutation half, moved into core so the audit wraps it rather than the handler remembering to. The console keeps parsing, deduplicating and capping the recipient list - those are presentation concerns - and calls this for the part that changes player state.

broadcast/5 is deliberately not a route. The ops plane is read-only and this does not change that; it is the Erlang entry point the existing console mutation calls, which is what lets {ok, Succeeded, Failed} reach an audit row instead of being flattened into a list of survivors on the way out.

Because it has no route, it gets no route-level capability check either - so the check happens inside it, through the same asobi_ops_caps:authorised/2 the router's security callback uses. One function still authorises; it is simply called from the entry point an in-process caller actually reaches.

Summary

Functions

Send Subject to every id in PlayerIds as Actor, and audit the result.

Positive allowlist of the fields a notification may carry off this endpoint.

Wire-name to column mapping this endpoint accepts in ?sort=.

Functions

broadcast/5

-spec broadcast(asobi_ops_auth:actor(), binary(), binary(), map(), [binary()]) ->
                   asobi_ops_audit:outcome().

Send Subject to every id in PlayerIds as Actor, and audit the result.

Returns the widened outcome unchanged, so a caller can report exactly what happened. The audit row is written whatever the outcome, including the all-failed case and the refusal.

project(Notification)

-spec project(map()) -> map().

Positive allowlist of the fields a notification may carry off this endpoint.

content stays. It is the body of a message an operator or the game sent, and the same field the receiving player already reads back from asobi_notification_controller:index/1; a send-history screen that cannot show what was sent cannot answer the one question it exists for.

query(Params)

-spec query(asobi_ops_params:params()) ->
               {ok,
                #kura_query{from :: atom() | module() | undefined,
                            select :: [atom() | term()] | {exprs, [term()]},
                            wheres :: [term()],
                            joins :: [term()],
                            order_bys :: [term()],
                            group_bys :: [atom()],
                            havings :: [term()],
                            limit :: non_neg_integer() | undefined,
                            offset :: non_neg_integer() | undefined,
                            distinct :: boolean() | [atom()],
                            lock :: binary() | undefined,
                            prefix :: binary() | undefined,
                            preloads :: [atom() | {atom(), list()}],
                            ctes :: [{binary(), #kura_query{}}],
                            combinations :: [{union | union_all | intersect | except, #kura_query{}}],
                            include_deleted :: boolean()}} |
               {error,
                {unknown_sort, binary()} | {unknown_order, binary()} | {invalid_filter, binary()}}.

sortable()

-spec sortable() -> asobi_ops_params:sort_allowlist().

Wire-name to column mapping this endpoint accepts in ?sort=.