bonfire-app/flavours/cooperation/config/bonfire_data.exs
Mayel de Borniol 0ef85e77f9 auto-format
2022-09-12 16:34:14 +12:00

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,
:bonfire_geolocate
]
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
]
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)