Skip to content

Commit

Permalink
Init Ash resources (#1)
Browse files Browse the repository at this point in the history
* init

* migration

* fix test

* style auth page
  • Loading branch information
yujonglee authored Jun 22, 2024
1 parent 8170b6a commit ab75f74
Show file tree
Hide file tree
Showing 42 changed files with 1,339 additions and 228 deletions.
10 changes: 9 additions & 1 deletion core/.formatter.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
[
import_deps: [:ecto, :ecto_sql, :phoenix],
import_deps: [
:ecto,
:ecto_sql,
:phoenix,
:ash,
:ash_phoenix,
:ash_postgres,
:ash_authentication
],
subdirectories: ["priv/*/migrations"],
plugins: [Phoenix.LiveView.HTMLFormatter],
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"]
Expand Down
3 changes: 2 additions & 1 deletion core/assets/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ module.exports = {
content: [
"./js/**/*.js",
"../lib/canary_web.ex",
"../lib/canary_web/**/*.*ex"
"../lib/canary_web/**/*.*ex",
"../deps/ash_authentication_phoenix/**/*.*ex",
],
theme: {
extend: {
Expand Down
9 changes: 9 additions & 0 deletions core/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ config :canary, Oban,
queues: [default: 10],
repo: Canary.Repo

config :canary, Canary.Repo, types: Canary.PostgrexTypes

config :canary,
ash_domains: [
Canary.Accounts,
Canary.Sources,
Canary.Clients
]

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"
41 changes: 41 additions & 0 deletions core/lib/canary/accounts/account.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
defmodule Canary.Accounts.Account do
use Ash.Resource,
domain: Canary.Accounts,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key :id

attribute :user_id, :uuid do
allow_nil? false
end

attribute :name, :string do
allow_nil? false
end
end

relationships do
many_to_many :users, Canary.Accounts.User do
through Canary.Accounts.AccountUser
end

has_many :source_websites, Canary.Sources.Website
has_many :client_websites, Canary.Clients.Website
end

actions do
create :create do
accept [:user_id, :name]
end

update :update do
accept [:name]
end
end

postgres do
table "accounts"
repo Canary.Repo
end
end
19 changes: 19 additions & 0 deletions core/lib/canary/accounts/account_user.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Canary.Accounts.AccountUser do
use Ash.Resource,
domain: Canary.Accounts,
data_layer: AshPostgres.DataLayer

relationships do
belongs_to :user, Canary.Accounts.User, primary_key?: true, allow_nil?: false
belongs_to :account, Canary.Accounts.Account, primary_key?: true, allow_nil?: false
end

actions do
defaults [:read, :destroy, create: :*, update: :*]
end

postgres do
table "account_users"
repo Canary.Repo
end
end
10 changes: 10 additions & 0 deletions core/lib/canary/accounts/accounts.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule Canary.Accounts do
use Ash.Domain

resources do
resource Canary.Accounts.User
resource Canary.Accounts.Token
resource Canary.Accounts.Account
resource Canary.Accounts.AccountUser
end
end
17 changes: 17 additions & 0 deletions core/lib/canary/accounts/changes/init_account.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Canary.Accounts.Changes.InitAccount do
use Ash.Resource.Change

@default_account_name "Default"

@impl true
def change(changeset, _, _) do
Ash.Changeset.after_action(changeset, fn _, user ->
case Canary.Accounts.Account
|> Ash.Changeset.for_create(:create, %{user_id: user.id, name: @default_account_name})
|> Ash.create() do
{:ok, _} -> {:ok, user}
error -> error
end
end)
end
end
10 changes: 10 additions & 0 deletions core/lib/canary/accounts/secrets.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule Canary.Accounts.Secrets do
use AshAuthentication.Secret

def secret_for([:authentication, :tokens, :signing_secret], Canary.Accounts.User, _) do
case Application.fetch_env(:canary, CanaryWeb.Endpoint) do
{:ok, endpoint_config} -> Keyword.fetch(endpoint_config, :secret_key_base)
:error -> :error
end
end
end
11 changes: 11 additions & 0 deletions core/lib/canary/accounts/token.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule Canary.Accounts.Token do
use Ash.Resource,
domain: Canary.Accounts,
data_layer: AshPostgres.DataLayer,
extensions: [AshAuthentication.TokenResource]

postgres do
table "tokens"
repo Canary.Repo
end
end
50 changes: 50 additions & 0 deletions core/lib/canary/accounts/user.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
defmodule Canary.Accounts.User do
use Ash.Resource,
domain: Canary.Accounts,
data_layer: AshPostgres.DataLayer,
extensions: [AshAuthentication]

attributes do
uuid_primary_key :id

attribute :email, :ci_string do
allow_nil? false
public? true
end

attribute :hashed_password, :string, allow_nil?: false, sensitive?: true
end

relationships do
many_to_many :accounts, Canary.Accounts.Account do
through Canary.Accounts.AccountUser
end
end

changes do
change Canary.Accounts.Changes.InitAccount, on: [:create]
end

identities do
identity :unique_email, [:email]
end

authentication do
strategies do
password :password do
identity_field :email
end
end

tokens do
enabled? true
token_resource Canary.Accounts.Token
signing_secret Canary.Accounts.Secrets
end
end

postgres do
table "users"
repo Canary.Repo
end
end
3 changes: 2 additions & 1 deletion core/lib/canary/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule Canary.Application do
children =
discord() ++
[
{AshAuthentication.Supervisor, otp_app: :canary},
CanaryWeb.Telemetry,
Canary.Repo,
{Oban, Application.fetch_env!(:canary, Oban)},
Expand Down Expand Up @@ -39,7 +40,7 @@ defmodule Canary.Application do

defp discord() do
if Application.get_env(:nostrum, :token) do
[Nostrum.Application, Canary.Clients.DiscordBot]
[Nostrum.Application, Canary.Clients.Discord]
else
[]
end
Expand Down
7 changes: 7 additions & 0 deletions core/lib/canary/clients/clients.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule Canary.Clients do
use Ash.Domain

resources do
resource Canary.Clients.Website
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule Canary.Clients.DiscordBot do
defmodule Canary.Clients.Discord do
use Nostrum.Consumer

alias Nostrum.Api
Expand Down
40 changes: 40 additions & 0 deletions core/lib/canary/clients/website.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule Canary.Clients.Website do
use Ash.Resource,
domain: Canary.Clients,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key :id

attribute :account_id, :uuid do
allow_nil? false
end

attribute :base_url, :string do
allow_nil? false
end

attribute :public_key, :string do
allow_nil? false
default &Ash.UUID.generate/0
end
end

actions do
defaults [:read, :destroy]

create :create do
accept [:base_url, :account_id]
change set_attribute(:public_key, Ash.UUID.generate())
end
end

relationships do
belongs_to :account, Canary.Accounts.Account
end

postgres do
table "client_websites"
repo Canary.Repo
end
end
8 changes: 5 additions & 3 deletions core/lib/canary/repo.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
defmodule Canary.Repo do
use Ecto.Repo,
otp_app: :canary,
adapter: Ecto.Adapters.Postgres
use AshPostgres.Repo, otp_app: :canary

def installed_extensions do
["uuid-ossp", "citext", "ash-functions"]
end
end
27 changes: 27 additions & 0 deletions core/lib/canary/sources/document.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule Canary.Sources.Document do
use Ash.Resource,
domain: Canary.Sources,
data_layer: AshPostgres.DataLayer

attributes do
integer_primary_key :id

attribute :content, :string
attribute :embedding, :vector
end

relationships do
belongs_to :snapshot, Canary.Sources.Snapshot
end

actions do
create :create do
accept [:content, :embedding]
end
end

postgres do
table "source_documents"
repo Canary.Repo
end
end
24 changes: 24 additions & 0 deletions core/lib/canary/sources/snapshot.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Canary.Sources.Snapshot do
use Ash.Resource,
domain: Canary.Sources,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key :id

attribute :source_id, :uuid do
allow_nil? false
end

create_timestamp :created_at
end

relationships do
has_many :documents, Canary.Sources.Document
end

postgres do
table "source_snapshots"
repo Canary.Repo
end
end
9 changes: 9 additions & 0 deletions core/lib/canary/sources/sources.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Canary.Sources do
use Ash.Domain

resources do
resource Canary.Sources.Snapshot
resource Canary.Sources.Document
resource Canary.Sources.Website
end
end
38 changes: 38 additions & 0 deletions core/lib/canary/sources/website.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule Canary.Sources.Website do
use Ash.Resource,
domain: Canary.Sources,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key :id

attribute :account_id, :uuid do
allow_nil? false
end

attribute :base_url, :string do
allow_nil? false
end
end

actions do
defaults [:destroy]

create :create do
accept [:base_url, :account_id]
end
end

relationships do
belongs_to :account, Canary.Accounts.Account

has_many :snapshots, Canary.Sources.Snapshot do
destination_attribute :source_id
end
end

postgres do
table "source_websites"
repo Canary.Repo
end
end
2 changes: 1 addition & 1 deletion core/lib/canary_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ defmodule CanaryWeb do

def router do
quote do
use Phoenix.Router, helpers: false
use Phoenix.Router, helpers: true

# Import common connection and controller functions to use in pipelines
import Plug.Conn
Expand Down
Loading

0 comments on commit ab75f74

Please sign in to comment.