aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/activity.ex2
-rw-r--r--lib/pleroma/activity_expiration.ex3
-rw-r--r--lib/pleroma/application.ex1
-rw-r--r--lib/pleroma/bookmark.ex13
-rw-r--r--lib/pleroma/conversation/participation.ex4
-rw-r--r--lib/pleroma/conversation/participation_recipient_ship.ex2
-rw-r--r--lib/pleroma/delivery.ex3
-rw-r--r--lib/pleroma/filter.ex2
-rw-r--r--lib/pleroma/flake_id.ex182
-rw-r--r--lib/pleroma/list.ex2
-rw-r--r--lib/pleroma/notification.ex4
-rw-r--r--lib/pleroma/password_reset_token.ex2
-rw-r--r--lib/pleroma/registration.ex4
-rw-r--r--lib/pleroma/scheduled_activity.ex2
-rw-r--r--lib/pleroma/thread_mute.ex4
-rw-r--r--lib/pleroma/user.ex4
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex2
-rw-r--r--lib/pleroma/web/common_api/utils.ex2
-rw-r--r--lib/pleroma/web/oauth/authorization.ex2
-rw-r--r--lib/pleroma/web/oauth/token.ex2
-rw-r--r--lib/pleroma/web/push/subscription.ex2
-rw-r--r--lib/pleroma/web/websub/websub_client_subscription.ex2
22 files changed, 31 insertions, 215 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index ec558168a..2c04a26f9 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -21,7 +21,7 @@ defmodule Pleroma.Activity do
@type t :: %__MODULE__{}
@type actor :: String.t()
- @primary_key {:id, Pleroma.FlakeId, autogenerate: true}
+ @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true}
# https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19
@mastodon_notification_types %{
diff --git a/lib/pleroma/activity_expiration.ex b/lib/pleroma/activity_expiration.ex
index bf57abca4..7ea5c48ca 100644
--- a/lib/pleroma/activity_expiration.ex
+++ b/lib/pleroma/activity_expiration.ex
@@ -7,7 +7,6 @@ defmodule Pleroma.ActivityExpiration do
alias Pleroma.Activity
alias Pleroma.ActivityExpiration
- alias Pleroma.FlakeId
alias Pleroma.Repo
import Ecto.Changeset
@@ -17,7 +16,7 @@ defmodule Pleroma.ActivityExpiration do
@min_activity_lifetime :timer.hours(1)
schema "activity_expirations" do
- belongs_to(:activity, Activity, type: FlakeId)
+ belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
field(:scheduled_at, :naive_datetime)
end
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index a339e2c48..7aec2c545 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -35,7 +35,6 @@ defmodule Pleroma.Application do
Pleroma.Config.TransferTask,
Pleroma.Emoji,
Pleroma.Captcha,
- Pleroma.FlakeId,
Pleroma.Daemons.ScheduledActivityDaemon,
Pleroma.Daemons.ActivityExpirationDaemon
] ++
diff --git a/lib/pleroma/bookmark.ex b/lib/pleroma/bookmark.ex
index d976f949c..221a94f34 100644
--- a/lib/pleroma/bookmark.ex
+++ b/lib/pleroma/bookmark.ex
@@ -10,20 +10,20 @@ defmodule Pleroma.Bookmark do
alias Pleroma.Activity
alias Pleroma.Bookmark
- alias Pleroma.FlakeId
alias Pleroma.Repo
alias Pleroma.User
@type t :: %__MODULE__{}
schema "bookmarks" do
- belongs_to(:user, User, type: FlakeId)
- belongs_to(:activity, Activity, type: FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
+ belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
timestamps()
end
- @spec create(FlakeId.t(), FlakeId.t()) :: {:ok, Bookmark.t()} | {:error, Changeset.t()}
+ @spec create(FlakeId.Ecto.CompatType.t(), FlakeId.Ecto.CompatType.t()) ::
+ {:ok, Bookmark.t()} | {:error, Changeset.t()}
def create(user_id, activity_id) do
attrs = %{
user_id: user_id,
@@ -37,7 +37,7 @@ defmodule Pleroma.Bookmark do
|> Repo.insert()
end
- @spec for_user_query(FlakeId.t()) :: Ecto.Query.t()
+ @spec for_user_query(FlakeId.Ecto.CompatType.t()) :: Ecto.Query.t()
def for_user_query(user_id) do
Bookmark
|> where(user_id: ^user_id)
@@ -52,7 +52,8 @@ defmodule Pleroma.Bookmark do
|> Repo.one()
end
- @spec destroy(FlakeId.t(), FlakeId.t()) :: {:ok, Bookmark.t()} | {:error, Changeset.t()}
+ @spec destroy(FlakeId.Ecto.CompatType.t(), FlakeId.Ecto.CompatType.t()) ::
+ {:ok, Bookmark.t()} | {:error, Changeset.t()}
def destroy(user_id, activity_id) do
from(b in Bookmark,
where: b.user_id == ^user_id,
diff --git a/lib/pleroma/conversation/participation.ex b/lib/pleroma/conversation/participation.ex
index ea5b9fe17..e946f6de2 100644
--- a/lib/pleroma/conversation/participation.ex
+++ b/lib/pleroma/conversation/participation.ex
@@ -13,10 +13,10 @@ defmodule Pleroma.Conversation.Participation do
import Ecto.Query
schema "conversation_participations" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:conversation, Conversation)
field(:read, :boolean, default: false)
- field(:last_activity_id, Pleroma.FlakeId, virtual: true)
+ field(:last_activity_id, FlakeId.Ecto.CompatType, virtual: true)
has_many(:recipient_ships, RecipientShip)
has_many(:recipients, through: [:recipient_ships, :user])
diff --git a/lib/pleroma/conversation/participation_recipient_ship.ex b/lib/pleroma/conversation/participation_recipient_ship.ex
index 932cbd04c..e3d158cbc 100644
--- a/lib/pleroma/conversation/participation_recipient_ship.ex
+++ b/lib/pleroma/conversation/participation_recipient_ship.ex
@@ -12,7 +12,7 @@ defmodule Pleroma.Conversation.Participation.RecipientShip do
import Ecto.Changeset
schema "conversation_participation_recipient_ships" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:participation, Participation)
end
diff --git a/lib/pleroma/delivery.ex b/lib/pleroma/delivery.ex
index 29a1e5a77..1d586a252 100644
--- a/lib/pleroma/delivery.ex
+++ b/lib/pleroma/delivery.ex
@@ -6,7 +6,6 @@ defmodule Pleroma.Delivery do
use Ecto.Schema
alias Pleroma.Delivery
- alias Pleroma.FlakeId
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
@@ -16,7 +15,7 @@ defmodule Pleroma.Delivery do
import Ecto.Query
schema "deliveries" do
- belongs_to(:user, User, type: FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:object, Object)
end
diff --git a/lib/pleroma/filter.ex b/lib/pleroma/filter.ex
index 90457dadf..c87141582 100644
--- a/lib/pleroma/filter.ex
+++ b/lib/pleroma/filter.ex
@@ -12,7 +12,7 @@ defmodule Pleroma.Filter do
alias Pleroma.User
schema "filters" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
field(:filter_id, :integer)
field(:hide, :boolean, default: false)
field(:whole_word, :boolean, default: true)
diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex
deleted file mode 100644
index 042cf8659..000000000
--- a/lib/pleroma/flake_id.ex
+++ /dev/null
@@ -1,182 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.FlakeId do
- @moduledoc """
- Flake is a decentralized, k-ordered id generation service.
-
- Adapted from:
-
- * [flaky](https://github.com/nirvana/flaky), released under the terms of the Truly Free License,
- * [Flake](https://github.com/boundary/flake), Copyright 2012, Boundary, Apache License, Version 2.0
- """
-
- @type t :: binary
-
- use Ecto.Type
- use GenServer
- require Logger
- alias __MODULE__
- import Kernel, except: [to_string: 1]
-
- defstruct node: nil, time: 0, sq: 0
-
- @doc "Converts a binary Flake to a String"
- def to_string(<<0::integer-size(64), id::integer-size(64)>>) do
- Kernel.to_string(id)
- end
-
- def to_string(<<_::integer-size(64), _::integer-size(48), _::integer-size(16)>> = flake) do
- encode_base62(flake)
- end
-
- def to_string(s), do: s
-
- def from_string(int) when is_integer(int) do
- from_string(Kernel.to_string(int))
- end
-
- for i <- [-1, 0] do
- def from_string(unquote(i)), do: <<0::integer-size(128)>>
- def from_string(unquote(Kernel.to_string(i))), do: <<0::integer-size(128)>>
- end
-
- def from_string(<<_::integer-size(128)>> = flake), do: flake
-
- def from_string(string) when is_binary(string) and byte_size(string) < 18 do
- case Integer.parse(string) do
- {id, ""} -> <<0::integer-size(64), id::integer-size(64)>>
- _ -> nil
- end
- end
-
- def from_string(string) do
- string |> decode_base62 |> from_integer
- end
-
- def to_integer(<<integer::integer-size(128)>>), do: integer
-
- def from_integer(integer) do
- <<_time::integer-size(64), _node::integer-size(48), _seq::integer-size(16)>> =
- <<integer::integer-size(128)>>
- end
-
- @doc "Generates a Flake"
- @spec get :: binary
- def get, do: to_string(:gen_server.call(:flake, :get))
-
- # checks that ID is is valid FlakeID
- #
- @spec is_flake_id?(String.t()) :: boolean
- def is_flake_id?(id), do: is_flake_id?(String.to_charlist(id), true)
- defp is_flake_id?([c | cs], true) when c >= ?0 and c <= ?9, do: is_flake_id?(cs, true)
- defp is_flake_id?([c | cs], true) when c >= ?A and c <= ?Z, do: is_flake_id?(cs, true)
- defp is_flake_id?([c | cs], true) when c >= ?a and c <= ?z, do: is_flake_id?(cs, true)
- defp is_flake_id?([], true), do: true
- defp is_flake_id?(_, _), do: false
-
- # -- Ecto.Type API
- @impl Ecto.Type
- def type, do: :uuid
-
- @impl Ecto.Type
- def cast(value) do
- {:ok, FlakeId.to_string(value)}
- end
-
- @impl Ecto.Type
- def load(value) do
- {:ok, FlakeId.to_string(value)}
- end
-
- @impl Ecto.Type
- def dump(value) do
- {:ok, FlakeId.from_string(value)}
- end
-
- def autogenerate, do: get()
-
- # -- GenServer API
- def start_link(_) do
- :gen_server.start_link({:local, :flake}, __MODULE__, [], [])
- end
-
- @impl GenServer
- def init([]) do
- {:ok, %FlakeId{node: worker_id(), time: time()}}
- end
-
- @impl GenServer
- def handle_call(:get, _from, state) do
- {flake, new_state} = get(time(), state)
- {:reply, flake, new_state}
- end
-
- # Matches when the calling time is the same as the state time. Incr. sq
- defp get(time, %FlakeId{time: time, node: node, sq: seq}) do
- new_state = %FlakeId{time: time, node: node, sq: seq + 1}
- {gen_flake(new_state), new_state}
- end
-
- # Matches when the times are different, reset sq
- defp get(newtime, %FlakeId{time: time, node: node}) when newtime > time do
- new_state = %FlakeId{time: newtime, node: node, sq: 0}
- {gen_flake(new_state), new_state}
- end
-
- # Error when clock is running backwards
- defp get(newtime, %FlakeId{time: time}) when newtime < time do
- {:error, :clock_running_backwards}
- end
-
- defp gen_flake(%FlakeId{time: time, node: node, sq: seq}) do
- <<time::integer-size(64), node::integer-size(48), seq::integer-size(16)>>
- end
-
- defp nthchar_base62(n) when n <= 9, do: ?0 + n
- defp nthchar_base62(n) when n <= 35, do: ?A + n - 10
- defp nthchar_base62(n), do: ?a + n - 36
-
- defp encode_base62(<<integer::integer-size(128)>>) do
- integer
- |> encode_base62([])
- |> List.to_string()
- end
-
- defp encode_base62(int, acc) when int < 0, do: encode_base62(-int, acc)
- defp encode_base62(int, []) when int == 0, do: '0'
- defp encode_base62(int, acc) when int == 0, do: acc
-
- defp encode_base62(int, acc) do
- r = rem(int, 62)
- id = div(int, 62)
- acc = [nthchar_base62(r) | acc]
- encode_base62(id, acc)
- end
-
- defp decode_base62(s) do
- decode_base62(String.to_charlist(s), 0)
- end
-
- defp decode_base62([c | cs], acc) when c >= ?0 and c <= ?9,
- do: decode_base62(cs, 62 * acc + (c - ?0))
-
- defp decode_base62([c | cs], acc) when c >= ?A and c <= ?Z,
- do: decode_base62(cs, 62 * acc + (c - ?A + 10))
-
- defp decode_base62([c | cs], acc) when c >= ?a and c <= ?z,
- do: decode_base62(cs, 62 * acc + (c - ?a + 36))
-
- defp decode_base62([], acc), do: acc
-
- defp time do
- {mega_seconds, seconds, micro_seconds} = :erlang.timestamp()
- 1_000_000_000 * mega_seconds + seconds * 1000 + :erlang.trunc(micro_seconds / 1000)
- end
-
- defp worker_id do
- <<worker::integer-size(48)>> = :crypto.strong_rand_bytes(6)
- worker
- end
-end
diff --git a/lib/pleroma/list.ex b/lib/pleroma/list.ex
index c572380c2..c5db1cb62 100644
--- a/lib/pleroma/list.ex
+++ b/lib/pleroma/list.ex
@@ -13,7 +13,7 @@ defmodule Pleroma.List do
alias Pleroma.User
schema "lists" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
field(:title, :string)
field(:following, {:array, :string}, default: [])
field(:ap_id, :string)
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 8012389ac..d94ae5971 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -22,8 +22,8 @@ defmodule Pleroma.Notification do
schema "notifications" do
field(:seen, :boolean, default: false)
- belongs_to(:user, User, type: Pleroma.FlakeId)
- belongs_to(:activity, Activity, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
+ belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
timestamps()
end
diff --git a/lib/pleroma/password_reset_token.ex b/lib/pleroma/password_reset_token.ex
index 4a833f6a5..db398b1fc 100644
--- a/lib/pleroma/password_reset_token.ex
+++ b/lib/pleroma/password_reset_token.ex
@@ -12,7 +12,7 @@ defmodule Pleroma.PasswordResetToken do
alias Pleroma.User
schema "password_reset_tokens" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
field(:token, :string)
field(:used, :boolean, default: false)
diff --git a/lib/pleroma/registration.ex b/lib/pleroma/registration.ex
index 21fd1fc3f..8544461db 100644
--- a/lib/pleroma/registration.ex
+++ b/lib/pleroma/registration.ex
@@ -11,10 +11,10 @@ defmodule Pleroma.Registration do
alias Pleroma.Repo
alias Pleroma.User
- @primary_key {:id, Pleroma.FlakeId, autogenerate: true}
+ @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true}
schema "registrations" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
field(:provider, :string)
field(:uid, :string)
field(:info, :map, default: %{})
diff --git a/lib/pleroma/scheduled_activity.ex b/lib/pleroma/scheduled_activity.ex
index de0e54699..fea2cf3ff 100644
--- a/lib/pleroma/scheduled_activity.ex
+++ b/lib/pleroma/scheduled_activity.ex
@@ -17,7 +17,7 @@ defmodule Pleroma.ScheduledActivity do
@min_offset :timer.minutes(5)
schema "scheduled_activities" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
field(:scheduled_at, :naive_datetime)
field(:params, :map)
diff --git a/lib/pleroma/thread_mute.ex b/lib/pleroma/thread_mute.ex
index 10d31679d..65cbbede3 100644
--- a/lib/pleroma/thread_mute.ex
+++ b/lib/pleroma/thread_mute.ex
@@ -12,7 +12,7 @@ defmodule Pleroma.ThreadMute do
require Ecto.Query
schema "thread_mutes" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
field(:context, :string)
end
@@ -24,7 +24,7 @@ defmodule Pleroma.ThreadMute do
end
def query(user_id, context) do
- user_id = Pleroma.FlakeId.from_string(user_id)
+ {:ok, user_id} = FlakeId.Ecto.CompatType.dump(user_id)
ThreadMute
|> Ecto.Query.where(user_id: ^user_id)
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index ab253a274..756eb53a6 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -34,7 +34,7 @@ defmodule Pleroma.User do
@type t :: %__MODULE__{}
- @primary_key {:id, Pleroma.FlakeId, autogenerate: true}
+ @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true}
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
@email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
@@ -606,7 +606,7 @@ defmodule Pleroma.User do
restrict_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
cond do
- is_integer(nickname_or_id) or Pleroma.FlakeId.is_flake_id?(nickname_or_id) ->
+ is_integer(nickname_or_id) or FlakeId.flake_id?(nickname_or_id) ->
get_cached_by_id(nickname_or_id) || get_cached_by_nickname(nickname_or_id)
restrict_to_local == false ->
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 72755904b..ff29efd43 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -510,7 +510,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
@spec fetch_latest_activity_id_for_context(String.t(), keyword() | map()) ::
- Pleroma.FlakeId.t() | nil
+ FlakeId.Ecto.CompatType.t() | nil
def fetch_latest_activity_id_for_context(context, opts \\ %{}) do
context
|> fetch_activities_for_context_query(Map.merge(%{"skip_preload" => true}, opts))
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index 1fb95f4ab..52fbc162b 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -26,7 +26,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
# This is a hack for twidere.
def get_by_id_or_ap_id(id) do
activity =
- with true <- Pleroma.FlakeId.is_flake_id?(id),
+ with true <- FlakeId.flake_id?(id),
%Activity{} = activity <- Activity.get_by_id_with_object(id) do
activity
else
diff --git a/lib/pleroma/web/oauth/authorization.ex b/lib/pleroma/web/oauth/authorization.ex
index d53e20d12..ed42a34f3 100644
--- a/lib/pleroma/web/oauth/authorization.ex
+++ b/lib/pleroma/web/oauth/authorization.ex
@@ -20,7 +20,7 @@ defmodule Pleroma.Web.OAuth.Authorization do
field(:scopes, {:array, :string}, default: [])
field(:valid_until, :naive_datetime_usec)
field(:used, :boolean, default: false)
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:app, App)
timestamps()
diff --git a/lib/pleroma/web/oauth/token.ex b/lib/pleroma/web/oauth/token.ex
index 40f131b57..8ea373805 100644
--- a/lib/pleroma/web/oauth/token.ex
+++ b/lib/pleroma/web/oauth/token.ex
@@ -21,7 +21,7 @@ defmodule Pleroma.Web.OAuth.Token do
field(:refresh_token, :string)
field(:scopes, {:array, :string}, default: [])
field(:valid_until, :naive_datetime_usec)
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:app, App)
timestamps()
diff --git a/lib/pleroma/web/push/subscription.ex b/lib/pleroma/web/push/subscription.ex
index da301fbbc..988fabaeb 100644
--- a/lib/pleroma/web/push/subscription.ex
+++ b/lib/pleroma/web/push/subscription.ex
@@ -15,7 +15,7 @@ defmodule Pleroma.Web.Push.Subscription do
@type t :: %__MODULE__{}
schema "push_subscriptions" do
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:token, Token)
field(:endpoint, :string)
field(:key_p256dh, :string)
diff --git a/lib/pleroma/web/websub/websub_client_subscription.ex b/lib/pleroma/web/websub/websub_client_subscription.ex
index 77703c496..23a04b87d 100644
--- a/lib/pleroma/web/websub/websub_client_subscription.ex
+++ b/lib/pleroma/web/websub/websub_client_subscription.ex
@@ -13,7 +13,7 @@ defmodule Pleroma.Web.Websub.WebsubClientSubscription do
field(:state, :string)
field(:subscribers, {:array, :string}, default: [])
field(:hub, :string)
- belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
timestamps()
end