captain-fact
captain-fact copied to clipboard
Tags system
:warning: This needs to be updated: a tag can have multiple ~~parents~~ related tags.
Users need to be able to associate tags to videos. Tags are meant to be reused in the future for other content types, or for users to indicate their expertises.
Examples of possible tags: Geopolitics, Cyber-security, Nuclear energy, French Politics
They should also include an optional parent_tag to create a hierarchy - however limited to 3 levels:
βββ Energy
β βββ Nuclear energy
β β βββ Nuclear fission
β β βββ Nuclear fusion
To provide an initial dataset, we should use the WikipΓ©dia categories.
TODO
Features
- [ ] Create the
tagstable and model (see migration below) - [ ] Create the
videos_tagstable and model (see migration below) - [ ] In
apps/cf/lib/tags/tags_manager.ex- [ ] Add a
createTagfunction that takes a tag (string), an optionalparent_tag_idand creates it in the DB or load it if a tag already exist for thisslug. Returns the DB entry. The function must ensure that we never go to deep in the tags hierarchy (tag.depth <= 3)
- [ ] Add a
- [ ] In
apps/cf/lib/videos/videos.ex- [ ] Add a
setTagsfunction that create or load the tags and associate them to the video. The function takes a user, a video and a list of tags. It must also ensure that users has the right permissions by usingUserPermissions.check!(user_id, :add, :tags)
- [ ] Add a
- [ ] In
apps/db/lib/db_schema/video.ex- [ ] Add tags to the model's
schema(many_to_many) - [ ] Add a
with_tagsfunction that preload tags in the query
- [ ] Add tags to the model's
- [ ] In
apps/cf_rest_api/lib/channels/video_debate_channel.ex- [ ] Preload video's tags
with_tagsinjoin - [ ] Add a
handle_in_authenticated("set_tags", ...)function that sets the tags of the video usingVideos.set_tagsand broadcast the updated tags on success withbroadcast!(socket, "tags_updated", tags)
- [ ] Preload video's tags
Expected tests
- [ ]
apps/db/test/db_schema/tag.ex- [ ] Slug's length must be >= 1
- [ ]
apps/cf/test/tags/tags_manager.ex- [ ] Returns the
Tagcreated if it doesn't exist - [ ] Returns the existing
Tagif it already exist - [ ] Fail if parent tag depth is
2or more
- [ ] Returns the
- [ ]
apps/cf/test/videos/videos.ex- [ ]
setTagsassociate the given tags to the video and returns it - [ ]
setTags(user, video, nil)removes all the tags for the video - [ ]
setTags(user, video, [])removes all the tags for the video
- [ ]
Resources
Tags migration
defmodule DB.Repo.Migrations.CreateTags do
use Ecto.Migration
def change do
create table(:tags) do
add(:slug, :string, null: false)
add(:depth, :integer, default: 0, null: false)
add(:parent_id, references(:tags, on_delete: :nilify_all), null: true)
add(:wikidata_category_id, :string, null: true)
timestamps()
end
create(unique_index(:tags, [:slug]))
end
end
VideosTags migration
defmodule DB.Repo.Migrations.VideosTags do
use Ecto.Migration
def change do
create table(:videos_tags) do
add(:video_id, references(:videos, on_delete: :delete_all), null: false)
add(:tag_id, references(:tags, on_delete: :delete_all), null: false)
timestamps()
end
create(unique_index(:tags, [:tag_id, :video_id]))
end
end