mirror of
https://github.com/bonfire-networks/bonfire-app.git
synced 2024-04-28 23:38:44 +00:00
987 lines
31 KiB
Elixir
987 lines
31 KiB
Elixir
import Config
|
|
|
|
#### Base configuration
|
|
|
|
verbs = [
|
|
"Boost",
|
|
"Create",
|
|
"Delete",
|
|
"Edit",
|
|
"Flag",
|
|
"Follow",
|
|
"Like",
|
|
"Mention",
|
|
"Message",
|
|
"Read",
|
|
"Reply",
|
|
"Request",
|
|
"See",
|
|
"Tag"
|
|
]
|
|
|
|
# Choose password hashing backend
|
|
# Note that this corresponds with our dependencies in mix.exs
|
|
hasher = if config_env() in [:dev, :test], do: Pbkdf2, else: Argon2
|
|
|
|
config :bonfire_data_identity, Bonfire.Data.Identity.Credential, hasher_module: hasher
|
|
|
|
#### Sentinel Data Services
|
|
|
|
# Search these apps/extensions for Pointable ecto schema definitions to index
|
|
pointable_schema_extensions = [
|
|
:bonfire,
|
|
:bonfire_data_access_control,
|
|
:bonfire_data_activity_pub,
|
|
:bonfire_data_identity,
|
|
:bonfire_data_social,
|
|
:bonfire_data_edges,
|
|
:bonfire_tag,
|
|
:bonfire_classify,
|
|
:bonfire_data_shared_users,
|
|
:bonfire_files,
|
|
:bonfire_quantify,
|
|
:bonfire_geolocate,
|
|
:bonfire_valueflows,
|
|
:bonfire_valueflows_observe
|
|
]
|
|
|
|
config :pointers, :search_path, pointable_schema_extensions
|
|
|
|
# Search these apps/extensions for context or queries modules to index (i.e. they contain modules with a queries_module/0 or context_modules/0 function)
|
|
context_and_queries_extensions =
|
|
pointable_schema_extensions ++
|
|
[
|
|
:bonfire_common,
|
|
:bonfire_me,
|
|
:bonfire_social
|
|
]
|
|
|
|
extensions_with_config =
|
|
context_and_queries_extensions ++
|
|
[
|
|
:bonfire_boundaries,
|
|
:bonfire_federate_activitypub,
|
|
:bonfire_search,
|
|
:bonfire_mailer
|
|
]
|
|
|
|
extensions_with_ui =
|
|
extensions_with_config ++
|
|
[
|
|
:bonfire_ui_common,
|
|
:bonfire_ui_me,
|
|
:bonfire_ui_social,
|
|
:bonfire_ui_valueflows,
|
|
:bonfire_ui_coordination,
|
|
:bonfire_ui_breadpub,
|
|
:bonfire_ui_kanban,
|
|
:bonfire_breadpub,
|
|
:bonfire_upcycle,
|
|
:bonfire_recyclapp,
|
|
:bonfire_ui_reflow,
|
|
:rauversion_extension
|
|
]
|
|
|
|
config :bonfire, :verb_names, verbs
|
|
config :bonfire, :context_modules_search_path, context_and_queries_extensions
|
|
config :bonfire, :query_modules_search_path, context_and_queries_extensions
|
|
config :bonfire, :config_modules_search_path, extensions_with_config
|
|
config :bonfire, :ui_modules_search_path, extensions_with_ui
|
|
|
|
# Search these apps/extensions for Verbs to index (i.e. they contain modules with a declare_verbs/0 function)
|
|
config :bonfire_data_access_control,
|
|
search_path: [
|
|
# :bonfire_me,
|
|
:bonfire_boundaries
|
|
|
|
# :bonfire_social,
|
|
# :bonfire,
|
|
]
|
|
|
|
#### Alias modules for readability
|
|
alias Pointers.Pointer
|
|
alias Pointers.Table
|
|
|
|
alias Bonfire.Data.AccessControl.Acl
|
|
alias Bonfire.Data.AccessControl.Circle
|
|
alias Bonfire.Data.AccessControl.Encircle
|
|
alias Bonfire.Data.AccessControl.Controlled
|
|
alias Bonfire.Data.AccessControl.InstanceAdmin
|
|
alias Bonfire.Data.AccessControl.Grant
|
|
alias Bonfire.Data.AccessControl.Verb
|
|
|
|
alias Bonfire.Data.ActivityPub.Actor
|
|
alias Bonfire.Data.ActivityPub.Peer
|
|
alias Bonfire.Data.ActivityPub.Peered
|
|
|
|
alias Bonfire.Boundaries.Permitted
|
|
alias Bonfire.Boundaries.Stereotyped
|
|
|
|
alias Bonfire.Data.Edges.Edge
|
|
alias Bonfire.Data.Edges.EdgeTotal
|
|
|
|
alias Bonfire.Data.Identity.Account
|
|
alias Bonfire.Data.Identity.Accounted
|
|
alias Bonfire.Data.Identity.AuthSecondFactor
|
|
alias Bonfire.Data.Identity.Caretaker
|
|
alias Bonfire.Data.Identity.CareClosure
|
|
alias Bonfire.Data.Identity.Character
|
|
alias Bonfire.Data.Identity.Credential
|
|
alias Bonfire.Data.Identity.Email
|
|
alias Bonfire.Data.Identity.ExtraInfo
|
|
alias Bonfire.Data.Identity.Named
|
|
alias Bonfire.Data.Identity.Self
|
|
alias Bonfire.Data.Identity.Settings
|
|
alias Bonfire.Data.Identity.User
|
|
|
|
alias Bonfire.Data.Social.Activity
|
|
alias Bonfire.Data.Social.APActivity
|
|
alias Bonfire.Data.Social.Article
|
|
alias Bonfire.Data.Social.Block
|
|
alias Bonfire.Data.Social.Bookmark
|
|
alias Bonfire.Data.Social.Boost
|
|
alias Bonfire.Data.Social.Created
|
|
alias Bonfire.Data.Social.Feed
|
|
alias Bonfire.Data.Social.FeedPublish
|
|
alias Bonfire.Data.Social.Flag
|
|
alias Bonfire.Data.Social.Follow
|
|
alias Bonfire.Data.Social.Like
|
|
alias Bonfire.Data.Social.Mention
|
|
alias Bonfire.Data.Social.Message
|
|
alias Bonfire.Data.Social.Post
|
|
alias Bonfire.Data.Social.PostContent
|
|
alias Bonfire.Data.Social.Profile
|
|
alias Bonfire.Data.Social.Replied
|
|
alias Bonfire.Data.Social.Request
|
|
|
|
alias Bonfire.Classify.Category
|
|
alias Bonfire.Geolocate.Geolocation
|
|
alias Bonfire.Files
|
|
alias Bonfire.Files.Media
|
|
alias Bonfire.Tag
|
|
alias Bonfire.Tag.Tagged
|
|
|
|
#### Flexto Stitching
|
|
|
|
## WARNING: This is the flaky magic bit. We use configuration to
|
|
## compile extra stuff into modules. If you add new fields or
|
|
## relations to ecto models in a dependency, you must recompile that
|
|
## dependency for it to show up! You will probably find you need to
|
|
## `rm -Rf _build/*/lib/bonfire_data_*` a lot.
|
|
|
|
mixin = [foreign_key: :id, references: :id]
|
|
|
|
common_assocs = %{
|
|
### Mixins
|
|
|
|
# A summary of an object that can appear in a feed.
|
|
activity: quote(do: has_one(:activity, unquote(Activity), unquote(mixin))),
|
|
# ActivityPub actor information
|
|
actor: quote(do: has_one(:actor, unquote(Actor), unquote(mixin))),
|
|
# Indicates the entity responsible for an activity. Sort of like creator, but transferrable. Used
|
|
# during deletion - when the caretaker is deleted, all their stuff will be too.
|
|
caretaker: quote(do: has_one(:caretaker, unquote(Caretaker), unquote(mixin))),
|
|
# A Character has a unique username and some feeds.
|
|
character: quote(do: has_one(:character, unquote(Character), unquote(mixin))),
|
|
# Indicates the creator of an object
|
|
created: quote(do: has_one(:created, unquote(Created), unquote(mixin))),
|
|
# Used for non-textual interactions such as likes and follows to indicate the other object.
|
|
edge: quote(do: has_one(:edge, unquote(Edge), unquote(mixin))),
|
|
# Adds a name that can appear in the user interface for an object. e.g. for an ACL.
|
|
named: quote(do: has_one(:named, unquote(Named), unquote(mixin))),
|
|
# Adds extra info that can appear in the user interface for an object. e.g. a summary or JSON-encoded data.
|
|
extra_info: quote(do: has_one(:extra_info, unquote(ExtraInfo), unquote(mixin))),
|
|
# Information about the remote instance the object is from, if it is not local.
|
|
peered: quote(do: has_one(:peered, unquote(Peered), unquote(mixin))),
|
|
# Information about the content of posts, e.g. a scrubbed html body
|
|
post_content: quote(do: has_one(:post_content, unquote(PostContent), unquote(mixin))),
|
|
# Information about a user or other object that they wish to make available
|
|
profile: quote(do: has_one(:profile, unquote(Profile), unquote(mixin))),
|
|
# Threading information, for threaded discussions.
|
|
replied: quote(do: has_one(:replied, unquote(Replied), unquote(mixin))),
|
|
# Information that allows the system to identify special system-managed ACLS.
|
|
stereotyped: quote(do: has_one(:stereotyped, unquote(Stereotyped), unquote(mixin))),
|
|
|
|
### Multimixins
|
|
|
|
# Links to access control information for this object.
|
|
controlled: quote(do: has_many(:controlled, unquote(Controlled), unquote(mixin))),
|
|
# Inserts the object into selected feeds.
|
|
feed_publishes: quote(do: has_many(:feed_publishes, unquote(FeedPublish), unquote(mixin))),
|
|
|
|
# Information that this object has some files
|
|
files: quote(do: has_many(:files, unquote(Files), unquote(mixin))),
|
|
# The actual files
|
|
media:
|
|
quote(
|
|
do:
|
|
many_to_many(:media, unquote(Media),
|
|
join_through: unquote(Files),
|
|
unique: true,
|
|
join_keys: [id: :id, media_id: :id],
|
|
on_replace: :delete
|
|
)
|
|
),
|
|
|
|
# Information that this object tagged other objects.
|
|
tagged: quote(do: has_many(:tagged, unquote(Tagged), unquote(mixin))),
|
|
# The actual tags
|
|
tags:
|
|
quote(
|
|
do:
|
|
many_to_many(:tags, unquote(Pointer),
|
|
join_through: unquote(Tagged),
|
|
unique: true,
|
|
join_keys: [id: :id, tag_id: :id],
|
|
on_replace: :delete
|
|
)
|
|
),
|
|
|
|
### Regular has_many associations
|
|
|
|
# The objects which reply to this object.
|
|
direct_replies:
|
|
quote(do: has_many(:direct_replies, unquote(Replied), foreign_key: :reply_to_id)),
|
|
# A recursive view of caretakers of caretakers of... used during deletion.
|
|
care_closure: quote(do: has_many(:care_closure, unquote(CareClosure), foreign_key: :branch_id)),
|
|
# Retrieves activities where we are the object. e.g. if we are a
|
|
# post or a user, this could turn up activities from likes or follows.
|
|
activities:
|
|
quote(do: has_many(:activities, unquote(Activity), foreign_key: :object_id, references: :id)),
|
|
|
|
### Stuff I'm not sure how to categorise yet
|
|
|
|
# Used currently only for requesting to follow a user, but more general
|
|
request: quote(do: has_one(:request, unquote(Request), unquote(mixin)))
|
|
}
|
|
|
|
# retrieves a list of quoted forms suitable for use with unquote_splicing
|
|
common = fn names ->
|
|
for name <- List.wrap(names) do
|
|
with nil <- common_assocs[name],
|
|
do:
|
|
raise(RuntimeError, message: "Expected a common association name, got #{inspect(name)}")
|
|
end
|
|
end
|
|
|
|
edge = common.([:controlled, :activities, :request, :created])
|
|
|
|
edges =
|
|
common.([:controlled, :activities, :request, :created, :caretaker, :activity, :feed_publishes])
|
|
|
|
# first up, pointers could have all the mixins we're using. TODO
|
|
|
|
pointer_mixins =
|
|
common.([
|
|
:activity,
|
|
:actor,
|
|
:caretaker,
|
|
:character,
|
|
:created,
|
|
:edge,
|
|
:named,
|
|
:extra_info,
|
|
:peered,
|
|
:post_content,
|
|
:profile,
|
|
:replied,
|
|
:stereotyped
|
|
])
|
|
|
|
config :pointers, Pointer,
|
|
code:
|
|
(quote do
|
|
@like_ulid "11KES11KET0BE11KEDY0VKN0WS"
|
|
@boost_ulid "300STANN0VNCERESHARESH0VTS"
|
|
@follow_ulid "70110WTHE1EADER1EADER1EADE"
|
|
field(:dummy, :any, virtual: true)
|
|
# pointables
|
|
has_one(:circle, unquote(Circle), foreign_key: :id)
|
|
|
|
many_to_many(:encircle_subjects, Pointer,
|
|
join_through: Encircle,
|
|
join_keys: [circle_id: :id, subject_id: :id]
|
|
)
|
|
|
|
has_one(:permitted, unquote(Permitted), foreign_key: :object_id)
|
|
has_one(:user, unquote(User), foreign_key: :id)
|
|
has_one(:post, unquote(Post), foreign_key: :id)
|
|
has_one(:message, unquote(Message), foreign_key: :id)
|
|
has_one(:category, unquote(Category), foreign_key: :id)
|
|
has_one(:geolocation, unquote(Geolocation), foreign_key: :id)
|
|
# mixins
|
|
unquote_splicing(pointer_mixins)
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :files, :media]))
|
|
# has_many
|
|
unquote_splicing(common.([:activities, :care_closure, :direct_replies, :feed_publishes]))
|
|
|
|
## special things
|
|
# these should go away in future and they should be populated by a single query.
|
|
has_one(:like_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @like_ulid]
|
|
)
|
|
|
|
has_one(:boost_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @boost_ulid]
|
|
)
|
|
|
|
has_one(:follow_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @follow_ulid]
|
|
)
|
|
end)
|
|
|
|
config :pointers, Table, []
|
|
|
|
# now let's weave everything else together for convenience
|
|
# bonfire_data_access_control
|
|
|
|
config :bonfire_data_access_control, Acl,
|
|
code:
|
|
(quote do
|
|
field(:grants_count, :integer, virtual: true)
|
|
field(:controlled_count, :integer, virtual: true)
|
|
# mixins
|
|
unquote_splicing(common.([:caretaker, :named, :extra_info, :stereotyped]))
|
|
|
|
# multimixins
|
|
# unquote_splicing(common.([:controlled]))
|
|
end)
|
|
|
|
config :bonfire_data_access_control, Circle,
|
|
code:
|
|
(quote do
|
|
field(:encircles_count, :integer, virtual: true)
|
|
# mixins
|
|
unquote_splicing(common.([:caretaker, :named, :extra_info, :stereotyped]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled]))
|
|
end)
|
|
|
|
config :bonfire_data_access_control, Controlled, []
|
|
|
|
config :bonfire_data_access_control, Encircle,
|
|
code:
|
|
(quote do
|
|
has_one(:peer, unquote(Peer), foreign_key: :id, references: :subject_id)
|
|
end)
|
|
|
|
config :bonfire_data_access_control, Grant,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
(unquote_splicing(common.([:caretaker])))
|
|
|
|
# multimixins
|
|
# unquote_splicing(common.([:controlled]))
|
|
end)
|
|
|
|
config :bonfire_data_access_control, Verb, []
|
|
|
|
config :bonfire_boundaries, Stereotyped,
|
|
code:
|
|
(quote do
|
|
has_one(:named, unquote(Named), foreign_key: :id, references: :stereotype_id)
|
|
end)
|
|
|
|
# bonfire_data_activity_pub
|
|
|
|
config :bonfire_data_activity_pub, Actor,
|
|
code:
|
|
(quote do
|
|
# hacks
|
|
belongs_to(:character, unquote(Character), foreign_key: :id, define_field: false)
|
|
belongs_to(:user, unquote(User), foreign_key: :id, define_field: false)
|
|
# mixins
|
|
unquote_splicing(common.([:peered]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled]))
|
|
end)
|
|
|
|
config :bonfire_data_activity_pub, Peer, []
|
|
config :bonfire_data_activity_pub, Peered, []
|
|
|
|
# bonfire_data_identity
|
|
|
|
config :bonfire_data_identity, Account,
|
|
code:
|
|
(quote do
|
|
has_one(:credential, unquote(Credential), foreign_key: :id)
|
|
has_one(:email, unquote(Email), foreign_key: :id)
|
|
has_one(:auth_second_factor, unquote(AuthSecondFactor), foreign_key: :id)
|
|
has_one(:settings, unquote(Settings), foreign_key: :id)
|
|
|
|
many_to_many(:users, unquote(User),
|
|
join_through: Accounted,
|
|
join_keys: [account_id: :id, id: :id]
|
|
)
|
|
|
|
# optional
|
|
many_to_many(:shared_users, unquote(User),
|
|
join_through: "bonfire_data_shared_user_accounts",
|
|
join_keys: [account_id: :id, shared_user_id: :id]
|
|
)
|
|
end)
|
|
|
|
config :bonfire_data_identity, Accounted,
|
|
code:
|
|
(quote do
|
|
belongs_to(:user, unquote(User), foreign_key: :id, define_field: false)
|
|
end)
|
|
|
|
config :bonfire_data_identity, Caretaker,
|
|
code:
|
|
(quote do
|
|
has_one(:user, unquote(User), foreign_key: :id, references: :caretaker_id)
|
|
# mixins
|
|
unquote_splicing(common.([:character, :profile]))
|
|
end)
|
|
|
|
config :bonfire_data_identity, Character,
|
|
code:
|
|
(quote do
|
|
@follow_ulid "70110WTHE1EADER1EADER1EADE"
|
|
# mixins
|
|
unquote_splicing(common.([:actor, :peered, :profile]))
|
|
has_one(:user, unquote(User), unquote(mixin))
|
|
has_one(:feed, unquote(Feed), unquote(mixin))
|
|
has_many(:followers, unquote(Follow), foreign_key: :following_id, references: :id)
|
|
has_many(:followed, unquote(Follow), foreign_key: :follower_id, references: :id)
|
|
|
|
has_one(:follow_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @follow_ulid]
|
|
)
|
|
end)
|
|
|
|
config :bonfire_data_identity, Credential,
|
|
code:
|
|
(quote do
|
|
belongs_to(:account, unquote(Account), foreign_key: :id, define_field: false)
|
|
end)
|
|
|
|
config :bonfire_data_identity, Email,
|
|
must_confirm: true,
|
|
code:
|
|
(quote do
|
|
belongs_to(:account, unquote(Account), foreign_key: :id, define_field: false)
|
|
end)
|
|
|
|
config :bonfire_data_identity, Self, []
|
|
|
|
config :bonfire_data_identity, User,
|
|
code:
|
|
(quote do
|
|
@like_ulid "11KES11KET0BE11KEDY0VKN0WS"
|
|
@boost_ulid "300STANN0VNCERESHARESH0VTS"
|
|
@follow_ulid "70110WTHE1EADER1EADER1EADE"
|
|
# mixins
|
|
has_one(:accounted, unquote(Accounted), foreign_key: :id)
|
|
has_one(:instance_admin, unquote(InstanceAdmin), foreign_key: :id, on_replace: :update)
|
|
has_one(:self, unquote(Self), foreign_key: :id)
|
|
has_one(:shared_user, unquote(Bonfire.Data.SharedUser), foreign_key: :id)
|
|
has_one(:settings, unquote(Settings), foreign_key: :id)
|
|
unquote_splicing(common.([:actor, :character, :created, :peered, :profile]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled]))
|
|
# manies
|
|
has_many(:encircles, unquote(Encircle), foreign_key: :subject_id)
|
|
# todo: stop through
|
|
has_many(:creations, through: [:created, :pointer])
|
|
# todo: stop through
|
|
has_many(:posts, through: [:created, :post])
|
|
|
|
has_many(:followers, unquote(Edge),
|
|
foreign_key: :object_id,
|
|
references: :id,
|
|
where: [table_id: @follow_ulid]
|
|
)
|
|
|
|
has_many(:followed, unquote(Edge),
|
|
foreign_key: :subject_id,
|
|
references: :id,
|
|
where: [table_id: @follow_ulid]
|
|
)
|
|
|
|
has_many(:user_activities, unquote(Activity), foreign_key: :subject_id, references: :id)
|
|
|
|
has_many(:boost_activities, unquote(Edge),
|
|
foreign_key: :subject_id,
|
|
references: :id,
|
|
where: [table_id: @boost_ulid]
|
|
)
|
|
|
|
has_many(:like_activities, unquote(Edge),
|
|
foreign_key: :subject_id,
|
|
references: :id,
|
|
where: [table_id: @like_ulid]
|
|
)
|
|
|
|
many_to_many(:caretaker_accounts, unquote(Account),
|
|
join_through: "bonfire_data_shared_user_accounts",
|
|
join_keys: [shared_user_id: :id, account_id: :id]
|
|
)
|
|
|
|
# has_many :account, through: [:accounted, :account] # this is private info, do not expose
|
|
# has_one :geolocation, Bonfire.Geolocate.Geolocation # enable if using Geolocate extension
|
|
end)
|
|
|
|
config :bonfire_data_identity, Named, []
|
|
config :bonfire_data_identity, ExtraInfo, []
|
|
|
|
### bonfire_data_social
|
|
|
|
config :bonfire_data_social, Activity,
|
|
code:
|
|
(quote do
|
|
@like_ulid "11KES11KET0BE11KEDY0VKN0WS"
|
|
@boost_ulid "300STANN0VNCERESHARESH0VTS"
|
|
@follow_ulid "70110WTHE1EADER1EADER1EADE"
|
|
has_many(:feed_publishes, unquote(FeedPublish), unquote(mixin))
|
|
has_one(:seen, unquote(Edge), foreign_key: :object_id, references: :id)
|
|
# ugly workaround needed for certain queries (TODO: check if still needed)
|
|
has_one(:activity, unquote(Activity), foreign_key: :id, references: :id)
|
|
# mixins linked to the object rather than the activity:
|
|
has_one(:created, unquote(Created), foreign_key: :id, references: :object_id)
|
|
has_one(:replied, unquote(Replied), foreign_key: :id, references: :object_id)
|
|
field(:path, EctoMaterializedPath.ULIDs, virtual: true)
|
|
|
|
has_one(:like_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :object_id,
|
|
where: [table_id: @like_ulid]
|
|
)
|
|
|
|
has_one(:boost_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :object_id,
|
|
where: [table_id: @boost_ulid]
|
|
)
|
|
|
|
has_one(:follow_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :object_id,
|
|
where: [table_id: @follow_ulid]
|
|
)
|
|
|
|
has_many(:controlled, unquote(Controlled), foreign_key: :id, references: :object_id)
|
|
has_many(:tagged, unquote(Tagged), foreign_key: :id, references: :object_id)
|
|
|
|
many_to_many(:tags, unquote(Pointer),
|
|
join_through: unquote(Tagged),
|
|
unique: true,
|
|
join_keys: [id: :object_id, tag_id: :id],
|
|
on_replace: :delete
|
|
)
|
|
|
|
has_many(:files, unquote(Files), foreign_key: :id, references: :object_id)
|
|
|
|
many_to_many(:media, unquote(Media),
|
|
join_through: unquote(Files),
|
|
unique: true,
|
|
join_keys: [id: :object_id, media_id: :id],
|
|
on_replace: :delete
|
|
)
|
|
end)
|
|
|
|
config :bonfire_data_social, APActivity,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(common.([:activity, :caretaker, :controlled])))
|
|
end)
|
|
|
|
config :bonfire_data_edges, Edge,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edge))
|
|
|
|
# TODO: requires composite foreign keys:
|
|
# has_one :activity, unquote(Activity),
|
|
# foreign_key: [:table_id, :object_id], references: [:table_id, :object_id]
|
|
end)
|
|
|
|
config :bonfire_data_social, Feed,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
(unquote_splicing(common.([:activity, :caretaker])))
|
|
|
|
# belongs_to :character, unquote(Character), foreign_key: :id, define_field: false
|
|
# belongs_to :user, unquote(User), foreign_key: :id, define_field: false
|
|
end)
|
|
|
|
config :bonfire_data_social, FeedPublish,
|
|
code:
|
|
(quote do
|
|
field(:dummy, :any, virtual: true)
|
|
has_one(:activity, unquote(Activity), foreign_key: :object_id, references: :id)
|
|
|
|
# belongs_to :character, unquote(Character), foreign_key: :id, define_field: false
|
|
# belongs_to :user, unquote(User), foreign_key: :id, define_field: false
|
|
end)
|
|
|
|
config :bonfire_data_social, Follow,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edges))
|
|
end)
|
|
|
|
# belongs_to: [follower_character: {Character, foreign_key: :follower_id, define_field: false}],
|
|
# belongs_to: [follower_profile: {Profile, foreign_key: :follower_id, define_field: false}],
|
|
# belongs_to: [followed_character: {Character, foreign_key: :followed_id, define_field: false}],
|
|
# belongs_to: [followed_profile: {Profile, foreign_key: :followed_id, define_field: false}]
|
|
|
|
config :bonfire_data_social, Block,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edges))
|
|
end)
|
|
|
|
config :bonfire_data_social, Boost,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edges))
|
|
end)
|
|
|
|
# has_one: [activity: {Activity, foreign_key: :object_id, references: :boosted_id}] # requires an ON clause
|
|
|
|
config :bonfire_data_social, Like,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edges))
|
|
end)
|
|
|
|
# has_one: [activity: {Activity, foreign_key: :object_id, references: :liked_id}] # requires an ON clause
|
|
|
|
config :bonfire_data_social, Flag,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edges))
|
|
end)
|
|
|
|
config :bonfire_data_social, Request,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edges))
|
|
end)
|
|
|
|
config :bonfire_data_social, Bookmark,
|
|
code:
|
|
(quote do
|
|
(unquote_splicing(edges))
|
|
end)
|
|
|
|
config :bonfire_data_social, Message,
|
|
code:
|
|
(quote do
|
|
@like_ulid "11KES11KET0BE11KEDY0VKN0WS"
|
|
@boost_ulid "300STANN0VNCERESHARESH0VTS"
|
|
# mixins
|
|
unquote_splicing(
|
|
common.([:activity, :caretaker, :created, :peered, :post_content, :replied])
|
|
)
|
|
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :feed_publishes, :tagged, :tags, :files, :media]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
# special
|
|
has_one(:like_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @like_ulid]
|
|
)
|
|
|
|
has_one(:boost_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @boost_ulid]
|
|
)
|
|
end)
|
|
|
|
config :bonfire_data_social, Mention, []
|
|
|
|
config :bonfire_data_social, Post,
|
|
code:
|
|
(quote do
|
|
@like_ulid "11KES11KET0BE11KEDY0VKN0WS"
|
|
@boost_ulid "300STANN0VNCERESHARESH0VTS"
|
|
# mixins
|
|
unquote_splicing(
|
|
common.([:activities, :activity, :caretaker, :created, :peered, :post_content, :replied])
|
|
)
|
|
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :files, :media, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
# special
|
|
has_one(:permitted, unquote(Permitted), foreign_key: :object_id)
|
|
# has_one: [creator_user: {[through: [:created, :creator_user]]}],
|
|
# has_one: [creator_character: {[through: [:created, :creator_character]]}],
|
|
# has_one: [creator_profile: {[through: [:created, :creator_profile]]}],
|
|
# has_one :activity, unquote(Activity), foreign_key: :object_id, references: :id # requires an ON clause
|
|
# has_one: [reply_to: {[through: [:replied, :reply_to]]}],
|
|
# has_one: [reply_to_post: {[through: [:replied, :reply_to_post]]}],
|
|
# has_one: [reply_to_post_content: {[through: [:replied, :reply_to_post_content]]}],
|
|
# has_one: [reply_to_creator_character: {[through: [:replied, :reply_to_creator_character]]}],
|
|
# has_one: [reply_to_creator_profile: {[through: [:replied, :reply_to_creator_profile]]}],
|
|
# has_one: [thread_post: {[through: [:replied, :thread_post]]}],
|
|
# has_one: [thread_post_content: {[through: [:replied, :thread_post_content]]}],
|
|
has_one(:like_count, unquote(EdgeTotal),
|
|
references: :id,
|
|
foreign_key: :id,
|
|
where: [table_id: @like_ulid]
|
|
)
|
|
|
|
has_one(:boost_count, unquote(EdgeTotal),
|
|
references: :id,
|
|
foreign_key: :id,
|
|
where: [table_id: @boost_ulid]
|
|
)
|
|
end)
|
|
|
|
config :bonfire_data_social, PostContent,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:created]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled]))
|
|
# virtuals for changesets
|
|
field(:hashtags, {:array, :any}, virtual: true)
|
|
field(:mentions, {:array, :any}, virtual: true)
|
|
field(:urls, {:array, :any}, virtual: true)
|
|
end)
|
|
|
|
config :bonfire_data_social, Replied,
|
|
code:
|
|
(quote do
|
|
# multimixins - shouldn't be here really
|
|
unquote_splicing(common.([:controlled]))
|
|
|
|
@like_ulid "11KES11KET0BE11KEDY0VKN0WS"
|
|
@boost_ulid "300STANN0VNCERESHARESH0VTS"
|
|
belongs_to(:post, unquote(Post), foreign_key: :id, define_field: false)
|
|
belongs_to(:post_content, unquote(PostContent), foreign_key: :id, define_field: false)
|
|
has_one(:activity, unquote(Activity), foreign_key: :object_id, references: :id)
|
|
# used in changesets
|
|
field(:replying_to, :map, virtual: true)
|
|
has_one(:reply_to_post, unquote(Post), foreign_key: :id, references: :reply_to_id)
|
|
|
|
has_one(:reply_to_post_content, unquote(PostContent),
|
|
foreign_key: :id,
|
|
references: :reply_to_id
|
|
)
|
|
|
|
has_one(:reply_to_created, unquote(Created), foreign_key: :id, references: :reply_to_id)
|
|
# has_one :reply_to_creator_user, through: [:reply_to_created, :creator_user]
|
|
# has_one :reply_to_creator_character, through: [:reply_to_created, :creator_character]
|
|
# has_one :reply_to_creator_profile, through: [:reply_to_created, :creator_profile]
|
|
has_many(:direct_replies, unquote(Replied), foreign_key: :reply_to_id, references: :id)
|
|
has_many(:thread_replies, unquote(Replied), foreign_key: :thread_id, references: :id)
|
|
has_one(:thread_post, unquote(Post), foreign_key: :id, references: :thread_id)
|
|
|
|
has_one(:thread_post_content, unquote(PostContent),
|
|
foreign_key: :id,
|
|
references: :thread_id
|
|
)
|
|
|
|
has_one(:like_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @like_ulid]
|
|
)
|
|
|
|
has_one(:boost_count, unquote(EdgeTotal),
|
|
foreign_key: :id,
|
|
references: :id,
|
|
where: [table_id: @boost_ulid]
|
|
)
|
|
end)
|
|
|
|
config :bonfire_data_social, Created,
|
|
code:
|
|
(quote do
|
|
belongs_to(:creator_user, unquote(User), foreign_key: :creator_id, define_field: false)
|
|
|
|
belongs_to(:creator_character, unquote(Character),
|
|
foreign_key: :creator_id,
|
|
define_field: false
|
|
)
|
|
|
|
belongs_to(:creator_profile, unquote(Profile),
|
|
foreign_key: :creator_id,
|
|
define_field: false
|
|
)
|
|
|
|
# mixins - shouldn't be here really
|
|
unquote_splicing(common.([:peered]))
|
|
# huh?
|
|
has_one(:post, unquote(Post), unquote(mixin))
|
|
end)
|
|
|
|
config :bonfire_data_social, Profile,
|
|
code:
|
|
(quote do
|
|
belongs_to(:user, unquote(User), foreign_key: :id, define_field: false)
|
|
# multimixins - shouldn't be here really
|
|
unquote_splicing(common.([:controlled]))
|
|
end)
|
|
|
|
######### other extensions
|
|
|
|
config :bonfire_files, Media,
|
|
code:
|
|
(quote do
|
|
field(:url, :string, virtual: true)
|
|
# multimixins - shouldn't be here really
|
|
unquote_splicing(common.([:controlled]))
|
|
end)
|
|
|
|
config :bonfire_tag, Tagged,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
(unquote_splicing(common.([:activity])))
|
|
end)
|
|
|
|
config :bonfire_classify, Category,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
# TODO :caretaker
|
|
unquote_splicing(common.([:activity, :created, :actor, :peered, :profile, :character]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :feed_publishes]))
|
|
|
|
has_one(:creator, through: [:created, :creator])
|
|
|
|
# add references of tagged objects to any Category
|
|
many_to_many(:tags, unquote(Pointer),
|
|
join_through: unquote(Tagged),
|
|
unique: true,
|
|
join_keys: [tag_id: :id, id: :id],
|
|
on_replace: :delete
|
|
)
|
|
end)
|
|
|
|
config :bonfire_geolocate, Bonfire.Geolocate.Geolocation,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(
|
|
common.([:activity, :caretaker, :created, :actor, :peered, :profile, :character])
|
|
)
|
|
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.EconomicEvent,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
# TODO :caretaker
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.EconomicResource,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.Knowledge.ResourceSpecification,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.Process,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.Knowledge.ProcessSpecification,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.Planning.Intent,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.Planning.Commitment,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows, ValueFlows.Proposal,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|
|
|
|
config :bonfire_valueflows_observe, ValueFlows.Observe.Observation,
|
|
code:
|
|
(quote do
|
|
# mixins
|
|
unquote_splicing(common.([:activity, :caretaker, :peered, :replied]))
|
|
# multimixins
|
|
unquote_splicing(common.([:controlled, :tagged, :tags, :feed_publishes]))
|
|
# has
|
|
unquote_splicing(common.([:direct_replies]))
|
|
end)
|