captain-fact icon indicating copy to clipboard operation
captain-fact copied to clipboard

Tags system

Open Betree opened this issue 7 years ago β€’ 0 comments

: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 tags table and model (see migration below)
  • [ ] Create the videos_tags table and model (see migration below)
  • [ ] In apps/cf/lib/tags/tags_manager.ex
    • [ ] Add a createTag function that takes a tag (string), an optional parent_tag_id and creates it in the DB or load it if a tag already exist for this slug. Returns the DB entry. The function must ensure that we never go to deep in the tags hierarchy (tag.depth <= 3)
  • [ ] In apps/cf/lib/videos/videos.ex
    • [ ] Add a setTags function 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 using UserPermissions.check!(user_id, :add, :tags)
  • [ ] In apps/db/lib/db_schema/video.ex
    • [ ] Add tags to the model's schema (many_to_many)
    • [ ] Add a with_tags function that preload tags in the query
  • [ ] In apps/cf_rest_api/lib/channels/video_debate_channel.ex
    • [ ] Preload video's tags with_tags in join
    • [ ] Add a handle_in_authenticated("set_tags", ...) function that sets the tags of the video using Videos.set_tags and broadcast the updated tags on success with broadcast!(socket, "tags_updated", 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 Tag created if it doesn't exist
    • [ ] Returns the existing Tag if it already exist
    • [ ] Fail if parent tag depth is 2 or more
  • [ ] apps/cf/test/videos/videos.ex
    • [ ] setTags associate 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

Betree avatar Oct 27 '18 11:10 Betree