ratemyclient/lib/my_first_elixir_vibe_code/accounts.ex
Kevin Sivic 9ece312442 Initial commit: RateMyClient™ Phoenix application
Features:
- User registration and authentication with email/password
- Admin login with username-based authentication (separate from regular users)
- Review system for contractors to rate clients
- Star rating system with review forms
- Client identification with private data protection
- Contractor registration with document verification
- Admin dashboard for review management
- Contact form (demo, non-functional)
- Responsive navigation with DaisyUI components
- Docker Compose setup for production deployment
- PostgreSQL database with Ecto migrations
- High Vis color scheme (dark background with safety orange/green)

Admin credentials: username: admin, password: admin123

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:30:50 -05:00

337 lines
6.4 KiB
Elixir

defmodule MyFirstElixirVibeCode.Accounts do
@moduledoc """
The Accounts context.
"""
import Ecto.Query, warn: false
alias MyFirstElixirVibeCode.Repo
alias MyFirstElixirVibeCode.Accounts.Client
@doc """
Returns the list of clients.
## Examples
iex> list_clients()
[%Client{}, ...]
"""
def list_clients do
Repo.all(Client)
end
@doc """
Gets a single client.
Raises `Ecto.NoResultsError` if the Client does not exist.
## Examples
iex> get_client!(123)
%Client{}
iex> get_client!(456)
** (Ecto.NoResultsError)
"""
def get_client!(id), do: Repo.get!(Client, id)
@doc """
Creates a client.
## Examples
iex> create_client(%{field: value})
{:ok, %Client{}}
iex> create_client(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_client(attrs) do
%Client{}
|> Client.changeset(attrs)
|> Repo.insert()
end
@doc """
Updates a client.
## Examples
iex> update_client(client, %{field: new_value})
{:ok, %Client{}}
iex> update_client(client, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_client(%Client{} = client, attrs) do
client
|> Client.changeset(attrs)
|> Repo.update()
end
@doc """
Deletes a client.
## Examples
iex> delete_client(client)
{:ok, %Client{}}
iex> delete_client(client)
{:error, %Ecto.Changeset{}}
"""
def delete_client(%Client{} = client) do
Repo.delete(client)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking client changes.
## Examples
iex> change_client(client)
%Ecto.Changeset{data: %Client{}}
"""
def change_client(%Client{} = client, attrs \\ %{}) do
Client.changeset(client, attrs)
end
alias MyFirstElixirVibeCode.Accounts.Contractor
@doc """
Returns the list of contractors.
## Examples
iex> list_contractors()
[%Contractor{}, ...]
"""
def list_contractors do
Repo.all(Contractor)
end
@doc """
Gets a single contractor.
Raises `Ecto.NoResultsError` if the Contractor does not exist.
## Examples
iex> get_contractor!(123)
%Contractor{}
iex> get_contractor!(456)
** (Ecto.NoResultsError)
"""
def get_contractor!(id), do: Repo.get!(Contractor, id)
@doc """
Creates a contractor.
## Examples
iex> create_contractor(%{field: value})
{:ok, %Contractor{}}
iex> create_contractor(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_contractor(attrs) do
%Contractor{}
|> Contractor.changeset(attrs)
|> Repo.insert()
end
@doc """
Updates a contractor.
## Examples
iex> update_contractor(contractor, %{field: new_value})
{:ok, %Contractor{}}
iex> update_contractor(contractor, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_contractor(%Contractor{} = contractor, attrs) do
contractor
|> Contractor.changeset(attrs)
|> Repo.update()
end
@doc """
Deletes a contractor.
## Examples
iex> delete_contractor(contractor)
{:ok, %Contractor{}}
iex> delete_contractor(contractor)
{:error, %Ecto.Changeset{}}
"""
def delete_contractor(%Contractor{} = contractor) do
Repo.delete(contractor)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking contractor changes.
## Examples
iex> change_contractor(contractor)
%Ecto.Changeset{data: %Contractor{}}
"""
def change_contractor(%Contractor{} = contractor, attrs \\ %{}) do
Contractor.changeset(contractor, attrs)
end
@doc """
Registers a new contractor with required documents.
## Examples
iex> register_contractor(%{field: value})
{:ok, %Contractor{}}
iex> register_contractor(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def register_contractor(attrs) do
%Contractor{}
|> Contractor.registration_changeset(attrs)
|> Repo.insert()
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking contractor registration changes.
## Examples
iex> change_contractor_registration(contractor)
%Ecto.Changeset{data: %Contractor{}}
"""
def change_contractor_registration(%Contractor{} = contractor, attrs \\ %{}) do
Contractor.registration_changeset(contractor, attrs)
end
alias MyFirstElixirVibeCode.Accounts.User
@doc """
Returns the list of users.
"""
def list_users do
Repo.all(User)
end
@doc """
Gets a single user.
Raises `Ecto.NoResultsError` if the User does not exist.
"""
def get_user!(id), do: Repo.get!(User, id)
@doc """
Gets a user by email.
"""
def get_user_by_email(email) when is_binary(email) do
Repo.get_by(User, email: email)
end
@doc """
Gets a user by email and password.
"""
def get_user_by_email_and_password(email, password)
when is_binary(email) and is_binary(password) do
user = Repo.get_by(User, email: email)
if User.valid_password?(user, password), do: user
end
@doc """
Gets a user by username and password (for admin login).
"""
def get_user_by_username_and_password(username, password)
when is_binary(username) and is_binary(password) do
user = Repo.get_by(User, username: username)
if user && user.is_admin && User.valid_password?(user, password), do: user
end
@doc """
Creates a user.
## Examples
iex> create_user(%{field: value})
{:ok, %User{}}
iex> create_user(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_user(attrs \\ %{}) do
%User{}
|> User.changeset(attrs)
|> Repo.insert()
end
@doc """
Updates a user.
## Examples
iex> update_user(user, %{field: new_value})
{:ok, %User{}}
iex> update_user(user, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_user(%User{} = user, attrs) do
user
|> User.changeset(attrs)
|> Repo.update()
end
@doc """
Deletes a user.
## Examples
iex> delete_user(user)
{:ok, %User{}}
iex> delete_user(user)
{:error, %Ecto.Changeset{}}
"""
def delete_user(%User{} = user) do
Repo.delete(user)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking user changes.
## Examples
iex> change_user(user)
%Ecto.Changeset{data: %User{}}
"""
def change_user(%User{} = user, attrs \\ %{}) do
User.changeset(user, attrs)
end
end