diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js
index 96c548a..a6be861 100644
--- a/assets/tailwind.config.js
+++ b/assets/tailwind.config.js
@@ -8,13 +8,13 @@ const path = require("path")
 module.exports = {
   content: [
     "./js/**/*.js",
-    "../lib/cms_web.ex",
-    "../lib/cms_web/**/*.*ex"
+    "../lib/web.ex",
+    "../lib/web/**/*.*ex"
   ],
   theme: {
     extend: {
-      typography: ({theme}) => ({
-        cms: {
+      typography: ({ theme }) => ({
+        sloanely_but_surely: {
           css: {
             '--tw-prose-body': theme('colors.black'),
             '--tw-prose-headings': theme('colors.black'),
@@ -61,14 +61,14 @@ module.exports = {
     //
     //     <div class="phx-click-loading:animate-ping">
     //
-    plugin(({addVariant}) => addVariant("phx-click-loading", [".phx-click-loading&", ".phx-click-loading &"])),
-    plugin(({addVariant}) => addVariant("phx-submit-loading", [".phx-submit-loading&", ".phx-submit-loading &"])),
-    plugin(({addVariant}) => addVariant("phx-change-loading", [".phx-change-loading&", ".phx-change-loading &"])),
+    plugin(({ addVariant }) => addVariant("phx-click-loading", [".phx-click-loading&", ".phx-click-loading &"])),
+    plugin(({ addVariant }) => addVariant("phx-submit-loading", [".phx-submit-loading&", ".phx-submit-loading &"])),
+    plugin(({ addVariant }) => addVariant("phx-change-loading", [".phx-change-loading&", ".phx-change-loading &"])),
 
     // Embeds Heroicons (https://heroicons.com) into your app.css bundle
     // See your `CoreComponents.icon/1` for more information.
     //
-    plugin(function({matchComponents, theme}) {
+    plugin(function({ matchComponents, theme }) {
       let iconsDir = path.join(__dirname, "../deps/heroicons/optimized")
       let values = {}
       let icons = [
@@ -80,11 +80,11 @@ module.exports = {
       icons.forEach(([suffix, dir]) => {
         fs.readdirSync(path.join(iconsDir, dir)).forEach(file => {
           let name = path.basename(file, ".svg") + suffix
-          values[name] = {name, fullPath: path.join(iconsDir, dir, file)}
+          values[name] = { name, fullPath: path.join(iconsDir, dir, file) }
         })
       })
       matchComponents({
-        "hero": ({name, fullPath}) => {
+        "hero": ({ name, fullPath }) => {
           let content = fs.readFileSync(fullPath).toString().replace(/\r?\n|\r/g, "")
           let size = theme("spacing.6")
           if (name.endsWith("-mini")) {
@@ -104,7 +104,7 @@ module.exports = {
             "height": size
           }
         }
-      }, {values})
+      }, { values })
     })
   ]
 }
diff --git a/config/config.exs b/config/config.exs
index 260235d..ee5b709 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -1,57 +1,42 @@
-# This file is responsible for configuring your application
-# and its dependencies with the aid of the Config module.
-#
-# This configuration file is loaded before any dependency and
-# is restricted to this project.
-
-# General application configuration
 import Config
 
-# Configures the endpoint
-config :cms, CMSWeb.Endpoint,
-  url: [host: "localhost"],
-  adapter: Bandit.PhoenixAdapter,
-  render_errors: [
-    formats: [html: CMSWeb.ErrorHTML, json: CMSWeb.ErrorJSON],
-    layout: false
-  ],
-  pubsub_server: CMS.PubSub,
-  live_view: [signing_salt: "afQxdsCJ"]
-
-config :cms,
-  namespace: CMS,
-  ecto_repos: [CMS.Repo],
-  generators: [timestamp_type: :utc_datetime, binary_id: true]
-
-# Configure esbuild (the version is required)
 config :esbuild,
   version: "0.17.11",
-  cms: [
+  sloanely_but_surely: [
     args: ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
     cd: Path.expand("../assets", __DIR__),
     env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
   ]
 
-# Configures Elixir's Logger
 config :logger, :console,
   format: "$time $metadata[$level] $message\n",
   metadata: [:request_id]
 
-# Use Jason for JSON parsing in Phoenix
 config :phoenix, :json_library, Jason
 
-# Configure tailwind (the version is required)
+config :sloanely_but_surely, Web.Endpoint,
+  url: [host: "localhost"],
+  adapter: Bandit.PhoenixAdapter,
+  render_errors: [
+    formats: [html: Web.ErrorHTML, json: Web.ErrorJSON],
+    layout: false
+  ],
+  pubsub_server: Core.PubSub,
+  live_view: [signing_salt: "afQxdsCJ"]
+
+config :sloanely_but_surely,
+  namespace: Core,
+  ecto_repos: [Core.Repo],
+  generators: [timestamp_type: :utc_datetime, binary_id: true]
+
 config :tailwind,
   version: "3.4.3",
-  cms: [
+  sloanely_but_surely: [
     args: ~w(
       --config=tailwind.config.js
       --input=css/app.css
       --output=../priv/static/assets/app.css
     ),
-
-    # Import environment specific config. This must remain at the bottom
-    # of this file so it overrides the configuration defined above.
     cd: Path.expand("../assets", __DIR__)
   ]
 
diff --git a/config/dev.exs b/config/dev.exs
index 52e40ff..cccdef2 100644
--- a/config/dev.exs
+++ b/config/dev.exs
@@ -1,82 +1,39 @@
 import Config
 
-# Configure your database
-# For development, we disable any cache and enable
-# debugging and code reloading.
-#
-# The watchers configuration can be used to run external
-# watchers to your application. For example, we can use it
-# to bundle .js and .css sources.
-# Binding to loopback ipv4 address prevents access from other machines.
-config :cms, CMS.Repo,
+config :logger, :console, format: "[$level] $message\n"
+
+config :phoenix,
+  plug_init_mode: :runtime,
+  stacktrace_depth: 20
+
+config :phoenix_live_view,
+  debug_heex_annotations: true,
+  enable_expensive_runtime_checks: true
+
+config :sloanely_but_surely, Core.Repo,
   username: "postgres",
   password: "postgres",
   hostname: "localhost",
-  database: "cms_dev",
+  database: "sloanely_but_surely_dev",
   stacktrace: true,
   show_sensitive_data_on_connection_error: true,
   pool_size: 10
 
-config :cms, CMSWeb.Endpoint,
-  # Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
+config :sloanely_but_surely, Web.Endpoint,
   http: [ip: {127, 0, 0, 1}, port: 4000],
   check_origin: false,
   code_reloader: true,
   debug_errors: true,
   secret_key_base: "OiPAYORPwZPHThILCLsbcM9fqJNWoTphDydEEXsrKaILQm1lz8lt0DMiu9cCoVqC",
   watchers: [
-    esbuild: {Esbuild, :install_and_run, [:cms, ~w(--sourcemap=inline --watch)]},
-    tailwind: {Tailwind, :install_and_run, [:cms, ~w(--watch)]}
-  ]
-
-# Watch static and templates for browser reloading.
-config :cms, CMSWeb.Endpoint,
+    esbuild: {Esbuild, :install_and_run, [:sloanely_but_surely, ~w(--sourcemap=inline --watch)]},
+    tailwind: {Tailwind, :install_and_run, [:sloanely_but_surely, ~w(--watch)]}
+  ],
   live_reload: [
     patterns: [
       ~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
-      ~r"lib/cms_web/(controllers|live|components)/.*(ex|heex)$"
+      ~r"lib/web/(controllers|live|components)/.*(ex|heex)$"
     ]
   ]
 
-# ## SSL Support
-#
-
-# Enable dev routes for dashboard and mailbox
-# In order to use HTTPS in development, a self-signed
-# certificate can be generated by running the following
-# Mix task:
-#
-config :cms, dev_routes: true
-
-# Do not include metadata nor timestamps in development logs
-#     mix phx.gen.cert
-#
-# Run `mix help phx.gen.cert` for more information.
-#
-config :logger, :console, format: "[$level] $message\n"
-
-# Initialize plugs at runtime for faster development compilation
-# The `http:` config above can be replaced with:
-#
-#     https: [
-config :phoenix, :plug_init_mode, :runtime
-
-# Set a higher stacktrace during development. Avoid configuring such
-#       port: 4001,
-# in production as building large stacktraces may be expensive.
-#       cipher_suite: :strong,
-#       keyfile: "priv/cert/selfsigned_key.pem",
-#       certfile: "priv/cert/selfsigned.pem"
-config :phoenix, :stacktrace_depth, 20
-
-config :phoenix_live_view,
-  # Include HEEx debug annotations as HTML comments in rendered markup
-  #     ],
-  #
-  debug_heex_annotations: true,
-  # Enable helpful, but potentially expensive runtime checks
-  # If desired, both `http:` and `https:` keys can be
-  # configured to run both http and https servers on
-  # different ports.
-
-  enable_expensive_runtime_checks: true
+config :sloanely_but_surely, dev_routes: true
diff --git a/config/prod.exs b/config/prod.exs
index eb88e2a..6041dfa 100644
--- a/config/prod.exs
+++ b/config/prod.exs
@@ -1,14 +1,5 @@
 import Config
 
-# Note we also include the path to a cache manifest
-# containing the digested version of static files. This
-# manifest is generated by the `mix assets.deploy` task,
-# which you should run after static files are built and
-# before starting your production server.
-config :cms, CMSWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json"
-
-# Do not print debug messages in production
 config :logger, level: :info
 
-# Runtime production configuration, including reading
-# of environment variables, is done on config/runtime.exs.
+config :sloanely_but_surely, Web.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json"
diff --git a/config/runtime.exs b/config/runtime.exs
index 827c59b..59dae60 100644
--- a/config/runtime.exs
+++ b/config/runtime.exs
@@ -1,26 +1,10 @@
 import Config
 
-# config/runtime.exs is executed for all environments, including
-# during releases. It is executed after compilation and before the
-# system starts, so it is typically used to load production configuration
-# and secrets from environment variables or elsewhere. Do not define
-# any compile-time configuration in here, as it won't be applied.
-# The block below contains prod specific runtime configuration.
-
-# ## Using releases
-#
-# If you use `mix release`, you need to explicitly enable the server
-# by passing the PHX_SERVER=true when you start it:
-#
-#     PHX_SERVER=true bin/cms start
-#
-# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server`
-# script that automatically sets the env var above.
 if System.get_env("PHX_SERVER") do
-  config :cms, CMSWeb.Endpoint, server: true
+  config :sloanely_but_surely, Web.Endpoint, server: true
 end
 
-config :cms,
+config :sloanely_but_surely,
   password_hash:
     System.get_env("PASSWORD_HASH") ||
       raise("""
@@ -39,11 +23,6 @@ if config_env() == :prod do
 
   maybe_ipv6 = if System.get_env("ECTO_IPV6") in ~w(true 1), do: [:inet6], else: []
 
-  # The secret key base is used to sign/encrypt cookies and other secrets.
-  # A default value is used in config/dev.exs and config/test.exs but you
-  # want to use a different value for prod and you most likely don't want
-  # to check this value into version control, so we use an environment
-  # variable instead.
   secret_key_base =
     System.get_env("SECRET_KEY_BASE") ||
       raise """
@@ -54,55 +33,17 @@ if config_env() == :prod do
   host = System.get_env("PHX_HOST") || "example.com"
   port = String.to_integer(System.get_env("PORT") || "4000")
 
-  config :cms, CMS.Repo,
+  config :sloanely_but_surely, Core.Repo,
     # ssl: true,
     url: database_url,
     pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
     socket_options: maybe_ipv6
 
-  config :cms, CMSWeb.Endpoint,
+  config :sloanely_but_surely, Web.Endpoint,
     url: [host: host, port: 443, scheme: "https"],
     http: [
-      # Enable IPv6 and bind on all interfaces.
-      # Set it to  {0, 0, 0, 0, 0, 0, 0, 1} for local network only access.
-      # See the documentation on https://hexdocs.pm/bandit/Bandit.html#t:options/0
-      # for details about using IPv6 vs IPv4 and loopback vs public addresses.
       ip: {0, 0, 0, 0, 0, 0, 0, 0},
       port: port
     ],
     secret_key_base: secret_key_base
-
-  config :cms, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY")
-
-  # ## SSL Support
-  #
-  # To get SSL working, you will need to add the `https` key
-  # to your endpoint configuration:
-  #
-  #     config :cms, CMSWeb.Endpoint,
-  #       https: [
-  #         ...,
-  #         port: 443,
-  #         cipher_suite: :strong,
-  #         keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
-  #         certfile: System.get_env("SOME_APP_SSL_CERT_PATH")
-  #       ]
-  #
-  # The `cipher_suite` is set to `:strong` to support only the
-  # latest and more secure SSL ciphers. This means old browsers
-  # and clients may not be supported. You can set it to
-  # `:compatible` for wider support.
-  #
-  # `:keyfile` and `:certfile` expect an absolute path to the key
-  # and cert in disk or a relative path inside priv, for example
-  # "priv/ssl/server.key". For all supported SSL configuration
-  # options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1
-  #
-  # We also recommend setting `force_ssl` in your config/prod.exs,
-  # ensuring no data is ever sent via http, always redirecting to https:
-  #
-  #     config :cms, CMSWeb.Endpoint,
-  #       force_ssl: [hsts: true]
-  #
-  # Check `Plug.SSL` for all available options in `force_ssl`.
 end
diff --git a/config/test.exs b/config/test.exs
index 86322de..e447f24 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -1,31 +1,21 @@
 import Config
 
-# Configure your database
-#
-# The MIX_TEST_PARTITION environment variable can be used
-# to provide built-in test partitioning in CI environment.
-# Run `mix help test` for more information.
-config :cms, CMS.Repo,
+config :logger, level: :warning
+
+config :phoenix, :plug_init_mode, :runtime
+
+config :phoenix_live_view,
+  enable_expensive_runtime_checks: true
+
+config :sloanely_but_surely, Core.Repo,
   username: "postgres",
   password: "postgres",
   hostname: "localhost",
-  database: "cms_test#{System.get_env("MIX_TEST_PARTITION")}",
+  database: "sloanely_but_surely_test#{System.get_env("MIX_TEST_PARTITION")}",
   pool: Ecto.Adapters.SQL.Sandbox,
   pool_size: System.schedulers_online() * 2
 
-# We don't run a server during test. If one is required,
-# you can enable the server option below.
-config :cms, CMSWeb.Endpoint,
+config :sloanely_but_surely, Web.Endpoint,
   http: [ip: {127, 0, 0, 1}, port: 4002],
   secret_key_base: "IAv/74HChZvRYUunjUjCoj/b8NA6mZtVbcxv6ECoOJ+Xr+CeNBVGZ7zkDhUlXSq4",
   server: false
-
-# Print only warnings and errors during test
-config :logger, level: :warning
-
-# Initialize plugs at runtime for faster test compilation
-config :phoenix, :plug_init_mode, :runtime
-
-# Enable helpful, but potentially expensive runtime checks
-config :phoenix_live_view,
-  enable_expensive_runtime_checks: true
diff --git a/lib/cms.ex b/lib/cms.ex
deleted file mode 100644
index 5bfe4d8..0000000
--- a/lib/cms.ex
+++ /dev/null
@@ -1,9 +0,0 @@
-defmodule CMS do
-  @moduledoc """
-  CMS keeps the contexts that define your domain
-  and business logic.
-
-  Contexts are also responsible for managing your data, regardless
-  if it comes from the database, an external API or others.
-  """
-end
diff --git a/lib/cms/application.ex b/lib/cms/application.ex
deleted file mode 100644
index 6b9b5cc..0000000
--- a/lib/cms/application.ex
+++ /dev/null
@@ -1,34 +0,0 @@
-defmodule CMS.Application do
-  # See https://hexdocs.pm/elixir/Application.html
-  # for more information on OTP Applications
-  @moduledoc false
-
-  use Application
-
-  @impl true
-  def start(_type, _args) do
-    children = [
-      CMSWeb.Telemetry,
-      CMS.Repo,
-      {DNSCluster, query: Application.get_env(:cms, :dns_cluster_query) || :ignore},
-      {Phoenix.PubSub, name: CMS.PubSub},
-      # Start a worker by calling: CMS.Worker.start_link(arg)
-      # {CMS.Worker, arg},
-      # Start to serve requests, typically the last entry
-      CMSWeb.Endpoint
-    ]
-
-    # See https://hexdocs.pm/elixir/Supervisor.html
-    # for other strategies and supported options
-    opts = [strategy: :one_for_one, name: CMS.Supervisor]
-    Supervisor.start_link(children, opts)
-  end
-
-  # Tell Phoenix to update the endpoint configuration
-  # whenever the application is updated.
-  @impl true
-  def config_change(changed, _new, removed) do
-    CMSWeb.Endpoint.config_change(changed, removed)
-    :ok
-  end
-end
diff --git a/lib/cms/posts.ex b/lib/cms/posts.ex
deleted file mode 100644
index 5ebaa01..0000000
--- a/lib/cms/posts.ex
+++ /dev/null
@@ -1,31 +0,0 @@
-defmodule CMS.Posts do
-  @moduledoc false
-  import Ecto.Query
-
-  alias CMS.Posts.Post
-  alias CMS.Repo
-
-  def create_post(attrs) do
-    %Post{}
-    |> Post.changeset(attrs)
-    |> Repo.insert()
-  end
-
-  def update_post(post, attrs) do
-    post
-    |> Post.changeset(attrs)
-    |> Repo.update()
-  end
-
-  def get_post!(id) do
-    Repo.get!(Post, id)
-  end
-
-  def list_posts do
-    query =
-      from post in Post,
-        order_by: [desc: post.inserted_at]
-
-    Repo.all(query)
-  end
-end
diff --git a/lib/cms/posts/post.ex b/lib/cms/posts/post.ex
deleted file mode 100644
index aaaea4f..0000000
--- a/lib/cms/posts/post.ex
+++ /dev/null
@@ -1,20 +0,0 @@
-defmodule CMS.Posts.Post do
-  @moduledoc false
-  use Ecto.Schema
-
-  import Ecto.Changeset, warn: false
-
-  @primary_key {:id, :binary_id, autogenerate: true}
-  schema "posts" do
-    field :title, :string
-    field :body, :string
-
-    timestamps()
-  end
-
-  def changeset(%__MODULE__{} = post, attrs \\ %{}) do
-    post
-    |> cast(attrs, [:title, :body])
-    |> validate_required([:body])
-  end
-end
diff --git a/lib/cms/repo.ex b/lib/cms/repo.ex
deleted file mode 100644
index edf96ef..0000000
--- a/lib/cms/repo.ex
+++ /dev/null
@@ -1,5 +0,0 @@
-defmodule CMS.Repo do
-  use Ecto.Repo,
-    otp_app: :cms,
-    adapter: Ecto.Adapters.Postgres
-end
diff --git a/lib/cms/statuses.ex b/lib/cms/statuses.ex
deleted file mode 100644
index 7f817f9..0000000
--- a/lib/cms/statuses.ex
+++ /dev/null
@@ -1,31 +0,0 @@
-defmodule CMS.Statuses do
-  @moduledoc false
-  import Ecto.Query
-
-  alias CMS.Repo
-  alias CMS.Statuses.Status
-
-  def create_status(attrs) do
-    %Status{}
-    |> Status.changeset(attrs)
-    |> Repo.insert()
-  end
-
-  def update_status(status, attrs) do
-    status
-    |> Status.changeset(attrs)
-    |> Repo.update()
-  end
-
-  def get_status!(id) do
-    Repo.get!(Status, id)
-  end
-
-  def list_statuses do
-    query =
-      from status in Status,
-        order_by: [desc: status.inserted_at]
-
-    Repo.all(query)
-  end
-end
diff --git a/lib/cms/statuses/status.ex b/lib/cms/statuses/status.ex
deleted file mode 100644
index 00cd5f0..0000000
--- a/lib/cms/statuses/status.ex
+++ /dev/null
@@ -1,19 +0,0 @@
-defmodule CMS.Statuses.Status do
-  @moduledoc false
-  use Ecto.Schema
-
-  import Ecto.Changeset
-
-  @primary_key {:id, :binary_id, autogenerate: true}
-  schema "statuses" do
-    field :body
-
-    timestamps()
-  end
-
-  def changeset(%__MODULE__{} = status, attrs \\ %{}) do
-    status
-    |> cast(attrs, [:body])
-    |> validate_required([:body])
-  end
-end
diff --git a/lib/cms_web/controllers/page_controller.ex b/lib/cms_web/controllers/page_controller.ex
deleted file mode 100644
index ca7d635..0000000
--- a/lib/cms_web/controllers/page_controller.ex
+++ /dev/null
@@ -1,16 +0,0 @@
-defmodule CMSWeb.PageController do
-  use CMSWeb, :controller
-
-  alias CMS.Posts
-  alias CMS.Statuses
-
-  def home(conn, _params) do
-    posts = Enum.take(Posts.list_posts(), 5)
-    statuses = Enum.take(Statuses.list_statuses(), 10)
-
-    conn
-    |> assign(:posts, posts)
-    |> assign(:statuses, statuses)
-    |> render(:home)
-  end
-end
diff --git a/lib/cms_web/telemetry.ex b/lib/cms_web/telemetry.ex
deleted file mode 100644
index ffc1ce9..0000000
--- a/lib/cms_web/telemetry.ex
+++ /dev/null
@@ -1,93 +0,0 @@
-defmodule CMSWeb.Telemetry do
-  @moduledoc false
-  use Supervisor
-
-  import Telemetry.Metrics
-
-  def start_link(arg) do
-    Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
-  end
-
-  @impl true
-  def init(_arg) do
-    children = [
-      # Telemetry poller will execute the given period measurements
-      # every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics
-      {:telemetry_poller, measurements: periodic_measurements(), period: 10_000}
-      # Add reporters as children of your supervision tree.
-      # {Telemetry.Metrics.ConsoleReporter, metrics: metrics()}
-    ]
-
-    Supervisor.init(children, strategy: :one_for_one)
-  end
-
-  def metrics do
-    [
-      # Phoenix Metrics
-      summary("phoenix.endpoint.start.system_time",
-        unit: {:native, :millisecond}
-      ),
-      summary("phoenix.endpoint.stop.duration",
-        unit: {:native, :millisecond}
-      ),
-      summary("phoenix.router_dispatch.start.system_time",
-        tags: [:route],
-        unit: {:native, :millisecond}
-      ),
-      summary("phoenix.router_dispatch.exception.duration",
-        tags: [:route],
-        unit: {:native, :millisecond}
-      ),
-      summary("phoenix.router_dispatch.stop.duration",
-        tags: [:route],
-        unit: {:native, :millisecond}
-      ),
-      summary("phoenix.socket_connected.duration",
-        unit: {:native, :millisecond}
-      ),
-      summary("phoenix.channel_joined.duration",
-        unit: {:native, :millisecond}
-      ),
-      summary("phoenix.channel_handled_in.duration",
-        tags: [:event],
-        unit: {:native, :millisecond}
-      ),
-
-      # Database Metrics
-      summary("cms.repo.query.total_time",
-        unit: {:native, :millisecond},
-        description: "The sum of the other measurements"
-      ),
-      summary("cms.repo.query.decode_time",
-        unit: {:native, :millisecond},
-        description: "The time spent decoding the data received from the database"
-      ),
-      summary("cms.repo.query.query_time",
-        unit: {:native, :millisecond},
-        description: "The time spent executing the query"
-      ),
-      summary("cms.repo.query.queue_time",
-        unit: {:native, :millisecond},
-        description: "The time spent waiting for a database connection"
-      ),
-      summary("cms.repo.query.idle_time",
-        unit: {:native, :millisecond},
-        description: "The time the connection spent waiting before being checked out for the query"
-      ),
-
-      # VM Metrics
-      summary("vm.memory.total", unit: {:byte, :kilobyte}),
-      summary("vm.total_run_queue_lengths.total"),
-      summary("vm.total_run_queue_lengths.cpu"),
-      summary("vm.total_run_queue_lengths.io")
-    ]
-  end
-
-  defp periodic_measurements do
-    [
-      # A module, function and arguments to be invoked periodically.
-      # This function must call :telemetry.execute/3 and a metric must be added above.
-      # {CMSWeb, :count_users, []}
-    ]
-  end
-end
diff --git a/lib/core.ex b/lib/core.ex
new file mode 100644
index 0000000..0ba92d0
--- /dev/null
+++ b/lib/core.ex
@@ -0,0 +1,4 @@
+defmodule Core do
+  @moduledoc false
+  use Boundary, deps: [Schema], exports: [Author, Posts, Statuses]
+end
diff --git a/lib/cms/author.ex b/lib/core/author.ex
similarity index 93%
rename from lib/cms/author.ex
rename to lib/core/author.ex
index 65e38a2..6ec9eef 100644
--- a/lib/cms/author.ex
+++ b/lib/core/author.ex
@@ -1,4 +1,4 @@
-defmodule CMS.Author do
+defmodule Core.Author do
   @moduledoc """
   Properties of the author, Sloane
 
@@ -26,7 +26,7 @@ defmodule CMS.Author do
       given_name: "Sloane",
       additional_name: "Loretta",
       family_name: "Perrault",
-      nickname: "sloanelybutsurely",
+      nickname: "sloanely_but_surely",
       email: "sloane@fastmail.com",
       url: "https://sloanelybutsurely.com"
     }
diff --git a/lib/core/posts.ex b/lib/core/posts.ex
new file mode 100644
index 0000000..e674b08
--- /dev/null
+++ b/lib/core/posts.ex
@@ -0,0 +1,37 @@
+defmodule Core.Posts do
+  @moduledoc false
+  import Ecto.Changeset
+  import Ecto.Query
+
+  alias Core.Repo
+
+  def changeset(%Schema.Post{} = post, attrs) do
+    post
+    |> cast(attrs, [:title, :body])
+    |> validate_required([:body])
+  end
+
+  def create_post(attrs) do
+    %Schema.Post{}
+    |> changeset(attrs)
+    |> Repo.insert()
+  end
+
+  def update_post(post, attrs) do
+    post
+    |> changeset(attrs)
+    |> Repo.update()
+  end
+
+  def get_post!(id) do
+    Repo.get!(Schema.Post, id)
+  end
+
+  def list_posts do
+    query =
+      from post in Schema.Post,
+        order_by: [desc: post.inserted_at]
+
+    Repo.all(query)
+  end
+end
diff --git a/lib/core/repo.ex b/lib/core/repo.ex
new file mode 100644
index 0000000..ae02811
--- /dev/null
+++ b/lib/core/repo.ex
@@ -0,0 +1,5 @@
+defmodule Core.Repo do
+  use Ecto.Repo,
+    otp_app: :sloanely_but_surely,
+    adapter: Ecto.Adapters.Postgres
+end
diff --git a/lib/core/statuses.ex b/lib/core/statuses.ex
new file mode 100644
index 0000000..bf9827c
--- /dev/null
+++ b/lib/core/statuses.ex
@@ -0,0 +1,37 @@
+defmodule Core.Statuses do
+  @moduledoc false
+  import Ecto.Changeset
+  import Ecto.Query
+
+  alias Core.Repo
+
+  def changeset(%Schema.Status{} = status, attrs \\ %{}) do
+    status
+    |> cast(attrs, [:body])
+    |> validate_required([:body])
+  end
+
+  def create_status(attrs) do
+    %Schema.Status{}
+    |> changeset(attrs)
+    |> Repo.insert()
+  end
+
+  def update_status(status, attrs) do
+    status
+    |> changeset(attrs)
+    |> Repo.update()
+  end
+
+  def get_status!(id) do
+    Repo.get!(Schema.Status, id)
+  end
+
+  def list_statuses do
+    query =
+      from status in Schema.Status,
+        order_by: [desc: status.inserted_at]
+
+    Repo.all(query)
+  end
+end
diff --git a/lib/mix/tasks/cms.gen.password_hash.ex b/lib/mix/tasks/sloanely_but_surely.gen.password_hash.ex
similarity index 84%
rename from lib/mix/tasks/cms.gen.password_hash.ex
rename to lib/mix/tasks/sloanely_but_surely.gen.password_hash.ex
index 8dfab3c..699ab8c 100644
--- a/lib/mix/tasks/cms.gen.password_hash.ex
+++ b/lib/mix/tasks/sloanely_but_surely.gen.password_hash.ex
@@ -1,8 +1,9 @@
-defmodule Mix.Tasks.Cms.Gen.PasswordHash do
+defmodule Mix.Tasks.SloanelyButSurely.Gen.PasswordHash do
   @shortdoc @moduledoc
   @moduledoc """
   Hashes a password for the admin account
   """
+  use Boundary, classify_to: SloanelyButSurely.Mix
   use Mix.Task
 
   @impl Mix.Task
diff --git a/lib/schema.ex b/lib/schema.ex
new file mode 100644
index 0000000..a23bc07
--- /dev/null
+++ b/lib/schema.ex
@@ -0,0 +1,4 @@
+defmodule Schema do
+  @moduledoc false
+  use Boundary, deps: [], exports: [Post, Status]
+end
diff --git a/lib/schema/post.ex b/lib/schema/post.ex
new file mode 100644
index 0000000..f61ca39
--- /dev/null
+++ b/lib/schema/post.ex
@@ -0,0 +1,12 @@
+defmodule Schema.Post do
+  @moduledoc false
+  use Ecto.Schema
+
+  @primary_key {:id, :binary_id, autogenerate: true}
+  schema "posts" do
+    field :title, :string
+    field :body, :string
+
+    timestamps()
+  end
+end
diff --git a/lib/schema/status.ex b/lib/schema/status.ex
new file mode 100644
index 0000000..b7d2feb
--- /dev/null
+++ b/lib/schema/status.ex
@@ -0,0 +1,11 @@
+defmodule Schema.Status do
+  @moduledoc false
+  use Ecto.Schema
+
+  @primary_key {:id, :binary_id, autogenerate: true}
+  schema "statuses" do
+    field :body
+
+    timestamps()
+  end
+end
diff --git a/lib/sloanely_but_surely.ex b/lib/sloanely_but_surely.ex
new file mode 100644
index 0000000..833a630
--- /dev/null
+++ b/lib/sloanely_but_surely.ex
@@ -0,0 +1,4 @@
+defmodule SloanelyButSurely do
+  @moduledoc false
+  use Boundary, top_level?: true, deps: [Core, Web]
+end
diff --git a/lib/sloanely_but_surely/application.ex b/lib/sloanely_but_surely/application.ex
new file mode 100644
index 0000000..c21a035
--- /dev/null
+++ b/lib/sloanely_but_surely/application.ex
@@ -0,0 +1,21 @@
+defmodule SloanelyButSurely.Application do
+  @moduledoc false
+  use Application
+
+  @impl Application
+  def start(_type, _args) do
+    children = [
+      Core.Repo,
+      {Phoenix.PubSub, name: Core.PubSub},
+      Web.Endpoint
+    ]
+
+    Supervisor.start_link(children, strategy: :one_for_one, name: Core.Supervisor)
+  end
+
+  @impl Application
+  def config_change(changed, _new, removed) do
+    Web.Endpoint.config_change(changed, removed)
+    :ok
+  end
+end
diff --git a/lib/sloanely_but_surely/mix.ex b/lib/sloanely_but_surely/mix.ex
new file mode 100644
index 0000000..f34549e
--- /dev/null
+++ b/lib/sloanely_but_surely/mix.ex
@@ -0,0 +1,4 @@
+defmodule SloanelyButSurely.Mix do
+  @moduledoc false
+  use Boundary, deps: [], exports: []
+end
diff --git a/lib/cms_web.ex b/lib/web.ex
similarity index 68%
rename from lib/cms_web.ex
rename to lib/web.ex
index d00f5ad..9d2fdee 100644
--- a/lib/cms_web.ex
+++ b/lib/web.ex
@@ -1,21 +1,6 @@
-defmodule CMSWeb do
-  @moduledoc """
-  The entrypoint for defining your web interface, such
-  as controllers, components, channels, and so on.
-
-  This can be used in your application as:
-
-      use CMSWeb, :controller
-      use CMSWeb, :html
-
-  The definitions below will be executed for every controller,
-  component, etc, so keep them short and clean, focused
-  on imports, uses and aliases.
-
-  Do NOT define functions inside the quoted expressions
-  below. Instead, define additional modules and import
-  those modules here.
-  """
+defmodule Web do
+  @moduledoc false
+  use Boundary, deps: [Core, Schema], exports: [Endpoint]
 
   def static_paths, do: ~w(assets fonts images favicon.ico robots.txt)
 
@@ -41,7 +26,7 @@ defmodule CMSWeb do
     quote do
       use Phoenix.Controller,
         formats: [:html, :json],
-        layouts: [html: CMSWeb.Layouts]
+        layouts: [html: Web.Layouts]
 
       import Plug.Conn
 
@@ -52,7 +37,7 @@ defmodule CMSWeb do
   def live_view do
     quote do
       use Phoenix.LiveView,
-        layout: {CMSWeb.Layouts, :app}
+        layout: {Web.Layouts, :app}
 
       unquote(html_helpers())
     end
@@ -81,9 +66,9 @@ defmodule CMSWeb do
 
   defp html_helpers do
     quote do
-      import CMSWeb.CoreComponents
-      # HTML escaping functionality
       import Phoenix.HTML
+      import Web.CoreComponents
+      # HTML escaping functionality
       # Core UI components
 
       # Shortcut for generating JS commands
@@ -97,9 +82,9 @@ defmodule CMSWeb do
   def verified_routes do
     quote do
       use Phoenix.VerifiedRoutes,
-        endpoint: CMSWeb.Endpoint,
-        router: CMSWeb.Router,
-        statics: CMSWeb.static_paths()
+        endpoint: Web.Endpoint,
+        router: Web.Router,
+        statics: Web.static_paths()
     end
   end
 
diff --git a/lib/cms_web/components/core_components.ex b/lib/web/components/core_components.ex
similarity index 99%
rename from lib/cms_web/components/core_components.ex
rename to lib/web/components/core_components.ex
index 70f31e3..cfdd2a9 100644
--- a/lib/cms_web/components/core_components.ex
+++ b/lib/web/components/core_components.ex
@@ -1,4 +1,4 @@
-defmodule CMSWeb.CoreComponents do
+defmodule Web.CoreComponents do
   @moduledoc """
   Provides core UI components.
   """
diff --git a/lib/cms_web/components/layouts.ex b/lib/web/components/layouts.ex
similarity index 78%
rename from lib/cms_web/components/layouts.ex
rename to lib/web/components/layouts.ex
index 4ceac28..7ed0d51 100644
--- a/lib/cms_web/components/layouts.ex
+++ b/lib/web/components/layouts.ex
@@ -1,14 +1,13 @@
-defmodule CMSWeb.Layouts do
+defmodule Web.Layouts do
   @moduledoc """
   This module holds different layouts used by your application.
 
   See the `layouts` directory for all templates available.
   The "root" layout is a skeleton rendered as part of the
   application router. The "app" layout is set as the default
-  layout on both `use CMSWeb, :controller` and
-  `use CMSWeb, :live_view`.
+  layout on both `use Web, :controller` and `use Web, :live_view`.
   """
-  use CMSWeb, :html
+  use Web, :html
 
   embed_templates "layouts/*"
 
diff --git a/lib/cms_web/components/layouts/app.html.heex b/lib/web/components/layouts/app.html.heex
similarity index 100%
rename from lib/cms_web/components/layouts/app.html.heex
rename to lib/web/components/layouts/app.html.heex
diff --git a/lib/cms_web/components/layouts/root.html.heex b/lib/web/components/layouts/root.html.heex
similarity index 100%
rename from lib/cms_web/components/layouts/root.html.heex
rename to lib/web/components/layouts/root.html.heex
diff --git a/lib/cms_web/controllers/admin_auth.ex b/lib/web/controllers/admin_auth.ex
similarity index 86%
rename from lib/cms_web/controllers/admin_auth.ex
rename to lib/web/controllers/admin_auth.ex
index e671dc6..40da948 100644
--- a/lib/cms_web/controllers/admin_auth.ex
+++ b/lib/web/controllers/admin_auth.ex
@@ -1,6 +1,6 @@
-defmodule CMSWeb.AdminAuth do
+defmodule Web.AdminAuth do
   @moduledoc false
-  use CMSWeb, :verified_routes
+  use Web, :verified_routes
 
   import Phoenix.Controller
   import Plug.Conn
@@ -14,7 +14,7 @@ defmodule CMSWeb.AdminAuth do
 
   def log_out_admin(conn, params) do
     if live_socket_id = get_session(conn, :live_socket_id) do
-      CMSWeb.Endpoint.broadcast(live_socket_id, "disconnect", %{})
+      Web.Endpoint.broadcast(live_socket_id, "disconnect", %{})
     end
 
     conn
@@ -35,7 +35,7 @@ defmodule CMSWeb.AdminAuth do
   end
 
   def correct_password?(password) do
-    password_hash = Application.fetch_env!(:cms, :password_hash)
+    password_hash = Application.fetch_env!(:sloanely_but_surely, :password_hash)
 
     Argon2.verify_pass(password, password_hash)
   end
diff --git a/lib/cms_web/controllers/admin_session_controller.ex b/lib/web/controllers/admin_session_controller.ex
similarity index 79%
rename from lib/cms_web/controllers/admin_session_controller.ex
rename to lib/web/controllers/admin_session_controller.ex
index a205f39..1b5e913 100644
--- a/lib/cms_web/controllers/admin_session_controller.ex
+++ b/lib/web/controllers/admin_session_controller.ex
@@ -1,7 +1,7 @@
-defmodule CMSWeb.AdminSessionController do
-  use CMSWeb, :controller
+defmodule Web.AdminSessionController do
+  use Web, :controller
 
-  alias CMSWeb.AdminAuth
+  alias Web.AdminAuth
 
   def create(conn, %{"password" => password} = params) do
     if AdminAuth.correct_password?(password) do
diff --git a/lib/cms_web/controllers/error_html.ex b/lib/web/controllers/error_html.ex
similarity index 92%
rename from lib/cms_web/controllers/error_html.ex
rename to lib/web/controllers/error_html.ex
index d855081..2c93991 100644
--- a/lib/cms_web/controllers/error_html.ex
+++ b/lib/web/controllers/error_html.ex
@@ -1,10 +1,10 @@
-defmodule CMSWeb.ErrorHTML do
+defmodule Web.ErrorHTML do
   @moduledoc """
   This module is invoked by your endpoint in case of errors on HTML requests.
 
   See config/config.exs.
   """
-  use CMSWeb, :html
+  use Web, :html
 
   # If you want to customize your error pages,
   # uncomment the embed_templates/1 call below
diff --git a/lib/cms_web/controllers/error_json.ex b/lib/web/controllers/error_json.ex
similarity index 95%
rename from lib/cms_web/controllers/error_json.ex
rename to lib/web/controllers/error_json.ex
index 2aad2f8..d27986a 100644
--- a/lib/cms_web/controllers/error_json.ex
+++ b/lib/web/controllers/error_json.ex
@@ -1,4 +1,4 @@
-defmodule CMSWeb.ErrorJSON do
+defmodule Web.ErrorJSON do
   @moduledoc """
   This module is invoked by your endpoint in case of errors on JSON requests.
 
diff --git a/lib/cms_web/controllers/globals.ex b/lib/web/controllers/globals.ex
similarity index 91%
rename from lib/cms_web/controllers/globals.ex
rename to lib/web/controllers/globals.ex
index b79931d..f45728a 100644
--- a/lib/cms_web/controllers/globals.ex
+++ b/lib/web/controllers/globals.ex
@@ -1,6 +1,6 @@
-defmodule CMSWeb.Globals do
+defmodule Web.Globals do
   @moduledoc false
-  use CMSWeb, :live_view
+  use Web, :live_view
 
   def assign_globals(%Plug.Conn{} = conn, _opts) do
     conn
diff --git a/lib/web/controllers/page_controller.ex b/lib/web/controllers/page_controller.ex
new file mode 100644
index 0000000..d35f827
--- /dev/null
+++ b/lib/web/controllers/page_controller.ex
@@ -0,0 +1,13 @@
+defmodule Web.PageController do
+  use Web, :controller
+
+  def home(conn, _params) do
+    posts = Enum.take(Core.Posts.list_posts(), 5)
+    statuses = Enum.take(Core.Statuses.list_statuses(), 10)
+
+    conn
+    |> assign(:posts, posts)
+    |> assign(:statuses, statuses)
+    |> render(:home)
+  end
+end
diff --git a/lib/cms_web/controllers/page_html.ex b/lib/web/controllers/page_html.ex
similarity index 78%
rename from lib/cms_web/controllers/page_html.ex
rename to lib/web/controllers/page_html.ex
index f682d22..70589f4 100644
--- a/lib/cms_web/controllers/page_html.ex
+++ b/lib/web/controllers/page_html.ex
@@ -1,10 +1,10 @@
-defmodule CMSWeb.PageHTML do
+defmodule Web.PageHTML do
   @moduledoc """
   This module contains pages rendered by PageController.
 
   See the `page_html` directory for all templates available.
   """
-  use CMSWeb, :html
+  use Web, :html
 
   embed_templates "page_html/*"
 end
diff --git a/lib/cms_web/controllers/page_html/home.html.heex b/lib/web/controllers/page_html/home.html.heex
similarity index 100%
rename from lib/cms_web/controllers/page_html/home.html.heex
rename to lib/web/controllers/page_html/home.html.heex
diff --git a/lib/cms_web/controllers/post_controller.ex b/lib/web/controllers/post_controller.ex
similarity index 59%
rename from lib/cms_web/controllers/post_controller.ex
rename to lib/web/controllers/post_controller.ex
index 22b3b62..181261b 100644
--- a/lib/cms_web/controllers/post_controller.ex
+++ b/lib/web/controllers/post_controller.ex
@@ -1,10 +1,8 @@
-defmodule CMSWeb.PostController do
-  use CMSWeb, :controller
-
-  alias CMS.Posts
+defmodule Web.PostController do
+  use Web, :controller
 
   def index(conn, _params) do
-    posts = Posts.list_posts()
+    posts = Core.Posts.list_posts()
 
     conn
     |> assign(:posts, posts)
@@ -12,7 +10,7 @@ defmodule CMSWeb.PostController do
   end
 
   def show(conn, %{"post_id" => post_id}) do
-    post = Posts.get_post!(post_id)
+    post = Core.Posts.get_post!(post_id)
 
     conn
     |> assign(:post, post)
diff --git a/lib/cms_web/controllers/post_html.ex b/lib/web/controllers/post_html.ex
similarity index 53%
rename from lib/cms_web/controllers/post_html.ex
rename to lib/web/controllers/post_html.ex
index f3f2082..c7cf197 100644
--- a/lib/cms_web/controllers/post_html.ex
+++ b/lib/web/controllers/post_html.ex
@@ -1,6 +1,6 @@
-defmodule CMSWeb.PostHTML do
+defmodule Web.PostHTML do
   @moduledoc false
-  use CMSWeb, :html
+  use Web, :html
 
   embed_templates "post_html/*"
 end
diff --git a/lib/cms_web/controllers/post_html/index.html.heex b/lib/web/controllers/post_html/index.html.heex
similarity index 100%
rename from lib/cms_web/controllers/post_html/index.html.heex
rename to lib/web/controllers/post_html/index.html.heex
diff --git a/lib/cms_web/controllers/post_html/show.html.heex b/lib/web/controllers/post_html/show.html.heex
similarity index 100%
rename from lib/cms_web/controllers/post_html/show.html.heex
rename to lib/web/controllers/post_html/show.html.heex
diff --git a/lib/cms_web/controllers/status_controller.ex b/lib/web/controllers/status_controller.ex
similarity index 57%
rename from lib/cms_web/controllers/status_controller.ex
rename to lib/web/controllers/status_controller.ex
index 6bf211e..7c8798e 100644
--- a/lib/cms_web/controllers/status_controller.ex
+++ b/lib/web/controllers/status_controller.ex
@@ -1,10 +1,8 @@
-defmodule CMSWeb.StatusController do
-  use CMSWeb, :controller
-
-  alias CMS.Statuses
+defmodule Web.StatusController do
+  use Web, :controller
 
   def index(conn, _params) do
-    statuses = Statuses.list_statuses()
+    statuses = Core.Statuses.list_statuses()
 
     conn
     |> assign(:statuses, statuses)
@@ -12,7 +10,7 @@ defmodule CMSWeb.StatusController do
   end
 
   def show(conn, %{"status_id" => status_id}) do
-    status = Statuses.get_status!(status_id)
+    status = Core.Statuses.get_status!(status_id)
 
     conn
     |> assign(:status, status)
diff --git a/lib/cms_web/controllers/status_html.ex b/lib/web/controllers/status_html.ex
similarity index 53%
rename from lib/cms_web/controllers/status_html.ex
rename to lib/web/controllers/status_html.ex
index e92f149..e99f601 100644
--- a/lib/cms_web/controllers/status_html.ex
+++ b/lib/web/controllers/status_html.ex
@@ -1,6 +1,6 @@
-defmodule CMSWeb.StatusHTML do
+defmodule Web.StatusHTML do
   @moduledoc false
-  use CMSWeb, :html
+  use Web, :html
 
   embed_templates "status_html/*"
 end
diff --git a/lib/cms_web/controllers/status_html/index.html.heex b/lib/web/controllers/status_html/index.html.heex
similarity index 100%
rename from lib/cms_web/controllers/status_html/index.html.heex
rename to lib/web/controllers/status_html/index.html.heex
diff --git a/lib/cms_web/controllers/status_html/show.html.heex b/lib/web/controllers/status_html/show.html.heex
similarity index 100%
rename from lib/cms_web/controllers/status_html/show.html.heex
rename to lib/web/controllers/status_html/show.html.heex
diff --git a/lib/cms_web/endpoint.ex b/lib/web/endpoint.ex
similarity index 85%
rename from lib/cms_web/endpoint.ex
rename to lib/web/endpoint.ex
index ea98ace..80608e7 100644
--- a/lib/cms_web/endpoint.ex
+++ b/lib/web/endpoint.ex
@@ -1,5 +1,5 @@
-defmodule CMSWeb.Endpoint do
-  use Phoenix.Endpoint, otp_app: :cms
+defmodule Web.Endpoint do
+  use Phoenix.Endpoint, otp_app: :sloanely_but_surely
 
   # The session will be stored in the cookie and signed,
   # this means its contents can be read but not tampered with.
@@ -21,9 +21,9 @@ defmodule CMSWeb.Endpoint do
   # when deploying your static files in production.
   plug Plug.Static,
     at: "/",
-    from: :cms,
+    from: :sloanely_but_surely,
     gzip: false,
-    only: CMSWeb.static_paths()
+    only: Web.static_paths()
 
   # Code reloading can be explicitly enabled under the
   # :code_reloader configuration of your endpoint.
@@ -31,7 +31,7 @@ defmodule CMSWeb.Endpoint do
     socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
     plug Phoenix.LiveReloader
     plug Phoenix.CodeReloader
-    plug Phoenix.Ecto.CheckRepoStatus, otp_app: :cms
+    plug Phoenix.Ecto.CheckRepoStatus, otp_app: :sloanely_but_surely
   end
 
   plug Phoenix.LiveDashboard.RequestLogger,
@@ -49,5 +49,5 @@ defmodule CMSWeb.Endpoint do
   plug Plug.MethodOverride
   plug Plug.Head
   plug Plug.Session, @session_options
-  plug CMSWeb.Router
+  plug Web.Router
 end
diff --git a/lib/cms_web/live/admin_live.ex b/lib/web/live/admin_live.ex
similarity index 77%
rename from lib/cms_web/live/admin_live.ex
rename to lib/web/live/admin_live.ex
index 8ae7075..3f6bc13 100644
--- a/lib/cms_web/live/admin_live.ex
+++ b/lib/web/live/admin_live.ex
@@ -1,6 +1,6 @@
-defmodule CMSWeb.AdminLive do
+defmodule Web.AdminLive do
   @moduledoc false
-  use CMSWeb, :live_view
+  use Web, :live_view
 
   @impl true
   def mount(_params, _session, socket) do
diff --git a/lib/cms_web/live/admin_login_live.ex b/lib/web/live/admin_login_live.ex
similarity index 94%
rename from lib/cms_web/live/admin_login_live.ex
rename to lib/web/live/admin_login_live.ex
index 9af7136..1f94232 100644
--- a/lib/cms_web/live/admin_login_live.ex
+++ b/lib/web/live/admin_login_live.ex
@@ -1,6 +1,6 @@
-defmodule CMSWeb.AdminLoginLive do
+defmodule Web.AdminLoginLive do
   @moduledoc false
-  use CMSWeb, :live_view
+  use Web, :live_view
 
   @impl true
   def mount(params, _session, socket) do
diff --git a/lib/cms_web/live/post_live.ex b/lib/web/live/post_live.ex
similarity index 77%
rename from lib/cms_web/live/post_live.ex
rename to lib/web/live/post_live.ex
index d47e53a..dcb7bef 100644
--- a/lib/cms_web/live/post_live.ex
+++ b/lib/web/live/post_live.ex
@@ -1,9 +1,6 @@
-defmodule CMSWeb.PostLive do
+defmodule Web.PostLive do
   @moduledoc false
-  use CMSWeb, :live_view
-
-  alias CMS.Posts
-  alias CMS.Posts.Post
+  use Web, :live_view
 
   @impl true
   def mount(_params, _session, socket) do
@@ -14,8 +11,8 @@ defmodule CMSWeb.PostLive do
 
   @impl true
   def handle_params(_params, _uri, %{assigns: %{live_action: :new}} = socket) do
-    post = %Post{}
-    changeset = Post.changeset(post)
+    post = %Schema.Post{}
+    changeset = Core.Posts.changeset(post, %{})
 
     socket = assign(socket, post: post, form: to_form(changeset))
 
@@ -23,9 +20,9 @@ defmodule CMSWeb.PostLive do
   end
 
   def handle_params(%{"post_id" => post_id}, _uri, %{assigns: %{live_action: :edit}} = socket) do
-    post = Posts.get_post!(post_id)
+    post = Core.Posts.get_post!(post_id)
 
-    changeset = Post.changeset(post)
+    changeset = Core.Posts.changeset(post, %{})
 
     socket = assign(socket, post: post, form: to_form(changeset))
 
@@ -35,7 +32,7 @@ defmodule CMSWeb.PostLive do
   @impl true
   def handle_event("save_post", %{"post" => attrs}, %{assigns: %{live_action: :new}} = socket) do
     socket =
-      case Posts.create_post(attrs) do
+      case Core.Posts.create_post(attrs) do
         {:ok, post} -> push_navigate(socket, to: ~p"/admin/posts/#{post}")
         {:error, changeset} -> assign(socket, form: to_form(changeset))
       end
@@ -45,9 +42,15 @@ defmodule CMSWeb.PostLive do
 
   def handle_event("save_post", %{"post" => attrs}, %{assigns: %{post: post, live_action: :edit}} = socket) do
     socket =
-      case Posts.update_post(post, attrs) do
+      case Core.Posts.update_post(post, attrs) do
         {:ok, post} ->
-          assign(socket, post: post, form: post |> Post.changeset() |> to_form())
+          assign(socket,
+            post: post,
+            form:
+              post
+              |> Core.Posts.changeset(%{})
+              |> to_form()
+          )
 
         {:error, changeset} ->
           assign(socket, form: to_form(changeset))
diff --git a/lib/cms_web/live/status_live.ex b/lib/web/live/status_live.ex
similarity index 66%
rename from lib/cms_web/live/status_live.ex
rename to lib/web/live/status_live.ex
index 563021e..bbfc028 100644
--- a/lib/cms_web/live/status_live.ex
+++ b/lib/web/live/status_live.ex
@@ -1,9 +1,6 @@
-defmodule CMSWeb.StatusLive do
+defmodule Web.StatusLive do
   @moduledoc false
-  use CMSWeb, :live_view
-
-  alias CMS.Statuses
-  alias CMS.Statuses.Status
+  use Web, :live_view
 
   @impl true
   def mount(_params, _session, socket) do
@@ -12,9 +9,9 @@ defmodule CMSWeb.StatusLive do
 
   @impl true
   def handle_params(_params, _uri, %{assigns: %{live_action: :new}} = socket) do
-    status = %Status{}
+    status = %Schema.Status{}
 
-    changeset = Status.changeset(status)
+    changeset = Core.Statuses.changeset(status, %{})
 
     socket = assign(socket, status: status, form: to_form(changeset))
 
@@ -22,9 +19,9 @@ defmodule CMSWeb.StatusLive do
   end
 
   def handle_params(%{"status_id" => status_id}, _uri, %{assigns: %{live_action: :edit}} = socket) do
-    status = Statuses.get_status!(status_id)
+    status = Core.Statuses.get_status!(status_id)
 
-    changeset = Status.changeset(status)
+    changeset = Core.Statuses.changeset(status, %{})
 
     socket = assign(socket, status: status, form: to_form(changeset))
 
@@ -34,7 +31,7 @@ defmodule CMSWeb.StatusLive do
   @impl true
   def handle_event("save_status", %{"status" => attrs}, %{assigns: %{live_action: :new}} = socket) do
     socket =
-      case Statuses.create_status(attrs) do
+      case Core.Statuses.create_status(attrs) do
         {:ok, status} -> push_navigate(socket, to: ~p"/admin/statuses/#{status}")
         {:error, changeset} -> assign(socket, form: to_form(changeset))
       end
@@ -42,15 +39,17 @@ defmodule CMSWeb.StatusLive do
     {:noreply, socket}
   end
 
-  def handle_event(
-        "save_status",
-        %{"status" => attrs},
-        %{assigns: %{status: status, live_action: :edit}} = socket
-      ) do
+  def handle_event("save_status", %{"status" => attrs}, %{assigns: %{status: status, live_action: :edit}} = socket) do
     socket =
-      case Statuses.update_status(status, attrs) do
+      case Core.Statuses.update_status(status, attrs) do
         {:ok, status} ->
-          assign(socket, status: status, form: to_form(Status.changeset(status)))
+          assign(socket,
+            status: status,
+            form:
+              status
+              |> Core.Statuses.changeset(%{})
+              |> to_form()
+          )
 
         {:error, changeset} ->
           assign(socket, form: to_form(changeset))
diff --git a/lib/cms_web/router.ex b/lib/web/router.ex
similarity index 58%
rename from lib/cms_web/router.ex
rename to lib/web/router.ex
index 4d87d96..319c7db 100644
--- a/lib/cms_web/router.ex
+++ b/lib/web/router.ex
@@ -1,17 +1,17 @@
-defmodule CMSWeb.Router do
-  use CMSWeb, :router
+defmodule Web.Router do
+  use Web, :router
 
-  import CMSWeb.AdminAuth
-  import CMSWeb.Globals
+  import Web.AdminAuth
+  import Web.Globals
 
-  alias CMSWeb.AdminAuth
-  alias CMSWeb.Globals
+  alias Web.AdminAuth
+  alias Web.Globals
 
   pipeline :browser do
     plug :accepts, ["html"]
     plug :fetch_session
     plug :fetch_live_flash
-    plug :put_root_layout, html: {CMSWeb.Layouts, :root}
+    plug :put_root_layout, html: {Web.Layouts, :root}
     plug :protect_from_forgery
     plug :put_secure_browser_headers
     plug :assign_globals
@@ -27,7 +27,7 @@ defmodule CMSWeb.Router do
   end
 
   live_session :default, on_mount: [AdminAuth, Globals] do
-    scope "/", CMSWeb do
+    scope "/", Web do
       pipe_through :browser
       pipe_through :supports_admin_action
 
@@ -44,7 +44,7 @@ defmodule CMSWeb.Router do
       get "/admin/session/destroy", AdminSessionController, :destroy
     end
 
-    scope "/admin", CMSWeb do
+    scope "/admin", Web do
       pipe_through :browser
       pipe_through :requires_admin
 
@@ -57,20 +57,4 @@ defmodule CMSWeb.Router do
       live "/statuses/:status_id", StatusLive, :edit
     end
   end
-
-  # Enable LiveDashboard in development
-  if Application.compile_env(:cms, :dev_routes) do
-    # If you want to use the LiveDashboard in production, you should put
-    # it behind authentication and allow only admins to access it.
-    # If your application does not have an admins-only section yet,
-    # you can use Plug.BasicAuth to set up some basic authentication
-    # as long as you are also using SSL (which you should anyway).
-    import Phoenix.LiveDashboard.Router
-
-    scope "/dev" do
-      pipe_through :browser
-
-      live_dashboard "/dashboard", metrics: CMSWeb.Telemetry
-    end
-  end
 end
diff --git a/mix.exs b/mix.exs
index 1a94067..d068189 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,12 +1,13 @@
-defmodule CMS.MixProject do
+defmodule SlaonelyButSurely.MixProject do
   use Mix.Project
 
   def project do
     [
-      app: :cms,
-      version: "0.1.0",
+      app: :sloanely_but_surely,
+      version: "1.0.0",
       elixir: "~> 1.14",
       elixirc_paths: elixirc_paths(Mix.env()),
+      compilers: [:boundary] ++ Mix.compilers(),
       start_permanent: Mix.env() == :prod,
       aliases: aliases(),
       deps: deps()
@@ -18,7 +19,7 @@ defmodule CMS.MixProject do
   # Type `mix help compile.app` for more information.
   def application do
     [
-      mod: {CMS.Application, []},
+      mod: {SloanelyButSurely.Application, []},
       extra_applications: [:logger, :runtime_tools]
     ]
   end
@@ -48,14 +49,14 @@ defmodule CMS.MixProject do
       {:telemetry_metrics, "~> 1.0"},
       {:telemetry_poller, "~> 1.0"},
       {:jason, "~> 1.2"},
-      {:dns_cluster, "~> 0.1.1"},
       {:bandit, "~> 1.5"},
       {:argon2_elixir, "~> 4.1"},
       {:timex, "~> 3.7"},
       {:typed_struct, "~> 0.3.0"},
 
       # dev/test only
-      {:styler, "~> 1.4", only: [:dev, :test], runtime: false}
+      {:styler, "~> 1.4", only: [:dev, :test], runtime: false},
+      {:boundary, "~> 0.10.4"}
     ]
   end
 
diff --git a/mix.lock b/mix.lock
index c80adeb..fce0b88 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,6 +1,7 @@
 %{
   "argon2_elixir": {:hex, :argon2_elixir, "4.1.2", "1160a3ccd59b951175525882240651f5ed3303b75c616204713f8b31c76b37bd", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "9222341e1b0d9aa5ca7e26a1c77bd1bd92d2314c92b57ca3e2c7ed847223b51d"},
   "bandit": {:hex, :bandit, "1.6.7", "42f30e37a1c89a2a12943c5dca76f731a2313e8a2e21c1a95dc8241893e922d1", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "551ba8ff5e4fc908cbeb8c9f0697775fb6813a96d9de5f7fe02e34e76fd7d184"},
+  "boundary": {:hex, :boundary, "0.10.4", "5fec5d2736c12f9bfe1720c3a2bd8c48c3547c24d6002ebf8e087570afd5bd2f", [:mix], [], "hexpm", "8baf6f23987afdb1483033ed0bde75c9c703613c22ed58d5f23bf948f203247c"},
   "castore": {:hex, :castore, "1.0.11", "4bbd584741601eb658007339ea730b082cc61f3554cf2e8f39bf693a11b49073", [:mix], [], "hexpm", "e03990b4db988df56262852f20de0f659871c35154691427a5047f4967a16a62"},
   "certifi": {:hex, :certifi, "2.14.0", "ed3bef654e69cde5e6c022df8070a579a79e8ba2368a00acf3d75b82d9aceeed", [:rebar3], [], "hexpm", "ea59d87ef89da429b8e905264fdec3419f84f2215bb3d81e07a18aac919026c3"},
   "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
diff --git a/priv/repo/migrations/20250222164951_add_posts_table.exs b/priv/repo/migrations/20250222164951_add_posts_table.exs
index e424163..2ab8d7b 100644
--- a/priv/repo/migrations/20250222164951_add_posts_table.exs
+++ b/priv/repo/migrations/20250222164951_add_posts_table.exs
@@ -1,4 +1,4 @@
-defmodule CMS.Repo.Migrations.AddPostsTable do
+defmodule Core.Repo.Migrations.AddPostsTable do
   use Ecto.Migration
 
   def change do
diff --git a/priv/repo/migrations/20250222201807_add_statuses_table.exs b/priv/repo/migrations/20250222201807_add_statuses_table.exs
index e57fab2..6b6d69a 100644
--- a/priv/repo/migrations/20250222201807_add_statuses_table.exs
+++ b/priv/repo/migrations/20250222201807_add_statuses_table.exs
@@ -1,4 +1,4 @@
-defmodule CMS.Repo.Migrations.AddStatusesTable do
+defmodule Core.Repo.Migrations.AddStatusesTable do
   use Ecto.Migration
 
   def change do
diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs
index 58b0e6b..a1b3017 100644
--- a/priv/repo/seeds.exs
+++ b/priv/repo/seeds.exs
@@ -5,7 +5,7 @@
 # Inside the script, you can read and write to any of your
 # repositories directly:
 #
-#     CMS.Repo.insert!(%CMS.SomeSchema{})
+#     Core.Repo.insert!(%CMS.SomeSchema{})
 #
 # We recommend using the bang functions (`insert!`, `update!`
 # and so on) as they will fail if something goes wrong.
diff --git a/test/cms_web/controllers/error_html_test.exs b/test/cms_web/controllers/error_html_test.exs
deleted file mode 100644
index 6789eb3..0000000
--- a/test/cms_web/controllers/error_html_test.exs
+++ /dev/null
@@ -1,14 +0,0 @@
-defmodule CMSWeb.ErrorHTMLTest do
-  use CMSWeb.ConnCase, async: true
-
-  # Bring render_to_string/4 for testing custom views
-  import Phoenix.Template
-
-  test "renders 404.html" do
-    assert render_to_string(CMSWeb.ErrorHTML, "404", "html", []) == "Not Found"
-  end
-
-  test "renders 500.html" do
-    assert render_to_string(CMSWeb.ErrorHTML, "500", "html", []) == "Internal Server Error"
-  end
-end
diff --git a/test/cms_web/controllers/error_json_test.exs b/test/cms_web/controllers/error_json_test.exs
deleted file mode 100644
index a289796..0000000
--- a/test/cms_web/controllers/error_json_test.exs
+++ /dev/null
@@ -1,12 +0,0 @@
-defmodule CMSWeb.ErrorJSONTest do
-  use CMSWeb.ConnCase, async: true
-
-  test "renders 404" do
-    assert CMSWeb.ErrorJSON.render("404.json", %{}) == %{errors: %{detail: "Not Found"}}
-  end
-
-  test "renders 500" do
-    assert CMSWeb.ErrorJSON.render("500.json", %{}) ==
-             %{errors: %{detail: "Internal Server Error"}}
-  end
-end
diff --git a/test/cms_web/controllers/page_controller_test.exs b/test/cms_web/controllers/page_controller_test.exs
deleted file mode 100644
index 6eea161..0000000
--- a/test/cms_web/controllers/page_controller_test.exs
+++ /dev/null
@@ -1,8 +0,0 @@
-defmodule CMSWeb.PageControllerTest do
-  use CMSWeb.ConnCase
-
-  test "GET /", %{conn: conn} do
-    conn = get(conn, ~p"/")
-    assert html_response(conn, 200) =~ "Peace of mind from prototype to production"
-  end
-end
diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex
index 82631ca..1e6b619 100644
--- a/test/support/conn_case.ex
+++ b/test/support/conn_case.ex
@@ -1,4 +1,4 @@
-defmodule CMSWeb.ConnCase do
+defmodule Test.ConnCase do
   @moduledoc """
   This module defines the test case to be used by
   tests that require setting up a connection.
@@ -11,7 +11,7 @@ defmodule CMSWeb.ConnCase do
   we enable the SQL sandbox, so changes done to the database
   are reverted at the end of every test. If you are using
   PostgreSQL, you can even run database tests asynchronously
-  by setting `use CMSWeb.ConnCase, async: true`, although
+  by setting `use Test.ConnCase, async: true`, although
   this option is not recommended for other databases.
   """
 
@@ -19,20 +19,21 @@ defmodule CMSWeb.ConnCase do
 
   using do
     quote do
-      use CMSWeb, :verified_routes
+      use Web, :verified_routes
 
-      import CMSWeb.ConnCase
       import Phoenix.ConnTest
       import Plug.Conn
+      import Test.ConnCase
+
       # The default endpoint for testing
-      @endpoint CMSWeb.Endpoint
+      @endpoint Web.Endpoint
 
       # Import conveniences for testing with connections
     end
   end
 
   setup tags do
-    CMS.DataCase.setup_sandbox(tags)
+    Test.DataCase.setup_sandbox(tags)
     {:ok, conn: Phoenix.ConnTest.build_conn()}
   end
 end
diff --git a/test/support/data_case.ex b/test/support/data_case.ex
index 0432616..ff9c165 100644
--- a/test/support/data_case.ex
+++ b/test/support/data_case.ex
@@ -1,4 +1,4 @@
-defmodule CMS.DataCase do
+defmodule Test.DataCase do
   @moduledoc """
   This module defines the setup for tests requiring
   access to the application's data layer.
@@ -10,7 +10,7 @@ defmodule CMS.DataCase do
   we enable the SQL sandbox, so changes done to the database
   are reverted at the end of every test. If you are using
   PostgreSQL, you can even run database tests asynchronously
-  by setting `use CMS.DataCase, async: true`, although
+  by setting `use Test.DataCase, async: true`, although
   this option is not recommended for other databases.
   """
 
@@ -20,17 +20,17 @@ defmodule CMS.DataCase do
 
   using do
     quote do
-      import CMS.DataCase
       import Ecto
       import Ecto.Changeset
       import Ecto.Query
+      import Test.DataCase
 
-      alias CMS.Repo
+      alias Core.Repo
     end
   end
 
   setup tags do
-    CMS.DataCase.setup_sandbox(tags)
+    Test.DataCase.setup_sandbox(tags)
     :ok
   end
 
@@ -38,7 +38,7 @@ defmodule CMS.DataCase do
   Sets up the sandbox based on the test tags.
   """
   def setup_sandbox(tags) do
-    pid = Sandbox.start_owner!(CMS.Repo, shared: not tags[:async])
+    pid = Sandbox.start_owner!(Core.Repo, shared: not tags[:async])
     on_exit(fn -> Sandbox.stop_owner(pid) end)
   end
 
diff --git a/test/support/test.ex b/test/support/test.ex
new file mode 100644
index 0000000..0dde93c
--- /dev/null
+++ b/test/support/test.ex
@@ -0,0 +1,3 @@
+defmodule Test do
+  use Boundary, top_level?: true, check: [in: false, out: false]
+end
diff --git a/test/test_helper.exs b/test/test_helper.exs
index dbebc90..e7e3f45 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -1,2 +1,2 @@
 ExUnit.start()
-Ecto.Adapters.SQL.Sandbox.mode(CMS.Repo, :manual)
+Ecto.Adapters.SQL.Sandbox.mode(Core.Repo, :manual)
diff --git a/test/web/controllers/error_html_test.exs b/test/web/controllers/error_html_test.exs
new file mode 100644
index 0000000..7c750cc
--- /dev/null
+++ b/test/web/controllers/error_html_test.exs
@@ -0,0 +1,14 @@
+defmodule Test.Web.ErrorHTMLTest do
+  use Test.ConnCase, async: true
+
+  # Bring render_to_string/4 for testing custom views
+  import Phoenix.Template
+
+  test "renders 404.html" do
+    assert render_to_string(Web.ErrorHTML, "404", "html", []) == "Not Found"
+  end
+
+  test "renders 500.html" do
+    assert render_to_string(Web.ErrorHTML, "500", "html", []) == "Internal Server Error"
+  end
+end
diff --git a/test/web/controllers/error_json_test.exs b/test/web/controllers/error_json_test.exs
new file mode 100644
index 0000000..b80c961
--- /dev/null
+++ b/test/web/controllers/error_json_test.exs
@@ -0,0 +1,12 @@
+defmodule Test.Web.ErrorJSONTest do
+  use Test.ConnCase, async: true
+
+  test "renders 404" do
+    assert Web.ErrorJSON.render("404.json", %{}) == %{errors: %{detail: "Not Found"}}
+  end
+
+  test "renders 500" do
+    assert Web.ErrorJSON.render("500.json", %{}) ==
+             %{errors: %{detail: "Internal Server Error"}}
+  end
+end
diff --git a/test/web/controllers/page_controller_test.exs b/test/web/controllers/page_controller_test.exs
new file mode 100644
index 0000000..6747117
--- /dev/null
+++ b/test/web/controllers/page_controller_test.exs
@@ -0,0 +1,8 @@
+defmodule Test.Web.PageControllerTest do
+  use Test.ConnCase
+
+  test "GET /", %{conn: conn} do
+    conn = get(conn, ~p"/")
+    assert html_response(conn, 200) =~ "sloanelybutsurely.com"
+  end
+end