Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8edf113
chore: merge ninja and seeding modules
GuilhermePSF Aug 19, 2025
fb61fba
fix: ninja context
GuilhermePSF Aug 20, 2025
e1fe312
feat: add guardians context
GuilhermePSF Aug 20, 2025
3cc247f
feat: add guardian schema
GuilhermePSF Aug 20, 2025
c3b16fc
feat: guardian migration
GuilhermePSF Aug 20, 2025
9c6eb3a
test: add guardian tests and fixtures
GuilhermePSF Aug 20, 2025
9f07efd
chore: add faker
GuilhermePSF Aug 21, 2025
09dac51
chore: format
GuilhermePSF Aug 21, 2025
fbb6be1
feat: highly improve seeding to better represent users
GuilhermePSF Aug 21, 2025
8fccd78
feat: guardian seeding
GuilhermePSF Aug 21, 2025
f6316ad
fix: typo
GuilhermePSF Aug 21, 2025
f44fef1
feat: guardian ninja relation schema
GuilhermePSF Aug 21, 2025
a90916f
feat: guardian ninja relation migration
GuilhermePSF Aug 21, 2025
3eba2ca
feat: guardian ninja relation context
GuilhermePSF Aug 21, 2025
cad5cff
feat: guardian ninja relation test and fixtures
GuilhermePSF Aug 21, 2025
3f9da8d
feat: create index and define references
GuilhermePSF Aug 21, 2025
8a82228
feat: guardian ninja seeding
GuilhermePSF Aug 21, 2025
09dfbdb
chore: format
GuilhermePSF Aug 21, 2025
a815a22
refactor: improve odds
GuilhermePSF Aug 21, 2025
8c025b0
feat: get guardians by ninja id and ninjas by guardian id.
GuilhermePSF Aug 21, 2025
e992cb8
feat: add guardian_id field to users and fix migration order
GuilhermePSF Aug 21, 2025
803c1c3
feat: remake account seeding to better suit the desired db structure
GuilhermePSF Aug 21, 2025
a1ecf67
Merge branch 'main' into gui/guardian-schemas
GuilhermePSF Sep 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/katana/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ defmodule Katana.Accounts.User do
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id

@registration_fields ~w(name email password)a
@registration_fields ~w(name email guardian_id password)a

@derive {LiveVue.Encoder, except: [:hashed_password, :current_password, :confirmed_at]}
schema "users" do
field :name, :string
field :email, :string

field :guardian_id, :binary_id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
field :guardian_id, :binary_id
has_one, :guardian, Guardian


field :password, :string, virtual: true, redact: true
field :hashed_password, :string, redact: true
field :current_password, :string, virtual: true, redact: true
Expand Down
118 changes: 118 additions & 0 deletions lib/katana/guardians.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
defmodule Katana.Guardians do
@moduledoc """
The Guardians context.
"""

import Ecto.Query, warn: false
alias Katana.Repo
alias Katana.Guardians.Guardian
alias Katana.GuardiansNinjas.GuardianNinja

@doc """
Returns the list of guardians.

## Examples

iex> list_guardians()
[%Guardian{}, ...]

"""
def list_guardians do
Repo.all(Guardian)
end

@doc """
Gets a single guardian.

Raises `Ecto.NoResultsError` if the Guardian does not exist.

## Examples

iex> get_guardian!(123)
%Guardian{}

iex> get_guardian!(456)
** (Ecto.NoResultsError)

"""
def get_guardian!(id), do: Repo.get!(Guardian, id)

@doc """
Creates a guardian.

## Examples

iex> create_guardian(%{field: value})
{:ok, %Guardian{}}

iex> create_guardian(%{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def create_guardian(attrs \\ %{}) do
%Guardian{}
|> Guardian.changeset(attrs)
|> Repo.insert()
end

@doc """
Updates a guardian.

## Examples

iex> update_guardian(guardian, %{field: new_value})
{:ok, %Guardian{}}

iex> update_guardian(guardian, %{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def update_guardian(%Guardian{} = guardian, attrs) do
guardian
|> Guardian.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a guardian.

## Examples

iex> delete_guardian(guardian)
{:ok, %Guardian{}}

iex> delete_guardian(guardian)
{:error, %Ecto.Changeset{}}

"""
def delete_guardian(%Guardian{} = guardian) do
Repo.delete(guardian)
end

@doc """
Returns all Guardians linked to a given Ninja id.
"""
def get_guardians_for_ninja(ninja_id) do
query =
from gn in GuardianNinja,
where: gn.ninja_id == ^ninja_id,
join: g in Guardian,
on: g.id == gn.guardian_id,
select: g

Repo.all(query)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking guardian changes.

## Examples

iex> change_guardian(guardian)
%Ecto.Changeset{data: %Guardian{}}

"""
def change_guardian(%Guardian{} = guardian, attrs \\ %{}) do
Guardian.changeset(guardian, attrs)
end
end
19 changes: 19 additions & 0 deletions lib/katana/guardians/guardian.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Katana.Guardians.Guardian do
use Ecto.Schema
import Ecto.Changeset

@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "guardians" do
field :phone, :string

timestamps(type: :utc_datetime)
end

@doc false
def changeset(guardian, attrs) do
guardian
|> cast(attrs, [:phone])
|> validate_required([:phone])
end
end
104 changes: 104 additions & 0 deletions lib/katana/guardians_ninjas.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
defmodule Katana.GuardiansNinjas do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid creating a context per entity. Read more about contexts and how to use them here.

Copy link
Collaborator Author

@GuilhermePSF GuilhermePSF Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What type or architecture should we adapt? What entities go in which context?

@moduledoc """
The GuardiansNinjas context.
"""

import Ecto.Query, warn: false
alias Katana.Repo

alias Katana.GuardiansNinjas.GuardianNinja

@doc """
Returns the list of guardian_ninja.
## Examples
iex> list_guardian_ninja()
[%GuardianNinja{}, ...]
"""
def list_guardian_ninja do
Repo.all(GuardianNinja)
end

@doc """
Gets a single guardian_ninja.
Raises `Ecto.NoResultsError` if the Guardian ninja does not exist.
## Examples
iex> get_guardian_ninja!(123)
%GuardianNinja{}
iex> get_guardian_ninja!(456)
** (Ecto.NoResultsError)
"""
def get_guardian_ninja!(id), do: Repo.get!(GuardianNinja, id)

@doc """
Creates a guardian_ninja.
## Examples
iex> create_guardian_ninja(%{field: value})
{:ok, %GuardianNinja{}}
iex> create_guardian_ninja(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_guardian_ninja(attrs \\ %{}) do
%GuardianNinja{}
|> GuardianNinja.changeset(attrs)
|> Repo.insert()
end

@doc """
Updates a guardian_ninja.
## Examples
iex> update_guardian_ninja(guardian_ninja, %{field: new_value})
{:ok, %GuardianNinja{}}
iex> update_guardian_ninja(guardian_ninja, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_guardian_ninja(%GuardianNinja{} = guardian_ninja, attrs) do
guardian_ninja
|> GuardianNinja.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a guardian_ninja.
## Examples
iex> delete_guardian_ninja(guardian_ninja)
{:ok, %GuardianNinja{}}
iex> delete_guardian_ninja(guardian_ninja)
{:error, %Ecto.Changeset{}}
"""
def delete_guardian_ninja(%GuardianNinja{} = guardian_ninja) do
Repo.delete(guardian_ninja)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking guardian_ninja changes.
## Examples
iex> change_guardian_ninja(guardian_ninja)
%Ecto.Changeset{data: %GuardianNinja{}}
"""
def change_guardian_ninja(%GuardianNinja{} = guardian_ninja, attrs \\ %{}) do
GuardianNinja.changeset(guardian_ninja, attrs)
end
end
20 changes: 20 additions & 0 deletions lib/katana/guardians_ninjas/guardian_ninja.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule Katana.GuardiansNinjas.GuardianNinja do
use Ecto.Schema
import Ecto.Changeset

@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "guardian_ninja" do
field :ninja_id, :binary_id
field :guardian_id, :binary_id

timestamps(type: :utc_datetime)
end

@doc false
def changeset(guardian_ninja, attrs) do
guardian_ninja
|> cast(attrs, [:ninja_id, :guardian_id])
|> validate_required([:ninja_id, :guardian_id])
end
end
66 changes: 66 additions & 0 deletions lib/katana/ninjas.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
defmodule Katana.Ninjas do
@moduledoc """
The Ninjas context.
"""

import Ecto.Query, warn: false
alias Katana.Repo
alias Katana.Ninjas.Ninja
alias Katana.GuardiansNinjas.GuardianNinja

@doc """
Creates a ninja.
"""
def create_ninja(attrs \\ %{}) do
%Ninja{}
|> Ninja.changeset(attrs)
|> Repo.insert()
end

@doc """
Returns all ninjas.
"""
def list_ninjas do
Repo.all(Ninja)
end

@doc """
Gets a single ninja by ID.
Raises `Ecto.NoResultsError` if not found.
"""
def get_ninja!(id), do: Repo.get!(Ninja, id)

@doc """
Updates a ninja.
"""
def update_ninja(%Ninja{} = ninja, attrs) do
ninja
|> Ninja.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a ninja.
"""
def delete_ninja(%Ninja{} = ninja) do
Repo.delete(ninja)
end

def get_ninjas_for_guardian(guardian_id) do
query =
from gn in GuardianNinja,
where: gn.guardian_id == ^guardian_id,
join: n in Ninja,
on: n.id == gn.ninja_id,
select: n

Repo.all(query)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking ninja changes.
"""
def change_ninja(%Ninja{} = ninja, attrs \\ %{}) do
Ninja.changeset(ninja, attrs)
end
end
Loading