CaptainFact / CaptainFact/captain-fact

Tags system

Open
#14 0 comments 0 reactions 0 assignees View on GitHub
backend complexity > complex feature
Dominant language
No language data
Stars
71
Forks
7
PR merge metrics
No merged PRs in 30d

Description

: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

```elixir
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

```elixir
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
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.