Full Code of fuelen/ecto_erd for AI

main da71179f04c3 cached
63 files
715.5 KB
206.0k tokens
99 symbols
1 requests
Download .txt
Showing preview only (746K chars total). Download the full file or copy to clipboard to get everything.
Repository: fuelen/ecto_erd
Branch: main
Commit: da71179f04c3
Files: 63
Total size: 715.5 KB

Directory structure:
gitextract_ouem7f1z/

├── .formatter.exs
├── .gitignore
├── LICENSE.txt
├── README.md
├── examples/
│   ├── dbml/
│   │   ├── changelog.com/
│   │   │   ├── Clusters.dbml
│   │   │   └── Default.dbml
│   │   ├── hexpm/
│   │   │   ├── Contexts-as-clusters.dbml
│   │   │   ├── Default.dbml
│   │   │   └── Only-selected-cluster-Accounts-context.dbml
│   │   └── plausible-analytics/
│   │       ├── Contexts-as-clusters.dbml
│   │       └── Default.dbml
│   ├── dot/
│   │   ├── changelog.com/
│   │   │   ├── Clusters.dot
│   │   │   ├── Default.dot
│   │   │   └── No-fields.dot
│   │   ├── hexpm/
│   │   │   ├── Contexts-as-clusters-no-fields.dot
│   │   │   ├── Contexts-as-clusters.dot
│   │   │   ├── Default.dot
│   │   │   ├── No-fields.dot
│   │   │   ├── Only-embedded-schemas.dot
│   │   │   └── Only-selected-cluster-Accounts-context.dot
│   │   └── plausible-analytics/
│   │       ├── Contexts-as-clusters-no-fields.dot
│   │       ├── Contexts-as-clusters.dot
│   │       ├── Default.dot
│   │       └── No-fields.dot
│   ├── mermaid/
│   │   ├── changelog.com/
│   │   │   ├── Default.mmd
│   │   │   └── No-fields.mmd
│   │   ├── hexpm/
│   │   │   ├── Default.mmd
│   │   │   └── No-fields.mmd
│   │   └── plausible-analytics/
│   │       ├── Default.mmd
│   │       └── No-fields.mmd
│   ├── plantuml/
│   │   ├── changelog.com/
│   │   │   ├── Clusters.puml
│   │   │   └── Default.puml
│   │   ├── hexpm/
│   │   │   ├── Contexts-as-clusters-no-fields.puml
│   │   │   ├── Contexts-as-clusters.puml
│   │   │   ├── Default.puml
│   │   │   ├── Only-embedded-schemas.puml
│   │   │   └── Only-selected-cluster-Accounts-context.puml
│   │   └── plausible-analytics/
│   │       ├── Contexts-as-clusters-no-fields.puml
│   │       ├── Contexts-as-clusters.puml
│   │       └── Default.puml
│   └── quick_dbd/
│       ├── changelog.com/
│       │   └── Default.qdbd
│       ├── hexpm/
│       │   ├── Default.qdbd
│       │   └── Only-selected-cluster-Accounts-context.qdbd
│       └── plausible-analytics/
│           └── Default.qdbd
├── examples_generator.exs
├── lib/
│   ├── ecto/
│   │   └── erd/
│   │       ├── color.ex
│   │       ├── document/
│   │       │   ├── dbml.ex
│   │       │   ├── dot.ex
│   │       │   ├── mermaid.ex
│   │       │   ├── plantuml.ex
│   │       │   └── quick_dbd.ex
│   │       ├── document.ex
│   │       ├── edge.ex
│   │       ├── field.ex
│   │       ├── graph.ex
│   │       ├── html.ex
│   │       ├── node.ex
│   │       ├── render.ex
│   │       └── schema_modules.ex
│   └── mix/
│       └── tasks/
│           └── ecto.gen.erd.ex
├── mix.exs
└── test/
    ├── ecto/
    │   └── erd_test.exs
    └── test_helper.exs

================================================
FILE CONTENTS
================================================

================================================
FILE: .formatter.exs
================================================
# Used by "mix format"
[
  inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]


================================================
FILE: .gitignore
================================================
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where third-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
ecto_erd-*.tar

# Temporary files, for example, from tests.
/tmp/


================================================
FILE: LICENSE.txt
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# Ecto.ERD

[![Hex.pm](https://img.shields.io/hexpm/v/ecto_erd.svg)](https://hex.pm/packages/ecto_erd)

A mix task for generating an ERD (Entity-Relationship Diagram) in various
formats for all Ecto schemas in your project.

Supported formats:

* [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) (default)
* [PlantUML](https://plantuml.com)
* [DBML](https://www.dbml.org/)
* [QuickDBD](https://www.quickdatabasediagrams.com)
* [Mermaid](https://mermaid-js.github.io/mermaid/#/entityRelationshipDiagram)

![Simple blog demo](assets/simple_blog_dot_demo.png)
<details>
  <summary>Definition of schemas</summary>

  ```elixir
  defmodule Blog.Post do
    use Ecto.Schema

    schema "posts" do
      field(:title, :string)
      field(:text, :string)
      timestamps()
      belongs_to(:user, Blog.User)
      has_many(:comments, Blog.Comment)
    end
  end

  defmodule Blog.Comment do
    use Ecto.Schema

    schema "comments" do
      field(:text, :string)
      timestamps()
      belongs_to(:post, Blog.Post)
      belongs_to(:user, Blog.User)
    end
  end

  defmodule Blog.User do
    use Ecto.Schema

    schema "users" do
      field(:email, :string)
      has_many(:posts, Blog.Post)
      has_many(:comments, Blog.Comment)
    end
  end
  ```

</details>

## Installation

The package can be installed by adding `ecto_erd` to your list of dependencies
in `mix.exs`:

```elixir
def deps do
  [
    {:ecto_erd, "~> 0.6", only: :dev}
  ]
end
```

## Usage

Just run:

```sh
mix ecto.gen.erd
```

The command above produces a DOT file, which you can convert to an
image using the Graphviz utility:

```sh
dot -Tpng ecto_erd.dot -o erd.png
```

Configuration is possible via the `.ecto_erd.exs` file.
The docs can be found at [https://hexdocs.pm/ecto_erd](https://hexdocs.pm/ecto_erd).
Configuration examples and output for a few open-source projects can be
found in the PAGES section under EXAMPLES.

## Troubleshooting

Trying to run `ecto_erd` in an umbrella project? You might see this error:

```
$ mix ecto.gen.erd
** (RuntimeError) Unable to detect `:otp_app`, please specify it explicitly
```

The easiest solution is to run the command on one of the apps in the `apps/` directory. Another option is to create a configuration file and specify the `:otp_app`. See the [docs for details](https://hexdocs.pm/ecto_erd/Mix.Tasks.Ecto.Gen.Erd.html#module-configuration-file).


================================================
FILE: examples/dbml/changelog.com/Clusters.dbml
================================================
TableGroup EPISODE {
  episodes
  episode_guests
  episode_hosts
  episode_requests
  episode_sponsors
  episode_stats
  episode_topics
}
TableGroup NEWS {
  news_ads
  news_issues
  news_issue_ads
  news_issue_items
  news_items
  news_item_comments
  news_item_topics
  news_queue
  news_sources
  news_sponsorships
}
TableGroup PERSON {
  people
}
TableGroup PODCAST {
  podcasts
  podcast_hosts
  podcast_topics
}
TableGroup POST {
  posts
  post_topics
}
TableGroup SPONSOR {
  sponsors
  sponsor_reps
}


Table feeds {
  id integer [pk]
  name varchar
  slug varchar
  description varchar
  title_format varchar
  plusplus boolean
  autosub boolean
  starts_at timestamp
  cover varchar
  podcast_ids array
  person_ids array
  owner_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table subscriptions {
  id integer [pk]
  unsubscribed_at timestamp
  context varchar
  episode_id integer
  item_id integer
  person_id integer
  podcast_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table topics {
  id integer [pk]
  name varchar
  slug varchar
  description varchar
  website varchar
  twitter_handle varchar
  icon varchar
  inserted_at timestamp
  updated_at timestamp
}

Table schema_migrations {
  version integer [pk]
  inserted_at timestamp
}

Table oban_jobs {
  id integer [pk]
  state varchar
  queue varchar
  worker varchar
  args jsonb
  meta jsonb
  tags array
  errors array
  attempt integer
  attempted_by array
  max_attempts integer
  priority integer
  attempted_at timestamp
  cancelled_at timestamp
  completed_at timestamp
  discarded_at timestamp
  inserted_at timestamp
  scheduled_at timestamp
}

Table episodes {
  id integer [pk]
  slug varchar
  guid varchar
  title varchar
  subtitle varchar
  type integer
  featured boolean
  highlight varchar
  subhighlight varchar
  summary varchar
  notes varchar
  doc_url varchar
  socialize_url varchar
  published boolean
  published_at timestamp
  recorded_at timestamp
  recorded_live boolean
  youtube_id varchar
  cover varchar
  audio_file varchar
  audio_bytes integer
  audio_duration integer
  audio_chapters jsonb
  plusplus_file varchar
  plusplus_bytes integer
  plusplus_duration integer
  plusplus_chapters jsonb
  download_count float
  import_count float
  reach_count integer
  email_subject varchar
  email_teaser varchar
  email_content varchar
  email_sends integer
  email_opens integer
  transcript array
  podcast_id integer
  request_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_guests {
  id integer [pk]
  position integer
  thanks boolean
  discount_code varchar
  episode_id integer
  person_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_hosts {
  id integer [pk]
  position integer
  person_id integer
  episode_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_requests {
  id integer [pk]
  status integer
  hosts varchar
  guests varchar
  topics varchar
  pitch varchar
  pronunciation varchar
  message varchar
  podcast_id integer
  submitter_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_sponsors {
  id integer [pk]
  position integer
  title varchar
  link_url varchar
  description varchar
  starts_at float
  ends_at float
  episode_id integer
  sponsor_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_stats {
  id integer [pk]
  date date
  episode_bytes integer
  total_bytes integer
  downloads float
  uniques integer
  demographics jsonb
  episode_id integer
  podcast_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_topics {
  id integer [pk]
  position integer
  topic_id integer
  episode_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_ads {
  id integer [pk]
  url varchar
  headline varchar
  story varchar
  image varchar
  active boolean
  newsletter boolean
  impression_count integer
  click_count integer
  sponsorship_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_issues {
  id integer [pk]
  slug varchar
  note varchar
  teaser varchar
  published boolean
  published_at timestamp
  inserted_at timestamp
  updated_at timestamp
}

Table news_issue_ads {
  id integer [pk]
  position integer
  image boolean
  ad_id integer
  issue_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_issue_items {
  id integer [pk]
  position integer
  image boolean
  issue_id integer
  item_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_items {
  id integer [pk]
  status integer
  type integer
  url varchar
  headline varchar
  story varchar
  image varchar
  object_id varchar
  feed_only boolean
  pinned boolean
  published_at timestamp
  refreshed_at timestamp
  impression_count integer
  click_count integer
  message varchar
  author_id integer
  logger_id integer
  submitter_id integer
  source_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_item_comments {
  id integer [pk]
  content varchar
  approved boolean
  edited_at timestamp
  deleted_at timestamp
  item_id integer
  author_id integer
  parent_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_item_topics {
  id integer [pk]
  position integer
  item_id integer
  topic_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_queue {
  id integer [pk]
  position float
  item_id integer
}

Table news_sources {
  id integer [pk]
  name varchar
  slug varchar
  website varchar
  twitter_handle varchar
  description varchar
  feed varchar
  regex varchar
  publication boolean
  icon varchar
  inserted_at timestamp
  updated_at timestamp
}

Table news_sponsorships {
  id integer [pk]
  name varchar
  weeks array
  impression_count integer
  click_count integer
  sponsor_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table people {
  id integer [pk]
  name varchar
  email varchar
  handle varchar
  github_handle varchar
  linkedin_handle varchar
  mastodon_handle varchar
  twitter_handle varchar
  slack_id varchar
  website varchar
  bio varchar
  location varchar
  auth_token varchar
  auth_token_expires_at timestamp
  joined_at timestamp
  signed_in_at timestamp
  approved boolean
  avatar varchar
  admin boolean
  host boolean
  editor boolean
  public_profile boolean
  settings jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table podcasts {
  id integer [pk]
  name varchar
  slug varchar
  status integer
  welcome varchar
  description varchar
  extended_description varchar
  vanity_domain varchar
  keywords varchar
  mastodon_handle varchar
  twitter_handle varchar
  apple_url varchar
  spotify_url varchar
  riverside_url varchar
  chartable_id varchar
  schedule_note varchar
  download_count float
  reach_count integer
  recorded_live boolean
  partner boolean
  position integer
  subscribers jsonb
  cover varchar
  inserted_at timestamp
  updated_at timestamp
}

Table podcast_hosts {
  id integer [pk]
  position integer
  retired boolean
  person_id integer
  podcast_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table podcast_topics {
  id integer [pk]
  position integer
  podcast_id integer
  topic_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table posts {
  id integer [pk]
  title varchar
  subtitle varchar
  slug varchar
  guid varchar
  canonical_url varchar
  image varchar
  tldr varchar
  body varchar
  published boolean
  published_at timestamp
  author_id integer
  editor_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table post_topics {
  id integer [pk]
  position integer
  topic_id integer
  post_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table sponsors {
  id integer [pk]
  name varchar
  description varchar
  website varchar
  github_handle varchar
  twitter_handle varchar
  avatar varchar
  color_logo varchar
  dark_logo varchar
  light_logo varchar
  inserted_at timestamp
  updated_at timestamp
}

Table sponsor_reps {
  id integer [pk]
  sponsor_id integer
  person_id integer
  inserted_at timestamp
  updated_at timestamp
}

Ref: episode_requests.id - episodes.request_id
Ref: episodes.id < episode_guests.episode_id
Ref: episodes.id < episode_hosts.episode_id
Ref: episodes.id < episode_sponsors.episode_id
Ref: episodes.id < episode_stats.episode_id
Ref: episodes.id < episode_topics.episode_id
Ref: episodes.id < subscriptions.episode_id
Ref: news_ads.id < news_issue_ads.ad_id
Ref: news_issues.id < news_issue_ads.issue_id
Ref: news_issues.id < news_issue_items.issue_id
Ref: news_item_comments.id < news_item_comments.parent_id
Ref: news_items.id < news_issue_items.item_id
Ref: news_items.id < news_item_comments.item_id
Ref: news_items.id < news_item_topics.item_id
Ref: news_items.id - news_queue.item_id
Ref: news_items.id < subscriptions.item_id
Ref: news_sources.id < news_items.source_id
Ref: news_sponsorships.id < news_ads.sponsorship_id
Ref: people.id < episode_guests.person_id
Ref: people.id < episode_hosts.person_id
Ref: people.id < episode_requests.submitter_id
Ref: people.id < feeds.owner_id
Ref: people.id < news_item_comments.author_id
Ref: people.id < news_items.author_id
Ref: people.id < news_items.logger_id
Ref: people.id < news_items.submitter_id
Ref: people.id < podcast_hosts.person_id
Ref: people.id < posts.author_id
Ref: people.id < posts.editor_id
Ref: people.id < sponsor_reps.person_id
Ref: people.id < subscriptions.person_id
Ref: podcasts.id < episode_requests.podcast_id
Ref: podcasts.id < episode_stats.podcast_id
Ref: podcasts.id < episodes.podcast_id
Ref: podcasts.id < podcast_hosts.podcast_id
Ref: podcasts.id < podcast_topics.podcast_id
Ref: podcasts.id < subscriptions.podcast_id
Ref: posts.id < post_topics.post_id
Ref: sponsors.id < episode_sponsors.sponsor_id
Ref: sponsors.id < news_sponsorships.sponsor_id
Ref: sponsors.id < sponsor_reps.sponsor_id
Ref: topics.id < episode_topics.topic_id
Ref: topics.id < news_item_topics.topic_id
Ref: topics.id < podcast_topics.topic_id
Ref: topics.id < post_topics.topic_id

================================================
FILE: examples/dbml/changelog.com/Default.dbml
================================================


Table episodes {
  id integer [pk]
  slug varchar
  guid varchar
  title varchar
  subtitle varchar
  type integer
  featured boolean
  highlight varchar
  subhighlight varchar
  summary varchar
  notes varchar
  doc_url varchar
  socialize_url varchar
  published boolean
  published_at timestamp
  recorded_at timestamp
  recorded_live boolean
  youtube_id varchar
  cover varchar
  audio_file varchar
  audio_bytes integer
  audio_duration integer
  audio_chapters jsonb
  plusplus_file varchar
  plusplus_bytes integer
  plusplus_duration integer
  plusplus_chapters jsonb
  download_count float
  import_count float
  reach_count integer
  email_subject varchar
  email_teaser varchar
  email_content varchar
  email_sends integer
  email_opens integer
  transcript array
  podcast_id integer
  request_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_guests {
  id integer [pk]
  position integer
  thanks boolean
  discount_code varchar
  episode_id integer
  person_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_hosts {
  id integer [pk]
  position integer
  person_id integer
  episode_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_requests {
  id integer [pk]
  status integer
  hosts varchar
  guests varchar
  topics varchar
  pitch varchar
  pronunciation varchar
  message varchar
  podcast_id integer
  submitter_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_sponsors {
  id integer [pk]
  position integer
  title varchar
  link_url varchar
  description varchar
  starts_at float
  ends_at float
  episode_id integer
  sponsor_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_stats {
  id integer [pk]
  date date
  episode_bytes integer
  total_bytes integer
  downloads float
  uniques integer
  demographics jsonb
  episode_id integer
  podcast_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table episode_topics {
  id integer [pk]
  position integer
  topic_id integer
  episode_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table feeds {
  id integer [pk]
  name varchar
  slug varchar
  description varchar
  title_format varchar
  plusplus boolean
  autosub boolean
  starts_at timestamp
  cover varchar
  podcast_ids array
  person_ids array
  owner_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_ads {
  id integer [pk]
  url varchar
  headline varchar
  story varchar
  image varchar
  active boolean
  newsletter boolean
  impression_count integer
  click_count integer
  sponsorship_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_issues {
  id integer [pk]
  slug varchar
  note varchar
  teaser varchar
  published boolean
  published_at timestamp
  inserted_at timestamp
  updated_at timestamp
}

Table news_issue_ads {
  id integer [pk]
  position integer
  image boolean
  ad_id integer
  issue_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_issue_items {
  id integer [pk]
  position integer
  image boolean
  issue_id integer
  item_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_items {
  id integer [pk]
  status integer
  type integer
  url varchar
  headline varchar
  story varchar
  image varchar
  object_id varchar
  feed_only boolean
  pinned boolean
  published_at timestamp
  refreshed_at timestamp
  impression_count integer
  click_count integer
  message varchar
  author_id integer
  logger_id integer
  submitter_id integer
  source_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_item_comments {
  id integer [pk]
  content varchar
  approved boolean
  edited_at timestamp
  deleted_at timestamp
  item_id integer
  author_id integer
  parent_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_item_topics {
  id integer [pk]
  position integer
  item_id integer
  topic_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table news_queue {
  id integer [pk]
  position float
  item_id integer
}

Table news_sources {
  id integer [pk]
  name varchar
  slug varchar
  website varchar
  twitter_handle varchar
  description varchar
  feed varchar
  regex varchar
  publication boolean
  icon varchar
  inserted_at timestamp
  updated_at timestamp
}

Table news_sponsorships {
  id integer [pk]
  name varchar
  weeks array
  impression_count integer
  click_count integer
  sponsor_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table people {
  id integer [pk]
  name varchar
  email varchar
  handle varchar
  github_handle varchar
  linkedin_handle varchar
  mastodon_handle varchar
  twitter_handle varchar
  slack_id varchar
  website varchar
  bio varchar
  location varchar
  auth_token varchar
  auth_token_expires_at timestamp
  joined_at timestamp
  signed_in_at timestamp
  approved boolean
  avatar varchar
  admin boolean
  host boolean
  editor boolean
  public_profile boolean
  settings jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table podcasts {
  id integer [pk]
  name varchar
  slug varchar
  status integer
  welcome varchar
  description varchar
  extended_description varchar
  vanity_domain varchar
  keywords varchar
  mastodon_handle varchar
  twitter_handle varchar
  apple_url varchar
  spotify_url varchar
  riverside_url varchar
  chartable_id varchar
  schedule_note varchar
  download_count float
  reach_count integer
  recorded_live boolean
  partner boolean
  position integer
  subscribers jsonb
  cover varchar
  inserted_at timestamp
  updated_at timestamp
}

Table podcast_hosts {
  id integer [pk]
  position integer
  retired boolean
  person_id integer
  podcast_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table podcast_topics {
  id integer [pk]
  position integer
  podcast_id integer
  topic_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table posts {
  id integer [pk]
  title varchar
  subtitle varchar
  slug varchar
  guid varchar
  canonical_url varchar
  image varchar
  tldr varchar
  body varchar
  published boolean
  published_at timestamp
  author_id integer
  editor_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table post_topics {
  id integer [pk]
  position integer
  topic_id integer
  post_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table sponsors {
  id integer [pk]
  name varchar
  description varchar
  website varchar
  github_handle varchar
  twitter_handle varchar
  avatar varchar
  color_logo varchar
  dark_logo varchar
  light_logo varchar
  inserted_at timestamp
  updated_at timestamp
}

Table sponsor_reps {
  id integer [pk]
  sponsor_id integer
  person_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table subscriptions {
  id integer [pk]
  unsubscribed_at timestamp
  context varchar
  episode_id integer
  item_id integer
  person_id integer
  podcast_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table topics {
  id integer [pk]
  name varchar
  slug varchar
  description varchar
  website varchar
  twitter_handle varchar
  icon varchar
  inserted_at timestamp
  updated_at timestamp
}

Table schema_migrations {
  version integer [pk]
  inserted_at timestamp
}

Table oban_jobs {
  id integer [pk]
  state varchar
  queue varchar
  worker varchar
  args jsonb
  meta jsonb
  tags array
  errors array
  attempt integer
  attempted_by array
  max_attempts integer
  priority integer
  attempted_at timestamp
  cancelled_at timestamp
  completed_at timestamp
  discarded_at timestamp
  inserted_at timestamp
  scheduled_at timestamp
}

Ref: episode_requests.id - episodes.request_id
Ref: episodes.id < episode_guests.episode_id
Ref: episodes.id < episode_hosts.episode_id
Ref: episodes.id < episode_sponsors.episode_id
Ref: episodes.id < episode_stats.episode_id
Ref: episodes.id < episode_topics.episode_id
Ref: episodes.id < subscriptions.episode_id
Ref: news_ads.id < news_issue_ads.ad_id
Ref: news_issues.id < news_issue_ads.issue_id
Ref: news_issues.id < news_issue_items.issue_id
Ref: news_item_comments.id < news_item_comments.parent_id
Ref: news_items.id < news_issue_items.item_id
Ref: news_items.id < news_item_comments.item_id
Ref: news_items.id < news_item_topics.item_id
Ref: news_items.id - news_queue.item_id
Ref: news_items.id < subscriptions.item_id
Ref: news_sources.id < news_items.source_id
Ref: news_sponsorships.id < news_ads.sponsorship_id
Ref: people.id < episode_guests.person_id
Ref: people.id < episode_hosts.person_id
Ref: people.id < episode_requests.submitter_id
Ref: people.id < feeds.owner_id
Ref: people.id < news_item_comments.author_id
Ref: people.id < news_items.author_id
Ref: people.id < news_items.logger_id
Ref: people.id < news_items.submitter_id
Ref: people.id < podcast_hosts.person_id
Ref: people.id < posts.author_id
Ref: people.id < posts.editor_id
Ref: people.id < sponsor_reps.person_id
Ref: people.id < subscriptions.person_id
Ref: podcasts.id < episode_requests.podcast_id
Ref: podcasts.id < episode_stats.podcast_id
Ref: podcasts.id < episodes.podcast_id
Ref: podcasts.id < podcast_hosts.podcast_id
Ref: podcasts.id < podcast_topics.podcast_id
Ref: podcasts.id < subscriptions.podcast_id
Ref: posts.id < post_topics.post_id
Ref: sponsors.id < episode_sponsors.sponsor_id
Ref: sponsors.id < news_sponsorships.sponsor_id
Ref: sponsors.id < sponsor_reps.sponsor_id
Ref: topics.id < episode_topics.topic_id
Ref: topics.id < news_item_topics.topic_id
Ref: topics.id < podcast_topics.topic_id
Ref: topics.id < post_topics.topic_id

================================================
FILE: examples/dbml/hexpm/Contexts-as-clusters.dbml
================================================
TableGroup "Ecto.Migration" {
  schema_migrations
}
TableGroup "Hexpm.Accounts" {
  audit_logs
  emails
  keys
  organizations
  organization_users
  password_resets
  sessions
  users
}
TableGroup "Hexpm.BlockAddress" {
  blocked_addresses
}
TableGroup "Hexpm.Repository" {
  downloads
  installs
  packages
  package_dependants
  package_downloads
  package_owners
  package_reports
  package_report_comments
  package_report_releases
  releases
  release_downloads
  repositories
  requirements
}
TableGroup "Hexpm.ShortURLs" {
  short_urls
}


Table schema_migrations {
  version integer [pk]
  inserted_at timestamp
}

Table audit_logs {
  id integer [pk]
  user_agent varchar
  remote_ip varchar
  action varchar
  params jsonb
  user_id integer
  organization_id integer
  key_id integer
  inserted_at timestamp
}

Table emails {
  id integer [pk]
  email varchar
  verified boolean
  primary boolean
  public boolean
  gravatar boolean
  verification_key varchar
  verification_expiry timestamp
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table keys {
  id integer [pk]
  name varchar
  secret_first varchar
  secret_second varchar
  public boolean
  revoke_at timestamp
  inserted_at timestamp
  updated_at timestamp
  last_use jsonb
  user_id integer
  organization_id integer
  permissions jsonb
}

Table organizations {
  id integer [pk]
  name varchar
  billing_active boolean
  billing_override boolean
  trial_end timestamp
  inserted_at timestamp
  updated_at timestamp
}

Table organization_users {
  id integer [pk]
  role varchar
  organization_id integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table password_resets {
  id integer [pk]
  key varchar
  primary_email varchar
  user_id integer
  inserted_at timestamp
}

Table sessions {
  id integer [pk]
  token bytea
  data jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table users {
  id integer [pk]
  username varchar
  full_name varchar
  password varchar
  service boolean
  deactivated_at timestamp
  role varchar
  inserted_at timestamp
  updated_at timestamp
  handles jsonb
  tfa jsonb
  organization_id integer
}

Table blocked_addresses {
  id integer [pk]
  ip varchar
  comment varchar
}

Table downloads {
  id integer [pk]
  package_id integer
  release_id integer
  downloads integer
  day date
}

Table installs {
  id integer [pk]
  hex varchar
  elixirs array
}

Table packages {
  id integer [pk]
  name varchar
  docs_updated_at timestamp
  inserted_at timestamp
  updated_at timestamp
  repository_id integer
  meta jsonb
}

Table package_dependants {
  id integer [pk]
  package_id integer
  name varchar
  repo varchar
}

Table package_downloads {
  package_id integer
  view varchar
  downloads integer
}

Table package_owners {
  id integer [pk]
  level varchar
  package_id integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table package_reports {
  id integer [pk]
  state varchar
  description varchar
  author_id integer
  package_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table package_report_comments {
  id integer [pk]
  text varchar
  inserted_at timestamp
  updated_at timestamp
  package_report_id integer
  author_id integer
}

Table package_report_releases {
  id integer [pk]
  release_id integer
  package_report_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table releases {
  id integer [pk]
  version varchar
  inner_checksum bytea
  outer_checksum bytea
  has_docs boolean
  inserted_at timestamp
  updated_at timestamp
  package_id integer
  publisher_id integer
  meta jsonb
  retirement jsonb
}

Table release_downloads {
  package_id integer
  release_id integer
  downloads integer
}

Table repositories {
  id integer [pk]
  name varchar
  inserted_at timestamp
  updated_at timestamp
  organization_id integer
}

Table requirements {
  id integer [pk]
  app varchar
  requirement varchar
  optional boolean
  release_id integer
  dependency_id integer
}

Table short_urls {
  id integer [pk]
  url varchar
  short_code varchar
  inserted_at timestamp
}

Ref: keys.id < audit_logs.key_id
Ref: organizations.id < audit_logs.organization_id
Ref: organizations.id < keys.organization_id
Ref: organizations.id < organization_users.organization_id
Ref: organizations.id - repositories.organization_id
Ref: organizations.id - users.organization_id
Ref: package_reports.id < package_report_comments.package_report_id
Ref: package_reports.id < package_report_releases.package_report_id
Ref: packages.id < downloads.package_id
Ref: packages.id < package_dependants.package_id
Ref: packages.id < package_downloads.package_id
Ref: packages.id < package_owners.package_id
Ref: packages.id < package_reports.package_id
Ref: packages.id < release_downloads.package_id
Ref: packages.id < releases.package_id
Ref: packages.id < requirements.dependency_id
Ref: releases.id < downloads.release_id
Ref: releases.id < package_report_releases.release_id
Ref: releases.id - release_downloads.release_id
Ref: releases.id < requirements.release_id
Ref: repositories.id < packages.repository_id
Ref: users.id < audit_logs.user_id
Ref: users.id < emails.user_id
Ref: users.id < keys.user_id
Ref: users.id < organization_users.user_id
Ref: users.id < package_owners.user_id
Ref: users.id < package_report_comments.author_id
Ref: users.id < package_reports.author_id
Ref: users.id < password_resets.user_id
Ref: users.id < releases.publisher_id

================================================
FILE: examples/dbml/hexpm/Default.dbml
================================================


Table schema_migrations {
  version integer [pk]
  inserted_at timestamp
}

Table audit_logs {
  id integer [pk]
  user_agent varchar
  remote_ip varchar
  action varchar
  params jsonb
  user_id integer
  organization_id integer
  key_id integer
  inserted_at timestamp
}

Table emails {
  id integer [pk]
  email varchar
  verified boolean
  primary boolean
  public boolean
  gravatar boolean
  verification_key varchar
  verification_expiry timestamp
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table keys {
  id integer [pk]
  name varchar
  secret_first varchar
  secret_second varchar
  public boolean
  revoke_at timestamp
  inserted_at timestamp
  updated_at timestamp
  last_use jsonb
  user_id integer
  organization_id integer
  permissions jsonb
}

Table organizations {
  id integer [pk]
  name varchar
  billing_active boolean
  billing_override boolean
  trial_end timestamp
  inserted_at timestamp
  updated_at timestamp
}

Table organization_users {
  id integer [pk]
  role varchar
  organization_id integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table password_resets {
  id integer [pk]
  key varchar
  primary_email varchar
  user_id integer
  inserted_at timestamp
}

Table sessions {
  id integer [pk]
  token bytea
  data jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table users {
  id integer [pk]
  username varchar
  full_name varchar
  password varchar
  service boolean
  deactivated_at timestamp
  role varchar
  inserted_at timestamp
  updated_at timestamp
  handles jsonb
  tfa jsonb
  organization_id integer
}

Table blocked_addresses {
  id integer [pk]
  ip varchar
  comment varchar
}

Table downloads {
  id integer [pk]
  package_id integer
  release_id integer
  downloads integer
  day date
}

Table installs {
  id integer [pk]
  hex varchar
  elixirs array
}

Table packages {
  id integer [pk]
  name varchar
  docs_updated_at timestamp
  inserted_at timestamp
  updated_at timestamp
  repository_id integer
  meta jsonb
}

Table package_dependants {
  id integer [pk]
  package_id integer
  name varchar
  repo varchar
}

Table package_downloads {
  package_id integer
  view varchar
  downloads integer
}

Table package_owners {
  id integer [pk]
  level varchar
  package_id integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table package_reports {
  id integer [pk]
  state varchar
  description varchar
  author_id integer
  package_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table package_report_comments {
  id integer [pk]
  text varchar
  inserted_at timestamp
  updated_at timestamp
  package_report_id integer
  author_id integer
}

Table package_report_releases {
  id integer [pk]
  release_id integer
  package_report_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table releases {
  id integer [pk]
  version varchar
  inner_checksum bytea
  outer_checksum bytea
  has_docs boolean
  inserted_at timestamp
  updated_at timestamp
  package_id integer
  publisher_id integer
  meta jsonb
  retirement jsonb
}

Table release_downloads {
  package_id integer
  release_id integer
  downloads integer
}

Table repositories {
  id integer [pk]
  name varchar
  inserted_at timestamp
  updated_at timestamp
  organization_id integer
}

Table requirements {
  id integer [pk]
  app varchar
  requirement varchar
  optional boolean
  release_id integer
  dependency_id integer
}

Table short_urls {
  id integer [pk]
  url varchar
  short_code varchar
  inserted_at timestamp
}

Ref: keys.id < audit_logs.key_id
Ref: organizations.id < audit_logs.organization_id
Ref: organizations.id < keys.organization_id
Ref: organizations.id < organization_users.organization_id
Ref: organizations.id - repositories.organization_id
Ref: organizations.id - users.organization_id
Ref: package_reports.id < package_report_comments.package_report_id
Ref: package_reports.id < package_report_releases.package_report_id
Ref: packages.id < downloads.package_id
Ref: packages.id < package_dependants.package_id
Ref: packages.id < package_downloads.package_id
Ref: packages.id < package_owners.package_id
Ref: packages.id < package_reports.package_id
Ref: packages.id < release_downloads.package_id
Ref: packages.id < releases.package_id
Ref: packages.id < requirements.dependency_id
Ref: releases.id < downloads.release_id
Ref: releases.id < package_report_releases.release_id
Ref: releases.id - release_downloads.release_id
Ref: releases.id < requirements.release_id
Ref: repositories.id < packages.repository_id
Ref: users.id < audit_logs.user_id
Ref: users.id < emails.user_id
Ref: users.id < keys.user_id
Ref: users.id < organization_users.user_id
Ref: users.id < package_owners.user_id
Ref: users.id < package_report_comments.author_id
Ref: users.id < package_reports.author_id
Ref: users.id < password_resets.user_id
Ref: users.id < releases.publisher_id

================================================
FILE: examples/dbml/hexpm/Only-selected-cluster-Accounts-context.dbml
================================================
TableGroup "Hexpm.Accounts" {
  audit_logs
  emails
  keys
  organizations
  organization_users
  password_resets
  sessions
  users
}


Table audit_logs {
  id integer [pk]
  user_agent varchar
  remote_ip varchar
  action varchar
  params jsonb
  user_id integer
  organization_id integer
  key_id integer
  inserted_at timestamp
}

Table emails {
  id integer [pk]
  email varchar
  verified boolean
  primary boolean
  public boolean
  gravatar boolean
  verification_key varchar
  verification_expiry timestamp
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table keys {
  id integer [pk]
  name varchar
  secret_first varchar
  secret_second varchar
  public boolean
  revoke_at timestamp
  inserted_at timestamp
  updated_at timestamp
  last_use jsonb
  user_id integer
  organization_id integer
  permissions jsonb
}

Table organizations {
  id integer [pk]
  name varchar
  billing_active boolean
  billing_override boolean
  trial_end timestamp
  inserted_at timestamp
  updated_at timestamp
}

Table organization_users {
  id integer [pk]
  role varchar
  organization_id integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table password_resets {
  id integer [pk]
  key varchar
  primary_email varchar
  user_id integer
  inserted_at timestamp
}

Table sessions {
  id integer [pk]
  token bytea
  data jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table users {
  id integer [pk]
  username varchar
  full_name varchar
  password varchar
  service boolean
  deactivated_at timestamp
  role varchar
  inserted_at timestamp
  updated_at timestamp
  handles jsonb
  tfa jsonb
  organization_id integer
}

Ref: keys.id < audit_logs.key_id
Ref: organizations.id < audit_logs.organization_id
Ref: organizations.id < keys.organization_id
Ref: organizations.id < organization_users.organization_id
Ref: organizations.id - users.organization_id
Ref: users.id < audit_logs.user_id
Ref: users.id < emails.user_id
Ref: users.id < keys.user_id
Ref: users.id < organization_users.user_id
Ref: users.id < password_resets.user_id

================================================
FILE: examples/dbml/plausible-analytics/Contexts-as-clusters.dbml
================================================
TableGroup "Ecto.Migration" {
  schema_migrations
}
TableGroup "FunWithFlags.Store" {
  fun_with_flags_toggles
}
TableGroup Oban {
  oban_jobs
}
TableGroup Plausible {
  events_v2
  sessions_v2
  funnels
  goals
  sites
}
TableGroup "Plausible.Auth" {
  api_keys
  email_activation_codes
  invitations
  totp_recovery_codes
  users
}
TableGroup "Plausible.Billing" {
  enterprise_plans
  subscriptions
}
TableGroup "Plausible.DataMigration" {
  domains_lookup
}
TableGroup "Plausible.Funnel" {
  funnel_steps
}
TableGroup "Plausible.Imported" {
  imported_browsers
  imported_devices
  imported_entry_pages
  imported_exit_pages
  imported_locations
  imported_operating_systems
  imported_pages
  site_imports
  imported_sources
  imported_visitors
}
TableGroup "Plausible.Ingestion" {
  ingest_counters
}
TableGroup "Plausible.Plugins" {
  plugins_api_tokens
}
TableGroup "Plausible.Shield" {
  shield_rules_country
  shield_rules_hostname
  shield_rules_ip
  shield_rules_page
}
TableGroup "Plausible.Site" {
  google_auth
  site_memberships
  monthly_reports
  shared_links
  spike_notifications
  site_user_preferences
  weekly_reports
}

Enum billing_interval {
  yearly
  monthly
}

Enum currency {
  XBD
  BYN
  HKD
  XOF
  SOS
  ARS
  EGP
  XDR
  GMD
  MAD
  XAG
  XAU
  COU
  UYW
  LKR
  SAR
  BBD
  XCD
  ZMW
  ZWL
  CZK
  JPY
  SEK
  PLN
  KYD
  THB
  QAR
  SLL
  RON
  CUC
  MOP
  CHW
  KGS
  ALL
  CLP
  XXX
  IDR
  BZD
  PYG
  LAK
  OMR
  HRK
  CHF
  BTN
  MRU
  GEL
  BOV
  AFN
  RSD
  XTS
  UYU
  BHD
  HNL
  GBP
  WST
  COP
  MKD
  ZAR
  SYP
  SZL
  HTG
  SVC
  NPR
  MXV
  MMK
  PKR
  GTQ
  AWG
  SGD
  TWD
  AOA
  TOP
  XBB
  KRW
  XBA
  TRY
  XPT
  SBD
  MUR
  NIO
  CNY
  BWP
  NOK
  LSL
  IRR
  BOB
  BRL
  SDG
  BIF
  BDT
  UYI
  NGN
  LBP
  GYD
  RWF
  ILS
  PGK
  TTD
  SSP
  MWK
  ETB
  INR
  AUD
  XPD
  CVE
  TMT
  YER
  BAM
  XSU
  MVR
  SCR
  JOD
  CHE
  CUP
  PAB
  MGA
  VES
  JMD
  VUV
  MNT
  NZD
  XBC
  KES
  GNF
  XAF
  TZS
  BND
  MYR
  LRD
  KPW
  PHP
  IQD
  CRC
  UZS
  TND
  DJF
  DOP
  GIP
  XUA
  CLF
  MDL
  NAD
  PEN
  CDF
  USD
  BGN
  STN
  UAH
  EUR
  FKP
  GHS
  BSD
  CAD
  FJD
  SRD
  KHR
  MXN
  HUF
  UGX
  AED
  XPF
  DZD
  RUB
  KZT
  AZN
  KMF
  AMD
  VND
  USN
  BMD
  ANG
  KWD
  TJS
  LYD
  DKK
  ERN
  ISK
  MZN
  SHP
}

Enum role {
  owner
  admin
  viewer
}

Enum action {
  allow
  deny
}

Enum source {
  noop
  csv
  universal_analytics
  google_analytics_4
}

Enum site_imports_status {
  pending
  failed
  completed
  importing
}

Enum subscriptions_status {
  active
  deleted
  past_due
  paused
}

Enum theme {
  system
  light
  dark
}

Table schema_migrations {
  version integer [pk]
  inserted_at timestamp
}

Table fun_with_flags_toggles {
  id integer [pk]
  flag_name varchar
  gate_type varchar
  target varchar
  enabled boolean
}

Table oban_jobs {
  id integer [pk]
  state varchar
  queue varchar
  worker varchar
  args jsonb
  meta jsonb
  tags array
  errors array
  attempt integer
  attempted_by array
  max_attempts integer
  priority integer
  attempted_at timestamp
  cancelled_at timestamp
  completed_at timestamp
  discarded_at timestamp
  inserted_at timestamp
  scheduled_at timestamp
}

Table events_v2 {
  name unknown
  site_id unknown
  hostname varchar
  pathname varchar
  user_id unknown
  session_id unknown
  timestamp timestamp
  "meta.key" array
  "meta.value" array
  revenue_source_amount unknown
  revenue_source_currency unknown
  revenue_reporting_amount unknown
  revenue_reporting_currency unknown
  referrer varchar
  referrer_source varchar
  utm_medium varchar
  utm_source varchar
  utm_campaign varchar
  utm_content varchar
  utm_term varchar
  country_code unknown
  subdivision1_code unknown
  subdivision2_code unknown
  city_geoname_id unknown
  screen_size unknown
  operating_system unknown
  operating_system_version unknown
  browser unknown
  browser_version unknown
}

Table sessions_v2 {
  hostname varchar
  site_id unknown
  user_id unknown
  session_id unknown
  start timestamp
  duration unknown
  is_bounce unknown
  entry_page varchar
  exit_page varchar
  exit_page_hostname varchar
  pageviews unknown
  events unknown
  sign unknown
  "entry_meta.key" array
  "entry_meta.value" array
  utm_medium varchar
  utm_source varchar
  utm_campaign varchar
  utm_content varchar
  utm_term varchar
  referrer varchar
  referrer_source varchar
  country_code unknown
  subdivision1_code unknown
  subdivision2_code unknown
  city_geoname_id unknown
  screen_size unknown
  operating_system unknown
  operating_system_version unknown
  browser unknown
  browser_version unknown
  timestamp timestamp
  transferred_from varchar
}

Table funnels {
  id integer [pk]
  name varchar
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table goals {
  id integer [pk]
  event_name varchar
  page_path varchar
  currency currency
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table sites {
  id integer [pk]
  domain varchar
  timezone varchar
  public boolean
  locked boolean
  stats_start_date date
  native_stats_start_at timestamp
  allowed_event_props array
  conversions_enabled boolean
  props_enabled boolean
  funnels_enabled boolean
  ingest_rate_limit_scale_seconds integer
  ingest_rate_limit_threshold integer
  domain_changed_from varchar
  domain_changed_at timestamp
  imported_data jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table api_keys {
  id integer [pk]
  name varchar
  scopes array
  hourly_request_limit integer
  key_hash varchar
  key_prefix varchar
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table email_activation_codes {
  id integer [pk]
  code varchar
  issued_at timestamp
  user_id integer
}

Table invitations {
  id integer [pk]
  invitation_id varchar
  email varchar
  role role
  inviter_id integer
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table totp_recovery_codes {
  id integer [pk]
  code_digest varchar
  user_id integer
  inserted_at timestamp
}

Table users {
  id integer [pk]
  email varchar
  password_hash varchar
  name varchar
  last_seen timestamp
  trial_expiry_date date
  theme theme
  email_verified boolean
  previous_email varchar
  accept_traffic_until date
  allow_next_upgrade_override boolean
  totp_enabled boolean
  totp_secret bytea
  totp_token varchar
  totp_last_used_at timestamp
  grace_period jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table enterprise_plans {
  id integer [pk]
  paddle_plan_id varchar
  billing_interval billing_interval
  monthly_pageview_limit integer
  site_limit integer
  team_member_limit integer
  features array
  hourly_api_request_limit integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table subscriptions {
  id integer [pk]
  paddle_subscription_id varchar
  paddle_plan_id varchar
  update_url varchar
  cancel_url varchar
  status subscriptions_status
  next_bill_amount varchar
  next_bill_date date
  last_bill_date date
  currency_code varchar
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table domains_lookup {
  site_id unknown
  domain varchar
}

Table funnel_steps {
  id integer [pk]
  step_order integer
  funnel_id integer
  goal_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table imported_browsers {
  site_id unknown
  import_id unknown
  date date
  browser varchar
  browser_version varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_devices {
  site_id unknown
  import_id unknown
  date date
  device varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_entry_pages {
  site_id unknown
  import_id unknown
  date date
  entry_page varchar
  visitors unknown
  entrances unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_exit_pages {
  site_id unknown
  import_id unknown
  date date
  exit_page varchar
  exits unknown
  visitors unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_locations {
  site_id unknown
  import_id unknown
  date date
  country varchar
  region varchar
  city unknown
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_operating_systems {
  site_id unknown
  import_id unknown
  date date
  operating_system varchar
  operating_system_version varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_pages {
  site_id unknown
  import_id unknown
  date date
  hostname varchar
  page varchar
  visits unknown
  visitors unknown
  active_visitors unknown
  pageviews unknown
  exits unknown
  time_on_page unknown
}

Table site_imports {
  id integer [pk]
  start_date date
  end_date date
  label varchar
  source source
  status site_imports_status
  legacy boolean
  site_id integer
  imported_by_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table imported_sources {
  site_id unknown
  import_id unknown
  date date
  source varchar
  referrer varchar
  utm_source varchar
  utm_medium varchar
  utm_campaign varchar
  utm_content varchar
  utm_term varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_visitors {
  site_id unknown
  import_id unknown
  date date
  visitors unknown
  pageviews unknown
  bounces unknown
  visits unknown
  visit_duration unknown
}

Table ingest_counters {
  event_timebucket timestamp
  site_id unknown
  domain unknown
  metric unknown
  value unknown
}

Table plugins_api_tokens {
  id uuid [pk]
  inserted_at timestamp
  updated_at timestamp
  token_hash bytea
  description varchar
  hint varchar
  last_used_at timestamp
  site_id integer
}

Table shield_rules_country {
  id uuid [pk]
  site_id integer
  country_code varchar
  action action
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table shield_rules_hostname {
  id uuid [pk]
  site_id integer
  hostname varchar
  hostname_pattern varchar
  action action
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table shield_rules_ip {
  id uuid [pk]
  site_id integer
  inet inet
  action action
  description varchar
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table shield_rules_page {
  id uuid [pk]
  site_id integer
  page_path varchar
  page_path_pattern varchar
  action action
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table google_auth {
  id integer [pk]
  email varchar
  property varchar
  refresh_token varchar
  access_token varchar
  expires timestamp
  user_id integer
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table site_memberships {
  id integer [pk]
  role role
  site_id integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table monthly_reports {
  id integer [pk]
  recipients array
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table shared_links {
  id integer [pk]
  site_id integer
  name varchar
  slug varchar
  password_hash varchar
  inserted_at timestamp
  updated_at timestamp
}

Table spike_notifications {
  id integer [pk]
  recipients array
  threshold integer
  last_sent timestamp
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table site_user_preferences {
  id integer [pk]
  pinned_at timestamp
  user_id integer
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table weekly_reports {
  id integer [pk]
  recipients array
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Ref: funnels.id < funnel_steps.funnel_id
Ref: goals.id < funnel_steps.goal_id
Ref: sites.id < funnels.site_id
Ref: sites.id < goals.site_id
Ref: sites.id - google_auth.site_id
Ref: sites.id < invitations.site_id
Ref: sites.id - monthly_reports.site_id
Ref: sites.id < plugins_api_tokens.site_id
Ref: sites.id < shared_links.site_id
Ref: sites.id < shield_rules_country.site_id
Ref: sites.id < shield_rules_hostname.site_id
Ref: sites.id < shield_rules_ip.site_id
Ref: sites.id < shield_rules_page.site_id
Ref: sites.id < site_imports.site_id
Ref: sites.id - site_memberships.site_id
Ref: sites.id < site_user_preferences.site_id
Ref: sites.id - spike_notifications.site_id
Ref: sites.id - weekly_reports.site_id
Ref: users.id < api_keys.user_id
Ref: users.id < email_activation_codes.user_id
Ref: users.id - enterprise_plans.user_id
Ref: users.id - google_auth.user_id
Ref: users.id < invitations.inviter_id
Ref: users.id < site_imports.imported_by_id
Ref: users.id < site_memberships.user_id
Ref: users.id < site_user_preferences.user_id
Ref: users.id - subscriptions.user_id
Ref: users.id < totp_recovery_codes.user_id

================================================
FILE: examples/dbml/plausible-analytics/Default.dbml
================================================

Enum billing_interval {
  yearly
  monthly
}

Enum currency {
  KMF
  AUD
  SAR
  BWP
  BBD
  EGP
  YER
  CDF
  IQD
  MRU
  JOD
  XPT
  XBB
  NGN
  BDT
  CNY
  ANG
  GTQ
  HTG
  TWD
  OMR
  STN
  AOA
  MUR
  XCD
  TND
  THB
  KES
  GIP
  MZN
  ERN
  MAD
  FKP
  MVR
  BND
  KZT
  EUR
  SYP
  MYR
  RSD
  KRW
  COU
  GMD
  ILS
  BAM
  XAG
  AZN
  AFN
  AWG
  SOS
  PAB
  AED
  UYI
  BTN
  USN
  KPW
  IDR
  XPD
  MOP
  GEL
  MXV
  CHW
  XAF
  UGX
  DJF
  SGD
  PGK
  IRR
  VES
  PHP
  SSP
  BOB
  XDR
  JPY
  BHD
  UAH
  ZAR
  BSD
  TMT
  XOF
  XTS
  MNT
  XSU
  XPF
  TTD
  PLN
  AMD
  SBD
  LSL
  GBP
  DOP
  SEK
  MDL
  CUP
  CZK
  SZL
  COP
  XAU
  NOK
  CLF
  RWF
  NAD
  KHR
  TRY
  LAK
  SDG
  XXX
  PEN
  LBP
  BZD
  CLP
  KGS
  TZS
  GNF
  KWD
  NZD
  SVC
  LRD
  CHF
  PKR
  SHP
  XUA
  XBD
  LYD
  BIF
  JMD
  ALL
  BYN
  CUC
  UZS
  MKD
  ZWL
  RON
  NIO
  MMK
  SRD
  ETB
  ARS
  GHS
  XBA
  XBC
  UYW
  HKD
  ISK
  DZD
  MWK
  RUB
  SLL
  SCR
  CHE
  CVE
  VND
  ZMW
  HNL
  HUF
  INR
  DKK
  FJD
  HRK
  UYU
  PYG
  BMD
  KYD
  VUV
  BGN
  TOP
  MXN
  CAD
  MGA
  BOV
  BRL
  WST
  NPR
  CRC
  GYD
  TJS
  LKR
  QAR
  USD
}

Enum role {
  owner
  admin
  viewer
}

Enum action {
  allow
  deny
}

Enum source {
  noop
  csv
  universal_analytics
  google_analytics_4
}

Enum site_imports_status {
  pending
  failed
  completed
  importing
}

Enum subscriptions_status {
  active
  deleted
  past_due
  paused
}

Enum theme {
  system
  light
  dark
}

Table schema_migrations {
  version integer [pk]
  inserted_at timestamp
}

Table fun_with_flags_toggles {
  id integer [pk]
  flag_name varchar
  gate_type varchar
  target varchar
  enabled boolean
}

Table oban_jobs {
  id integer [pk]
  state varchar
  queue varchar
  worker varchar
  args jsonb
  meta jsonb
  tags array
  errors array
  attempt integer
  attempted_by array
  max_attempts integer
  priority integer
  attempted_at timestamp
  cancelled_at timestamp
  completed_at timestamp
  discarded_at timestamp
  inserted_at timestamp
  scheduled_at timestamp
}

Table api_keys {
  id integer [pk]
  name varchar
  scopes array
  hourly_request_limit integer
  key_hash varchar
  key_prefix varchar
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table email_activation_codes {
  id integer [pk]
  code varchar
  issued_at timestamp
  user_id integer
}

Table invitations {
  id integer [pk]
  invitation_id varchar
  email varchar
  role role
  inviter_id integer
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table totp_recovery_codes {
  id integer [pk]
  code_digest varchar
  user_id integer
  inserted_at timestamp
}

Table users {
  id integer [pk]
  email varchar
  password_hash varchar
  name varchar
  last_seen timestamp
  trial_expiry_date date
  theme theme
  email_verified boolean
  previous_email varchar
  accept_traffic_until date
  allow_next_upgrade_override boolean
  totp_enabled boolean
  totp_secret bytea
  totp_token varchar
  totp_last_used_at timestamp
  grace_period jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table enterprise_plans {
  id integer [pk]
  paddle_plan_id varchar
  billing_interval billing_interval
  monthly_pageview_limit integer
  site_limit integer
  team_member_limit integer
  features array
  hourly_api_request_limit integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table subscriptions {
  id integer [pk]
  paddle_subscription_id varchar
  paddle_plan_id varchar
  update_url varchar
  cancel_url varchar
  status subscriptions_status
  next_bill_amount varchar
  next_bill_date date
  last_bill_date date
  currency_code varchar
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table events_v2 {
  name unknown
  site_id unknown
  hostname varchar
  pathname varchar
  user_id unknown
  session_id unknown
  timestamp timestamp
  "meta.key" array
  "meta.value" array
  revenue_source_amount unknown
  revenue_source_currency unknown
  revenue_reporting_amount unknown
  revenue_reporting_currency unknown
  referrer varchar
  referrer_source varchar
  utm_medium varchar
  utm_source varchar
  utm_campaign varchar
  utm_content varchar
  utm_term varchar
  country_code unknown
  subdivision1_code unknown
  subdivision2_code unknown
  city_geoname_id unknown
  screen_size unknown
  operating_system unknown
  operating_system_version unknown
  browser unknown
  browser_version unknown
}

Table sessions_v2 {
  hostname varchar
  site_id unknown
  user_id unknown
  session_id unknown
  start timestamp
  duration unknown
  is_bounce unknown
  entry_page varchar
  exit_page varchar
  exit_page_hostname varchar
  pageviews unknown
  events unknown
  sign unknown
  "entry_meta.key" array
  "entry_meta.value" array
  utm_medium varchar
  utm_source varchar
  utm_campaign varchar
  utm_content varchar
  utm_term varchar
  referrer varchar
  referrer_source varchar
  country_code unknown
  subdivision1_code unknown
  subdivision2_code unknown
  city_geoname_id unknown
  screen_size unknown
  operating_system unknown
  operating_system_version unknown
  browser unknown
  browser_version unknown
  timestamp timestamp
  transferred_from varchar
}

Table domains_lookup {
  site_id unknown
  domain varchar
}

Table funnels {
  id integer [pk]
  name varchar
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table funnel_steps {
  id integer [pk]
  step_order integer
  funnel_id integer
  goal_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table goals {
  id integer [pk]
  event_name varchar
  page_path varchar
  currency currency
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table imported_browsers {
  site_id unknown
  import_id unknown
  date date
  browser varchar
  browser_version varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_devices {
  site_id unknown
  import_id unknown
  date date
  device varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_entry_pages {
  site_id unknown
  import_id unknown
  date date
  entry_page varchar
  visitors unknown
  entrances unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_exit_pages {
  site_id unknown
  import_id unknown
  date date
  exit_page varchar
  exits unknown
  visitors unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_locations {
  site_id unknown
  import_id unknown
  date date
  country varchar
  region varchar
  city unknown
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_operating_systems {
  site_id unknown
  import_id unknown
  date date
  operating_system varchar
  operating_system_version varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_pages {
  site_id unknown
  import_id unknown
  date date
  hostname varchar
  page varchar
  visits unknown
  visitors unknown
  active_visitors unknown
  pageviews unknown
  exits unknown
  time_on_page unknown
}

Table site_imports {
  id integer [pk]
  start_date date
  end_date date
  label varchar
  source source
  status site_imports_status
  legacy boolean
  site_id integer
  imported_by_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table imported_sources {
  site_id unknown
  import_id unknown
  date date
  source varchar
  referrer varchar
  utm_source varchar
  utm_medium varchar
  utm_campaign varchar
  utm_content varchar
  utm_term varchar
  visitors unknown
  visits unknown
  visit_duration unknown
  pageviews unknown
  bounces unknown
}

Table imported_visitors {
  site_id unknown
  import_id unknown
  date date
  visitors unknown
  pageviews unknown
  bounces unknown
  visits unknown
  visit_duration unknown
}

Table ingest_counters {
  event_timebucket timestamp
  site_id unknown
  domain unknown
  metric unknown
  value unknown
}

Table plugins_api_tokens {
  id uuid [pk]
  inserted_at timestamp
  updated_at timestamp
  token_hash bytea
  description varchar
  hint varchar
  last_used_at timestamp
  site_id integer
}

Table shield_rules_country {
  id uuid [pk]
  site_id integer
  country_code varchar
  action action
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table shield_rules_hostname {
  id uuid [pk]
  site_id integer
  hostname varchar
  hostname_pattern varchar
  action action
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table shield_rules_ip {
  id uuid [pk]
  site_id integer
  inet inet
  action action
  description varchar
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table shield_rules_page {
  id uuid [pk]
  site_id integer
  page_path varchar
  page_path_pattern varchar
  action action
  added_by varchar
  inserted_at timestamp
  updated_at timestamp
}

Table sites {
  id integer [pk]
  domain varchar
  timezone varchar
  public boolean
  locked boolean
  stats_start_date date
  native_stats_start_at timestamp
  allowed_event_props array
  conversions_enabled boolean
  props_enabled boolean
  funnels_enabled boolean
  ingest_rate_limit_scale_seconds integer
  ingest_rate_limit_threshold integer
  domain_changed_from varchar
  domain_changed_at timestamp
  imported_data jsonb
  inserted_at timestamp
  updated_at timestamp
}

Table google_auth {
  id integer [pk]
  email varchar
  property varchar
  refresh_token varchar
  access_token varchar
  expires timestamp
  user_id integer
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table site_memberships {
  id integer [pk]
  role role
  site_id integer
  user_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table monthly_reports {
  id integer [pk]
  recipients array
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table shared_links {
  id integer [pk]
  site_id integer
  name varchar
  slug varchar
  password_hash varchar
  inserted_at timestamp
  updated_at timestamp
}

Table spike_notifications {
  id integer [pk]
  recipients array
  threshold integer
  last_sent timestamp
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table site_user_preferences {
  id integer [pk]
  pinned_at timestamp
  user_id integer
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Table weekly_reports {
  id integer [pk]
  recipients array
  site_id integer
  inserted_at timestamp
  updated_at timestamp
}

Ref: funnels.id < funnel_steps.funnel_id
Ref: goals.id < funnel_steps.goal_id
Ref: sites.id < funnels.site_id
Ref: sites.id < goals.site_id
Ref: sites.id - google_auth.site_id
Ref: sites.id < invitations.site_id
Ref: sites.id - monthly_reports.site_id
Ref: sites.id < plugins_api_tokens.site_id
Ref: sites.id < shared_links.site_id
Ref: sites.id < shield_rules_country.site_id
Ref: sites.id < shield_rules_hostname.site_id
Ref: sites.id < shield_rules_ip.site_id
Ref: sites.id < shield_rules_page.site_id
Ref: sites.id < site_imports.site_id
Ref: sites.id - site_memberships.site_id
Ref: sites.id < site_user_preferences.site_id
Ref: sites.id - spike_notifications.site_id
Ref: sites.id - weekly_reports.site_id
Ref: users.id < api_keys.user_id
Ref: users.id < email_activation_codes.user_id
Ref: users.id - enterprise_plans.user_id
Ref: users.id - google_auth.user_id
Ref: users.id < invitations.inviter_id
Ref: users.id < site_imports.imported_by_id
Ref: users.id < site_memberships.user_id
Ref: users.id < site_user_preferences.user_id
Ref: users.id - subscriptions.user_id
Ref: users.id < totp_recovery_codes.user_id

================================================
FILE: examples/dot/changelog.com/Clusters.dot
================================================
digraph {
  ranksep=1.0; rankdir=LR;
  node [shape = none, fontname="Roboto Mono"];
  "Changelog.Feed" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Feed   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>feeds</i></font></td></tr><tr><td align='left' port='field@id'>:id               <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@name'>:name             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@slug'>:slug             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@description'>:description      <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@title_format'>:title_format     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@plusplus'>:plusplus         <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@autosub'>:autosub          <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@starts_at'>:starts_at        <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@cover'>:cover            <i><font color='gray54'>Changelog.Files.Cover.Type     </font></i></td></tr><tr><td align='left' port='field@podcast_ids'>:podcast_ids      <i><font color='gray54'>{:array, :integer}             </font></i></td></tr><tr><td align='left' port='field@person_ids'>:person_ids       <i><font color='gray54'>{:array, :integer}             </font></i></td></tr><tr><td align='left' port='field@owner_id'>:owner_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at      <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at       <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.Subscription" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Subscription   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>subscriptions</i></font></td></tr><tr><td align='left' port='field@id'>:id                  <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@unsubscribed_at'>:unsubscribed_at     <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@context'>:context             <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id          <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id             <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id           <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id          <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at         <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at          <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.Topic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Topic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>topics</i></font></td></tr><tr><td align='left' port='field@id'>:id                 <i><font color='gray54'>:id                           </font></i></td></tr><tr><td align='left' port='field@name'>:name               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@slug'>:slug               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@description'>:description        <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@website'>:website            <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle     <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@icon'>:icon               <i><font color='gray54'>Changelog.Files.Icon.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at        <i><font color='gray54'>:naive_datetime               </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at         <i><font color='gray54'>:naive_datetime               </font></i></td></tr></table>>]
  "Ecto.Migration.SchemaMigration" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Ecto.Migration.SchemaMigration   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>schema_migrations</i></font></td></tr><tr><td align='left' port='field@version'>:version         <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Oban.Job" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Oban.Job   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>oban_jobs</i></font></td></tr><tr><td align='left' port='field@id'>:id               <i><font color='gray54'>:id                    </font></i></td></tr><tr><td align='left' port='field@state'>:state            <i><font color='gray54'>:string                </font></i></td></tr><tr><td align='left' port='field@queue'>:queue            <i><font color='gray54'>:string                </font></i></td></tr><tr><td align='left' port='field@worker'>:worker           <i><font color='gray54'>:string                </font></i></td></tr><tr><td align='left' port='field@args'>:args             <i><font color='gray54'>:map                   </font></i></td></tr><tr><td align='left' port='field@meta'>:meta             <i><font color='gray54'>:map                   </font></i></td></tr><tr><td align='left' port='field@tags'>:tags             <i><font color='gray54'>{:array, :string}      </font></i></td></tr><tr><td align='left' port='field@errors'>:errors           <i><font color='gray54'>{:array, :map}         </font></i></td></tr><tr><td align='left' port='field@attempt'>:attempt          <i><font color='gray54'>:integer               </font></i></td></tr><tr><td align='left' port='field@attempted_by'>:attempted_by     <i><font color='gray54'>{:array, :string}      </font></i></td></tr><tr><td align='left' port='field@max_attempts'>:max_attempts     <i><font color='gray54'>:integer               </font></i></td></tr><tr><td align='left' port='field@priority'>:priority         <i><font color='gray54'>:integer               </font></i></td></tr><tr><td align='left' port='field@attempted_at'>:attempted_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@cancelled_at'>:cancelled_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@completed_at'>:completed_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@discarded_at'>:discarded_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at      <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@scheduled_at'>:scheduled_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr></table>>]
  subgraph cluster_EPISODE {
    style=filled
    fontname="Roboto Mono"
    color = "#b4eeb4"
    label = <<font point-size='24'><b>EPISODE</b></font>>
    "Changelog.Episode" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Episode   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episodes</i></font></td></tr><tr><td align='left' port='field@id'>:id                    <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@slug'>:slug                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@guid'>:guid                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@title'>:title                 <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@subtitle'>:subtitle              <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@type'>:type                  <i><font color='gray54'>Changelog.Episode.Type                               </font></i></td></tr><tr><td align='left' port='field@featured'>:featured              <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@highlight'>:highlight             <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@subhighlight'>:subhighlight          <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@summary'>:summary               <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@notes'>:notes                 <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@doc_url'>:doc_url               <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@socialize_url'>:socialize_url         <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@published'>:published             <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at          <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@recorded_at'>:recorded_at           <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@recorded_live'>:recorded_live         <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@youtube_id'>:youtube_id            <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@cover'>:cover                 <i><font color='gray54'>Changelog.Files.Cover.Type                           </font></i></td></tr><tr><td align='left' port='field@audio_file'>:audio_file            <i><font color='gray54'>Changelog.Files.Audio.Type                           </font></i></td></tr><tr><td align='left' port='field@audio_bytes'>:audio_bytes           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@audio_duration'>:audio_duration        <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@audio_chapters'>:audio_chapters        <i><font color='gray54'>#Ecto.Embedded&lt;[many: Changelog.EpisodeChapter]&gt;     </font></i></td></tr><tr><td align='left' port='field@plusplus_file'>:plusplus_file         <i><font color='gray54'>Changelog.Files.PlusPlus.Type                        </font></i></td></tr><tr><td align='left' port='field@plusplus_bytes'>:plusplus_bytes        <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@plusplus_duration'>:plusplus_duration     <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@plusplus_chapters'>:plusplus_chapters     <i><font color='gray54'>#Ecto.Embedded&lt;[many: Changelog.EpisodeChapter]&gt;     </font></i></td></tr><tr><td align='left' port='field@download_count'>:download_count        <i><font color='gray54'>:float                                               </font></i></td></tr><tr><td align='left' port='field@import_count'>:import_count          <i><font color='gray54'>:float                                               </font></i></td></tr><tr><td align='left' port='field@reach_count'>:reach_count           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@email_subject'>:email_subject         <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email_teaser'>:email_teaser          <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email_content'>:email_content         <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email_sends'>:email_sends           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@email_opens'>:email_opens           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@transcript'>:transcript            <i><font color='gray54'>{:array, :map}                                       </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id            <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@request_id'>:request_id            <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at           <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at            <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr></table>>]
  "Changelog.EpisodeChapter" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td border='1' sides='b' colspan='2' port='header@schema_module'><font point-size='18'>   Changelog.EpisodeChapter   </font></td></tr><tr><td align='left' port='field@id'>:id            <i><font color='gray54'>:binary_id     </font></i></td></tr><tr><td align='left' port='field@title'>:title         <i><font color='gray54'>:string        </font></i></td></tr><tr><td align='left' port='field@starts_at'>:starts_at     <i><font color='gray54'>:float         </font></i></td></tr><tr><td align='left' port='field@ends_at'>:ends_at       <i><font color='gray54'>:float         </font></i></td></tr><tr><td align='left' port='field@link_url'>:link_url      <i><font color='gray54'>:string        </font></i></td></tr><tr><td align='left' port='field@image_url'>:image_url     <i><font color='gray54'>:string        </font></i></td></tr></table>>]
  "Changelog.EpisodeGuest" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeGuest   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_guests</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position          <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@thanks'>:thanks            <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@discount_code'>:discount_code     <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeHost" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeHost   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_hosts</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeRequest" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeRequest   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_requests</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                                 </font></i></td></tr><tr><td align='left' port='field@status'>:status            <i><font color='gray54'>Changelog.EpisodeRequest.Status     </font></i></td></tr><tr><td align='left' port='field@hosts'>:hosts             <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@guests'>:guests            <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@topics'>:topics            <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@pitch'>:pitch             <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@pronunciation'>:pronunciation     <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@message'>:message           <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id        <i><font color='gray54'>:id                                 </font></i></td></tr><tr><td align='left' port='field@submitter_id'>:submitter_id      <i><font color='gray54'>:id                                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime                     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime                     </font></i></td></tr></table>>]
  "Changelog.EpisodeSponsor" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeSponsor   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_sponsors</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@title'>:title           <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@link_url'>:link_url        <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@description'>:description     <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@starts_at'>:starts_at       <i><font color='gray54'>:float              </font></i></td></tr><tr><td align='left' port='field@ends_at'>:ends_at         <i><font color='gray54'>:float              </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@sponsor_id'>:sponsor_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeStat" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeStat   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_stats</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@date'>:date              <i><font color='gray54'>:date               </font></i></td></tr><tr><td align='left' port='field@episode_bytes'>:episode_bytes     <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@total_bytes'>:total_bytes       <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@downloads'>:downloads         <i><font color='gray54'>:float              </font></i></td></tr><tr><td align='left' port='field@uniques'>:uniques           <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@demographics'>:demographics      <i><font color='gray54'>:map                </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  }
  subgraph cluster_NEWS {
    style=filled
    fontname="Roboto Mono"
    color = "#eee5de"
    label = <<font point-size='24'><b>NEWS</b></font>>
    "Changelog.NewsAd" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsAd   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_ads</i></font></td></tr><tr><td align='left' port='field@id'>:id                   <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@url'>:url                  <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@headline'>:headline             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@story'>:story                <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@image'>:image                <i><font color='gray54'>Changelog.Files.Image.Type     </font></i></td></tr><tr><td align='left' port='field@active'>:active               <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@newsletter'>:newsletter           <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@impression_count'>:impression_count     <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@click_count'>:click_count          <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@sponsorship_id'>:sponsorship_id       <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at          <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at           <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.NewsIssue" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsIssue   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_issues</i></font></td></tr><tr><td align='left' port='field@id'>:id               <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@slug'>:slug             <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@note'>:note             <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@teaser'>:teaser           <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@published'>:published        <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at     <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at       <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsIssueAd" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsIssueAd   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_issue_ads</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@image'>:image           <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@ad_id'>:ad_id           <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@issue_id'>:issue_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsIssueItem" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsIssueItem   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_issue_items</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@image'>:image           <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@issue_id'>:issue_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsItem" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsItem   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_items</i></font></td></tr><tr><td align='left' port='field@id'>:id                   <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@status'>:status               <i><font color='gray54'>Changelog.NewsItem.Status      </font></i></td></tr><tr><td align='left' port='field@type'>:type                 <i><font color='gray54'>Changelog.NewsItem.Type        </font></i></td></tr><tr><td align='left' port='field@url'>:url                  <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@headline'>:headline             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@story'>:story                <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@image'>:image                <i><font color='gray54'>Changelog.Files.Image.Type     </font></i></td></tr><tr><td align='left' port='field@object_id'>:object_id            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@feed_only'>:feed_only            <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@pinned'>:pinned               <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at         <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@refreshed_at'>:refreshed_at         <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@impression_count'>:impression_count     <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@click_count'>:click_count          <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@message'>:message              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@author_id'>:author_id            <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@logger_id'>:logger_id            <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@submitter_id'>:submitter_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@source_id'>:source_id            <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at          <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at           <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.NewsItemComment" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsItemComment   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_item_comments</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@content'>:content         <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@approved'>:approved        <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@edited_at'>:edited_at       <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@deleted_at'>:deleted_at      <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@author_id'>:author_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@parent_id'>:parent_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsItemTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsItemTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_item_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsQueue" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsQueue   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_queue</i></font></td></tr><tr><td align='left' port='field@id'>:id           <i><font color='gray54'>:id        </font></i></td></tr><tr><td align='left' port='field@position'>:position     <i><font color='gray54'>:float     </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id      <i><font color='gray54'>:id        </font></i></td></tr></table>>]
  "Changelog.NewsSource" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsSource   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_sources</i></font></td></tr><tr><td align='left' port='field@id'>:id                 <i><font color='gray54'>:id                           </font></i></td></tr><tr><td align='left' port='field@name'>:name               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@slug'>:slug               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@website'>:website            <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle     <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@description'>:description        <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@feed'>:feed               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@regex'>:regex              <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@publication'>:publication        <i><font color='gray54'>:boolean                      </font></i></td></tr><tr><td align='left' port='field@icon'>:icon               <i><font color='gray54'>Changelog.Files.Icon.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at        <i><font color='gray54'>:naive_datetime               </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at         <i><font color='gray54'>:naive_datetime               </font></i></td></tr></table>>]
  "Changelog.NewsSponsorship" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsSponsorship   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_sponsorships</i></font></td></tr><tr><td align='left' port='field@id'>:id                   <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@name'>:name                 <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@weeks'>:weeks                <i><font color='gray54'>{:array, :date}     </font></i></td></tr><tr><td align='left' port='field@impression_count'>:impression_count     <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@click_count'>:click_count          <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@sponsor_id'>:sponsor_id           <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at          <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at           <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  }
  subgraph cluster_PERSON {
    style=filled
    fontname="Roboto Mono"
    color = "#f0ffff"
    label = <<font point-size='24'><b>PERSON</b></font>>
    "Changelog.Person" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Person   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>people</i></font></td></tr><tr><td align='left' port='field@id'>:id                        <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@name'>:name                      <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email'>:email                     <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@handle'>:handle                    <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@github_handle'>:github_handle             <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@linkedin_handle'>:linkedin_handle           <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@mastodon_handle'>:mastodon_handle           <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle            <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@slack_id'>:slack_id                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@website'>:website                   <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@bio'>:bio                       <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@location'>:location                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@auth_token'>:auth_token                <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@auth_token_expires_at'>:auth_token_expires_at     <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@joined_at'>:joined_at                 <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@signed_in_at'>:signed_in_at              <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@approved'>:approved                  <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@avatar'>:avatar                    <i><font color='gray54'>Changelog.Files.Avatar.Type                          </font></i></td></tr><tr><td align='left' port='field@admin'>:admin                     <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@host'>:host                      <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@editor'>:editor                    <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@public_profile'>:public_profile            <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@settings'>:settings                  <i><font color='gray54'>#Ecto.Embedded&lt;[one: Changelog.Person.Settings]&gt;     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at               <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at                <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr></table>>]
  "Changelog.Person.Settings" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td border='1' sides='b' colspan='2' port='header@schema_module'><font point-size='18'>   Changelog.Person.Settings   </font></td></tr><tr><td align='left' port='field@subscribe_to_contributed_news'>:subscribe_to_contributed_news          <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@subscribe_to_participated_episodes'>:subscribe_to_participated_episodes     <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_authored_news'>:email_on_authored_news                 <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_submitted_news'>:email_on_submitted_news                <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_comment_replies'>:email_on_comment_replies               <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_comment_mentions'>:email_on_comment_mentions              <i><font color='gray54'>:boolean     </font></i></td></tr></table>>]
  }
  subgraph cluster_PODCAST {
    style=filled
    fontname="Roboto Mono"
    color = "#ffefd5"
    label = <<font point-size='24'><b>PODCAST</b></font>>
    "Changelog.Podcast" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Podcast   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>podcasts</i></font></td></tr><tr><td align='left' port='field@id'>:id                       <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@name'>:name                     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@slug'>:slug                     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@status'>:status                   <i><font color='gray54'>Changelog.Podcast.Status       </font></i></td></tr><tr><td align='left' port='field@welcome'>:welcome                  <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@description'>:description              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@extended_description'>:extended_description     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@vanity_domain'>:vanity_domain            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@keywords'>:keywords                 <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@mastodon_handle'>:mastodon_handle          <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle           <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@apple_url'>:apple_url                <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@spotify_url'>:spotify_url              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@riverside_url'>:riverside_url            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@chartable_id'>:chartable_id             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@schedule_note'>:schedule_note            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@download_count'>:download_count           <i><font color='gray54'>:float                         </font></i></td></tr><tr><td align='left' port='field@reach_count'>:reach_count              <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@recorded_live'>:recorded_live            <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@partner'>:partner                  <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@position'>:position                 <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@subscribers'>:subscribers              <i><font color='gray54'>:map                           </font></i></td></tr><tr><td align='left' port='field@cover'>:cover                    <i><font color='gray54'>Changelog.Files.Cover.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at              <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at               <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.PodcastHost" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.PodcastHost   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>podcast_hosts</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@retired'>:retired         <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.PodcastTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.PodcastTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>podcast_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  }
  subgraph cluster_POST {
    style=filled
    fontname="Roboto Mono"
    color = "#eee5de"
    label = <<font point-size='24'><b>POST</b></font>>
    "Changelog.Post" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Post   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>posts</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@title'>:title             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@subtitle'>:subtitle          <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@slug'>:slug              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@guid'>:guid              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@canonical_url'>:canonical_url     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@image'>:image             <i><font color='gray54'>Changelog.Files.Image.Type     </font></i></td></tr><tr><td align='left' port='field@tldr'>:tldr              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@body'>:body              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@published'>:published         <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at      <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@author_id'>:author_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@editor_id'>:editor_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.PostTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.PostTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>post_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@post_id'>:post_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  }
  subgraph cluster_SPONSOR {
    style=filled
    fontname="Roboto Mono"
    color = "#fffafa"
    label = <<font point-size='24'><b>SPONSOR</b></font>>
    "Changelog.Sponsor" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Sponsor   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>sponsors</i></font></td></tr><tr><td align='left' port='field@id'>:id                 <i><font color='gray54'>:id                                </font></i></td></tr><tr><td align='left' port='field@name'>:name               <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@description'>:description        <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@website'>:website            <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@github_handle'>:github_handle      <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle     <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@avatar'>:avatar             <i><font color='gray54'>Changelog.Files.Avatar.Type        </font></i></td></tr><tr><td align='left' port='field@color_logo'>:color_logo         <i><font color='gray54'>Changelog.Files.ColorLogo.Type     </font></i></td></tr><tr><td align='left' port='field@dark_logo'>:dark_logo          <i><font color='gray54'>Changelog.Files.DarkLogo.Type      </font></i></td></tr><tr><td align='left' port='field@light_logo'>:light_logo         <i><font color='gray54'>Changelog.Files.LightLogo.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at        <i><font color='gray54'>:naive_datetime                    </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at         <i><font color='gray54'>:naive_datetime                    </font></i></td></tr></table>>]
  "Changelog.SponsorRep" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.SponsorRep   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>sponsor_reps</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@sponsor_id'>:sponsor_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  }

  "Changelog.EpisodeRequest":"field@id":e -> "Changelog.Episode":"field@request_id":w [dir=none]
  "Changelog.Episode":"field@audio_chapters":e -> "Changelog.EpisodeChapter":"header@schema_module":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeGuest":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeHost":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeSponsor":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeStat":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeTopic":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.Subscription":"field@episode_id":w
  "Changelog.Episode":"field@plusplus_chapters":e -> "Changelog.EpisodeChapter":"header@schema_module":w
  "Changelog.NewsAd":"field@id":e -> "Changelog.NewsIssueAd":"field@ad_id":w
  "Changelog.NewsIssue":"field@id":e -> "Changelog.NewsIssueAd":"field@issue_id":w
  "Changelog.NewsIssue":"field@id":e -> "Changelog.NewsIssueItem":"field@issue_id":w
  "Changelog.NewsItemComment":"field@id":e -> "Changelog.NewsItemComment":"field@parent_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsIssueItem":"field@item_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsItemComment":"field@item_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsItemTopic":"field@item_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsQueue":"field@item_id":w [dir=none]
  "Changelog.NewsItem":"field@id":e -> "Changelog.Subscription":"field@item_id":w
  "Changelog.NewsSource":"field@id":e -> "Changelog.NewsItem":"field@source_id":w
  "Changelog.NewsSponsorship":"field@id":e -> "Changelog.NewsAd":"field@sponsorship_id":w
  "Changelog.Person":"field@id":e -> "Changelog.EpisodeGuest":"field@person_id":w
  "Changelog.Person":"field@id":e -> "Changelog.EpisodeHost":"field@person_id":w
  "Changelog.Person":"field@id":e -> "Changelog.EpisodeRequest":"field@submitter_id":w
  "Changelog.Person":"field@id":e -> "Changelog.Feed":"field@owner_id":w
  "Changelog.Person":"field@id":e -> "Changelog.NewsItemComment":"field@author_id":w
  "Changelog.Person":"field@id":e -> "Changelog.NewsItem":"field@author_id":w
  "Changelog.Person":"field@id":e -> "Changelog.NewsItem":"field@logger_id":w
  "Changelog.Person":"field@id":e -> "Changelog.NewsItem":"field@submitter_id":w
  "Changelog.Person":"field@id":e -> "Changelog.PodcastHost":"field@person_id":w
  "Changelog.Person":"field@id":e -> "Changelog.Post":"field@author_id":w
  "Changelog.Person":"field@id":e -> "Changelog.Post":"field@editor_id":w
  "Changelog.Person":"field@id":e -> "Changelog.SponsorRep":"field@person_id":w
  "Changelog.Person":"field@id":e -> "Changelog.Subscription":"field@person_id":w
  "Changelog.Person":"field@settings":e -> "Changelog.Person.Settings":"header@schema_module":w [dir=none]
  "Changelog.Podcast":"field@id":e -> "Changelog.EpisodeRequest":"field@podcast_id":w
  "Changelog.Podcast":"field@id":e -> "Changelog.EpisodeStat":"field@podcast_id":w
  "Changelog.Podcast":"field@id":e -> "Changelog.Episode":"field@podcast_id":w
  "Changelog.Podcast":"field@id":e -> "Changelog.PodcastHost":"field@podcast_id":w
  "Changelog.Podcast":"field@id":e -> "Changelog.PodcastTopic":"field@podcast_id":w
  "Changelog.Podcast":"field@id":e -> "Changelog.Subscription":"field@podcast_id":w
  "Changelog.Post":"field@id":e -> "Changelog.PostTopic":"field@post_id":w
  "Changelog.Sponsor":"field@id":e -> "Changelog.EpisodeSponsor":"field@sponsor_id":w
  "Changelog.Sponsor":"field@id":e -> "Changelog.NewsSponsorship":"field@sponsor_id":w
  "Changelog.Sponsor":"field@id":e -> "Changelog.SponsorRep":"field@sponsor_id":w
  "Changelog.Topic":"field@id":e -> "Changelog.EpisodeTopic":"field@topic_id":w
  "Changelog.Topic":"field@id":e -> "Changelog.NewsItemTopic":"field@topic_id":w
  "Changelog.Topic":"field@id":e -> "Changelog.PodcastTopic":"field@topic_id":w
  "Changelog.Topic":"field@id":e -> "Changelog.PostTopic":"field@topic_id":w
}


================================================
FILE: examples/dot/changelog.com/Default.dot
================================================
digraph {
  ranksep=1.0; rankdir=LR;
  node [shape = none, fontname="Roboto Mono"];
  "Changelog.Episode" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Episode   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episodes</i></font></td></tr><tr><td align='left' port='field@id'>:id                    <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@slug'>:slug                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@guid'>:guid                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@title'>:title                 <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@subtitle'>:subtitle              <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@type'>:type                  <i><font color='gray54'>Changelog.Episode.Type                               </font></i></td></tr><tr><td align='left' port='field@featured'>:featured              <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@highlight'>:highlight             <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@subhighlight'>:subhighlight          <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@summary'>:summary               <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@notes'>:notes                 <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@doc_url'>:doc_url               <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@socialize_url'>:socialize_url         <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@published'>:published             <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at          <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@recorded_at'>:recorded_at           <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@recorded_live'>:recorded_live         <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@youtube_id'>:youtube_id            <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@cover'>:cover                 <i><font color='gray54'>Changelog.Files.Cover.Type                           </font></i></td></tr><tr><td align='left' port='field@audio_file'>:audio_file            <i><font color='gray54'>Changelog.Files.Audio.Type                           </font></i></td></tr><tr><td align='left' port='field@audio_bytes'>:audio_bytes           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@audio_duration'>:audio_duration        <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@audio_chapters'>:audio_chapters        <i><font color='gray54'>#Ecto.Embedded&lt;[many: Changelog.EpisodeChapter]&gt;     </font></i></td></tr><tr><td align='left' port='field@plusplus_file'>:plusplus_file         <i><font color='gray54'>Changelog.Files.PlusPlus.Type                        </font></i></td></tr><tr><td align='left' port='field@plusplus_bytes'>:plusplus_bytes        <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@plusplus_duration'>:plusplus_duration     <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@plusplus_chapters'>:plusplus_chapters     <i><font color='gray54'>#Ecto.Embedded&lt;[many: Changelog.EpisodeChapter]&gt;     </font></i></td></tr><tr><td align='left' port='field@download_count'>:download_count        <i><font color='gray54'>:float                                               </font></i></td></tr><tr><td align='left' port='field@import_count'>:import_count          <i><font color='gray54'>:float                                               </font></i></td></tr><tr><td align='left' port='field@reach_count'>:reach_count           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@email_subject'>:email_subject         <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email_teaser'>:email_teaser          <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email_content'>:email_content         <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email_sends'>:email_sends           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@email_opens'>:email_opens           <i><font color='gray54'>:integer                                             </font></i></td></tr><tr><td align='left' port='field@transcript'>:transcript            <i><font color='gray54'>{:array, :map}                                       </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id            <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@request_id'>:request_id            <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at           <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at            <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr></table>>]
  "Changelog.EpisodeChapter" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td border='1' sides='b' colspan='2' port='header@schema_module'><font point-size='18'>   Changelog.EpisodeChapter   </font></td></tr><tr><td align='left' port='field@id'>:id            <i><font color='gray54'>:binary_id     </font></i></td></tr><tr><td align='left' port='field@title'>:title         <i><font color='gray54'>:string        </font></i></td></tr><tr><td align='left' port='field@starts_at'>:starts_at     <i><font color='gray54'>:float         </font></i></td></tr><tr><td align='left' port='field@ends_at'>:ends_at       <i><font color='gray54'>:float         </font></i></td></tr><tr><td align='left' port='field@link_url'>:link_url      <i><font color='gray54'>:string        </font></i></td></tr><tr><td align='left' port='field@image_url'>:image_url     <i><font color='gray54'>:string        </font></i></td></tr></table>>]
  "Changelog.EpisodeGuest" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeGuest   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_guests</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position          <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@thanks'>:thanks            <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@discount_code'>:discount_code     <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeHost" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeHost   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_hosts</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeRequest" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeRequest   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_requests</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                                 </font></i></td></tr><tr><td align='left' port='field@status'>:status            <i><font color='gray54'>Changelog.EpisodeRequest.Status     </font></i></td></tr><tr><td align='left' port='field@hosts'>:hosts             <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@guests'>:guests            <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@topics'>:topics            <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@pitch'>:pitch             <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@pronunciation'>:pronunciation     <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@message'>:message           <i><font color='gray54'>:string                             </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id        <i><font color='gray54'>:id                                 </font></i></td></tr><tr><td align='left' port='field@submitter_id'>:submitter_id      <i><font color='gray54'>:id                                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime                     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime                     </font></i></td></tr></table>>]
  "Changelog.EpisodeSponsor" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeSponsor   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_sponsors</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@title'>:title           <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@link_url'>:link_url        <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@description'>:description     <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@starts_at'>:starts_at       <i><font color='gray54'>:float              </font></i></td></tr><tr><td align='left' port='field@ends_at'>:ends_at         <i><font color='gray54'>:float              </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@sponsor_id'>:sponsor_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeStat" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeStat   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_stats</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@date'>:date              <i><font color='gray54'>:date               </font></i></td></tr><tr><td align='left' port='field@episode_bytes'>:episode_bytes     <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@total_bytes'>:total_bytes       <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@downloads'>:downloads         <i><font color='gray54'>:float              </font></i></td></tr><tr><td align='left' port='field@uniques'>:uniques           <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@demographics'>:demographics      <i><font color='gray54'>:map                </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.EpisodeTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.EpisodeTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>episode_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.Feed" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Feed   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>feeds</i></font></td></tr><tr><td align='left' port='field@id'>:id               <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@name'>:name             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@slug'>:slug             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@description'>:description      <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@title_format'>:title_format     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@plusplus'>:plusplus         <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@autosub'>:autosub          <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@starts_at'>:starts_at        <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@cover'>:cover            <i><font color='gray54'>Changelog.Files.Cover.Type     </font></i></td></tr><tr><td align='left' port='field@podcast_ids'>:podcast_ids      <i><font color='gray54'>{:array, :integer}             </font></i></td></tr><tr><td align='left' port='field@person_ids'>:person_ids       <i><font color='gray54'>{:array, :integer}             </font></i></td></tr><tr><td align='left' port='field@owner_id'>:owner_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at      <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at       <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.NewsAd" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsAd   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_ads</i></font></td></tr><tr><td align='left' port='field@id'>:id                   <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@url'>:url                  <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@headline'>:headline             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@story'>:story                <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@image'>:image                <i><font color='gray54'>Changelog.Files.Image.Type     </font></i></td></tr><tr><td align='left' port='field@active'>:active               <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@newsletter'>:newsletter           <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@impression_count'>:impression_count     <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@click_count'>:click_count          <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@sponsorship_id'>:sponsorship_id       <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at          <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at           <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.NewsIssue" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsIssue   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_issues</i></font></td></tr><tr><td align='left' port='field@id'>:id               <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@slug'>:slug             <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@note'>:note             <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@teaser'>:teaser           <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@published'>:published        <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at     <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at       <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsIssueAd" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsIssueAd   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_issue_ads</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@image'>:image           <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@ad_id'>:ad_id           <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@issue_id'>:issue_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsIssueItem" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsIssueItem   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_issue_items</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@image'>:image           <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@issue_id'>:issue_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsItem" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsItem   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_items</i></font></td></tr><tr><td align='left' port='field@id'>:id                   <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@status'>:status               <i><font color='gray54'>Changelog.NewsItem.Status      </font></i></td></tr><tr><td align='left' port='field@type'>:type                 <i><font color='gray54'>Changelog.NewsItem.Type        </font></i></td></tr><tr><td align='left' port='field@url'>:url                  <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@headline'>:headline             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@story'>:story                <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@image'>:image                <i><font color='gray54'>Changelog.Files.Image.Type     </font></i></td></tr><tr><td align='left' port='field@object_id'>:object_id            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@feed_only'>:feed_only            <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@pinned'>:pinned               <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at         <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@refreshed_at'>:refreshed_at         <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@impression_count'>:impression_count     <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@click_count'>:click_count          <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@message'>:message              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@author_id'>:author_id            <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@logger_id'>:logger_id            <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@submitter_id'>:submitter_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@source_id'>:source_id            <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at          <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at           <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.NewsItemComment" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsItemComment   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_item_comments</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@content'>:content         <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@approved'>:approved        <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@edited_at'>:edited_at       <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@deleted_at'>:deleted_at      <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@author_id'>:author_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@parent_id'>:parent_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsItemTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsItemTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_item_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.NewsQueue" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsQueue   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_queue</i></font></td></tr><tr><td align='left' port='field@id'>:id           <i><font color='gray54'>:id        </font></i></td></tr><tr><td align='left' port='field@position'>:position     <i><font color='gray54'>:float     </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id      <i><font color='gray54'>:id        </font></i></td></tr></table>>]
  "Changelog.NewsSource" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsSource   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_sources</i></font></td></tr><tr><td align='left' port='field@id'>:id                 <i><font color='gray54'>:id                           </font></i></td></tr><tr><td align='left' port='field@name'>:name               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@slug'>:slug               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@website'>:website            <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle     <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@description'>:description        <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@feed'>:feed               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@regex'>:regex              <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@publication'>:publication        <i><font color='gray54'>:boolean                      </font></i></td></tr><tr><td align='left' port='field@icon'>:icon               <i><font color='gray54'>Changelog.Files.Icon.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at        <i><font color='gray54'>:naive_datetime               </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at         <i><font color='gray54'>:naive_datetime               </font></i></td></tr></table>>]
  "Changelog.NewsSponsorship" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.NewsSponsorship   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>news_sponsorships</i></font></td></tr><tr><td align='left' port='field@id'>:id                   <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@name'>:name                 <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@weeks'>:weeks                <i><font color='gray54'>{:array, :date}     </font></i></td></tr><tr><td align='left' port='field@impression_count'>:impression_count     <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@click_count'>:click_count          <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@sponsor_id'>:sponsor_id           <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at          <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at           <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.Person" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Person   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>people</i></font></td></tr><tr><td align='left' port='field@id'>:id                        <i><font color='gray54'>:id                                                  </font></i></td></tr><tr><td align='left' port='field@name'>:name                      <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@email'>:email                     <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@handle'>:handle                    <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@github_handle'>:github_handle             <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@linkedin_handle'>:linkedin_handle           <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@mastodon_handle'>:mastodon_handle           <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle            <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@slack_id'>:slack_id                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@website'>:website                   <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@bio'>:bio                       <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@location'>:location                  <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@auth_token'>:auth_token                <i><font color='gray54'>:string                                              </font></i></td></tr><tr><td align='left' port='field@auth_token_expires_at'>:auth_token_expires_at     <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@joined_at'>:joined_at                 <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@signed_in_at'>:signed_in_at              <i><font color='gray54'>:utc_datetime                                        </font></i></td></tr><tr><td align='left' port='field@approved'>:approved                  <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@avatar'>:avatar                    <i><font color='gray54'>Changelog.Files.Avatar.Type                          </font></i></td></tr><tr><td align='left' port='field@admin'>:admin                     <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@host'>:host                      <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@editor'>:editor                    <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@public_profile'>:public_profile            <i><font color='gray54'>:boolean                                             </font></i></td></tr><tr><td align='left' port='field@settings'>:settings                  <i><font color='gray54'>#Ecto.Embedded&lt;[one: Changelog.Person.Settings]&gt;     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at               <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at                <i><font color='gray54'>:naive_datetime                                      </font></i></td></tr></table>>]
  "Changelog.Person.Settings" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td border='1' sides='b' colspan='2' port='header@schema_module'><font point-size='18'>   Changelog.Person.Settings   </font></td></tr><tr><td align='left' port='field@subscribe_to_contributed_news'>:subscribe_to_contributed_news          <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@subscribe_to_participated_episodes'>:subscribe_to_participated_episodes     <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_authored_news'>:email_on_authored_news                 <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_submitted_news'>:email_on_submitted_news                <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_comment_replies'>:email_on_comment_replies               <i><font color='gray54'>:boolean     </font></i></td></tr><tr><td align='left' port='field@email_on_comment_mentions'>:email_on_comment_mentions              <i><font color='gray54'>:boolean     </font></i></td></tr></table>>]
  "Changelog.Podcast" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Podcast   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>podcasts</i></font></td></tr><tr><td align='left' port='field@id'>:id                       <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@name'>:name                     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@slug'>:slug                     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@status'>:status                   <i><font color='gray54'>Changelog.Podcast.Status       </font></i></td></tr><tr><td align='left' port='field@welcome'>:welcome                  <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@description'>:description              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@extended_description'>:extended_description     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@vanity_domain'>:vanity_domain            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@keywords'>:keywords                 <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@mastodon_handle'>:mastodon_handle          <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle           <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@apple_url'>:apple_url                <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@spotify_url'>:spotify_url              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@riverside_url'>:riverside_url            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@chartable_id'>:chartable_id             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@schedule_note'>:schedule_note            <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@download_count'>:download_count           <i><font color='gray54'>:float                         </font></i></td></tr><tr><td align='left' port='field@reach_count'>:reach_count              <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@recorded_live'>:recorded_live            <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@partner'>:partner                  <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@position'>:position                 <i><font color='gray54'>:integer                       </font></i></td></tr><tr><td align='left' port='field@subscribers'>:subscribers              <i><font color='gray54'>:map                           </font></i></td></tr><tr><td align='left' port='field@cover'>:cover                    <i><font color='gray54'>Changelog.Files.Cover.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at              <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at               <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.PodcastHost" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.PodcastHost   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>podcast_hosts</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@retired'>:retired         <i><font color='gray54'>:boolean            </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.PodcastTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.PodcastTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>podcast_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.Post" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Post   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>posts</i></font></td></tr><tr><td align='left' port='field@id'>:id                <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@title'>:title             <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@subtitle'>:subtitle          <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@slug'>:slug              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@guid'>:guid              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@canonical_url'>:canonical_url     <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@image'>:image             <i><font color='gray54'>Changelog.Files.Image.Type     </font></i></td></tr><tr><td align='left' port='field@tldr'>:tldr              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@body'>:body              <i><font color='gray54'>:string                        </font></i></td></tr><tr><td align='left' port='field@published'>:published         <i><font color='gray54'>:boolean                       </font></i></td></tr><tr><td align='left' port='field@published_at'>:published_at      <i><font color='gray54'>:utc_datetime                  </font></i></td></tr><tr><td align='left' port='field@author_id'>:author_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@editor_id'>:editor_id         <i><font color='gray54'>:id                            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at       <i><font color='gray54'>:naive_datetime                </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at        <i><font color='gray54'>:naive_datetime                </font></i></td></tr></table>>]
  "Changelog.PostTopic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.PostTopic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>post_topics</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@position'>:position        <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@topic_id'>:topic_id        <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@post_id'>:post_id         <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.Sponsor" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Sponsor   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>sponsors</i></font></td></tr><tr><td align='left' port='field@id'>:id                 <i><font color='gray54'>:id                                </font></i></td></tr><tr><td align='left' port='field@name'>:name               <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@description'>:description        <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@website'>:website            <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@github_handle'>:github_handle      <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle     <i><font color='gray54'>:string                            </font></i></td></tr><tr><td align='left' port='field@avatar'>:avatar             <i><font color='gray54'>Changelog.Files.Avatar.Type        </font></i></td></tr><tr><td align='left' port='field@color_logo'>:color_logo         <i><font color='gray54'>Changelog.Files.ColorLogo.Type     </font></i></td></tr><tr><td align='left' port='field@dark_logo'>:dark_logo          <i><font color='gray54'>Changelog.Files.DarkLogo.Type      </font></i></td></tr><tr><td align='left' port='field@light_logo'>:light_logo         <i><font color='gray54'>Changelog.Files.LightLogo.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at        <i><font color='gray54'>:naive_datetime                    </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at         <i><font color='gray54'>:naive_datetime                    </font></i></td></tr></table>>]
  "Changelog.SponsorRep" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.SponsorRep   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>sponsor_reps</i></font></td></tr><tr><td align='left' port='field@id'>:id              <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@sponsor_id'>:sponsor_id      <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id       <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at      <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.Subscription" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Subscription   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>subscriptions</i></font></td></tr><tr><td align='left' port='field@id'>:id                  <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@unsubscribed_at'>:unsubscribed_at     <i><font color='gray54'>:utc_datetime       </font></i></td></tr><tr><td align='left' port='field@context'>:context             <i><font color='gray54'>:string             </font></i></td></tr><tr><td align='left' port='field@episode_id'>:episode_id          <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@item_id'>:item_id             <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@person_id'>:person_id           <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@podcast_id'>:podcast_id          <i><font color='gray54'>:id                 </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at         <i><font color='gray54'>:naive_datetime     </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at          <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Changelog.Topic" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Changelog.Topic   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>topics</i></font></td></tr><tr><td align='left' port='field@id'>:id                 <i><font color='gray54'>:id                           </font></i></td></tr><tr><td align='left' port='field@name'>:name               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@slug'>:slug               <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@description'>:description        <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@website'>:website            <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@twitter_handle'>:twitter_handle     <i><font color='gray54'>:string                       </font></i></td></tr><tr><td align='left' port='field@icon'>:icon               <i><font color='gray54'>Changelog.Files.Icon.Type     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at        <i><font color='gray54'>:naive_datetime               </font></i></td></tr><tr><td align='left' port='field@updated_at'>:updated_at         <i><font color='gray54'>:naive_datetime               </font></i></td></tr></table>>]
  "Ecto.Migration.SchemaMigration" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Ecto.Migration.SchemaMigration   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>schema_migrations</i></font></td></tr><tr><td align='left' port='field@version'>:version         <i><font color='gray54'>:integer            </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at     <i><font color='gray54'>:naive_datetime     </font></i></td></tr></table>>]
  "Oban.Job" [label= <<table align='left' border='1' style='rounded' cellspacing='0' cellpadding='4' cellborder='0'><tr><td port='header@schema_module'><font point-size='18'>   Oban.Job   </font></td></tr><tr><td border='1' sides='b' colspan='2'><font point-size='14'><i>oban_jobs</i></font></td></tr><tr><td align='left' port='field@id'>:id               <i><font color='gray54'>:id                    </font></i></td></tr><tr><td align='left' port='field@state'>:state            <i><font color='gray54'>:string                </font></i></td></tr><tr><td align='left' port='field@queue'>:queue            <i><font color='gray54'>:string                </font></i></td></tr><tr><td align='left' port='field@worker'>:worker           <i><font color='gray54'>:string                </font></i></td></tr><tr><td align='left' port='field@args'>:args             <i><font color='gray54'>:map                   </font></i></td></tr><tr><td align='left' port='field@meta'>:meta             <i><font color='gray54'>:map                   </font></i></td></tr><tr><td align='left' port='field@tags'>:tags             <i><font color='gray54'>{:array, :string}      </font></i></td></tr><tr><td align='left' port='field@errors'>:errors           <i><font color='gray54'>{:array, :map}         </font></i></td></tr><tr><td align='left' port='field@attempt'>:attempt          <i><font color='gray54'>:integer               </font></i></td></tr><tr><td align='left' port='field@attempted_by'>:attempted_by     <i><font color='gray54'>{:array, :string}      </font></i></td></tr><tr><td align='left' port='field@max_attempts'>:max_attempts     <i><font color='gray54'>:integer               </font></i></td></tr><tr><td align='left' port='field@priority'>:priority         <i><font color='gray54'>:integer               </font></i></td></tr><tr><td align='left' port='field@attempted_at'>:attempted_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@cancelled_at'>:cancelled_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@completed_at'>:completed_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@discarded_at'>:discarded_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@inserted_at'>:inserted_at      <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr><tr><td align='left' port='field@scheduled_at'>:scheduled_at     <i><font color='gray54'>:utc_datetime_usec     </font></i></td></tr></table>>]

  "Changelog.EpisodeRequest":"field@id":e -> "Changelog.Episode":"field@request_id":w [dir=none]
  "Changelog.Episode":"field@audio_chapters":e -> "Changelog.EpisodeChapter":"header@schema_module":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeGuest":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeHost":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeSponsor":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeStat":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.EpisodeTopic":"field@episode_id":w
  "Changelog.Episode":"field@id":e -> "Changelog.Subscription":"field@episode_id":w
  "Changelog.Episode":"field@plusplus_chapters":e -> "Changelog.EpisodeChapter":"header@schema_module":w
  "Changelog.NewsAd":"field@id":e -> "Changelog.NewsIssueAd":"field@ad_id":w
  "Changelog.NewsIssue":"field@id":e -> "Changelog.NewsIssueAd":"field@issue_id":w
  "Changelog.NewsIssue":"field@id":e -> "Changelog.NewsIssueItem":"field@issue_id":w
  "Changelog.NewsItemComment":"field@id":e -> "Changelog.NewsItemComment":"field@parent_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsIssueItem":"field@item_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsItemComment":"field@item_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsItemTopic":"field@item_id":w
  "Changelog.NewsItem":"field@id":e -> "Changelog.NewsQueue":"field@item_id":w [dir=none]
  "Changelog.NewsItem":"field@id":e -> "Changelog.Subscription":"field@item_id":w
  "Changelog.NewsSource":"field@id":e -> "Changelog.NewsItem":"field@source_id":w
  "Changelog.NewsSponsorship":"field@id":e -> "Changelog.NewsAd":"fie
Download .txt
gitextract_ouem7f1z/

├── .formatter.exs
├── .gitignore
├── LICENSE.txt
├── README.md
├── examples/
│   ├── dbml/
│   │   ├── changelog.com/
│   │   │   ├── Clusters.dbml
│   │   │   └── Default.dbml
│   │   ├── hexpm/
│   │   │   ├── Contexts-as-clusters.dbml
│   │   │   ├── Default.dbml
│   │   │   └── Only-selected-cluster-Accounts-context.dbml
│   │   └── plausible-analytics/
│   │       ├── Contexts-as-clusters.dbml
│   │       └── Default.dbml
│   ├── dot/
│   │   ├── changelog.com/
│   │   │   ├── Clusters.dot
│   │   │   ├── Default.dot
│   │   │   └── No-fields.dot
│   │   ├── hexpm/
│   │   │   ├── Contexts-as-clusters-no-fields.dot
│   │   │   ├── Contexts-as-clusters.dot
│   │   │   ├── Default.dot
│   │   │   ├── No-fields.dot
│   │   │   ├── Only-embedded-schemas.dot
│   │   │   └── Only-selected-cluster-Accounts-context.dot
│   │   └── plausible-analytics/
│   │       ├── Contexts-as-clusters-no-fields.dot
│   │       ├── Contexts-as-clusters.dot
│   │       ├── Default.dot
│   │       └── No-fields.dot
│   ├── mermaid/
│   │   ├── changelog.com/
│   │   │   ├── Default.mmd
│   │   │   └── No-fields.mmd
│   │   ├── hexpm/
│   │   │   ├── Default.mmd
│   │   │   └── No-fields.mmd
│   │   └── plausible-analytics/
│   │       ├── Default.mmd
│   │       └── No-fields.mmd
│   ├── plantuml/
│   │   ├── changelog.com/
│   │   │   ├── Clusters.puml
│   │   │   └── Default.puml
│   │   ├── hexpm/
│   │   │   ├── Contexts-as-clusters-no-fields.puml
│   │   │   ├── Contexts-as-clusters.puml
│   │   │   ├── Default.puml
│   │   │   ├── Only-embedded-schemas.puml
│   │   │   └── Only-selected-cluster-Accounts-context.puml
│   │   └── plausible-analytics/
│   │       ├── Contexts-as-clusters-no-fields.puml
│   │       ├── Contexts-as-clusters.puml
│   │       └── Default.puml
│   └── quick_dbd/
│       ├── changelog.com/
│       │   └── Default.qdbd
│       ├── hexpm/
│       │   ├── Default.qdbd
│       │   └── Only-selected-cluster-Accounts-context.qdbd
│       └── plausible-analytics/
│           └── Default.qdbd
├── examples_generator.exs
├── lib/
│   ├── ecto/
│   │   └── erd/
│   │       ├── color.ex
│   │       ├── document/
│   │       │   ├── dbml.ex
│   │       │   ├── dot.ex
│   │       │   ├── mermaid.ex
│   │       │   ├── plantuml.ex
│   │       │   └── quick_dbd.ex
│   │       ├── document.ex
│   │       ├── edge.ex
│   │       ├── field.ex
│   │       ├── graph.ex
│   │       ├── html.ex
│   │       ├── node.ex
│   │       ├── render.ex
│   │       └── schema_modules.ex
│   └── mix/
│       └── tasks/
│           └── ecto.gen.erd.ex
├── mix.exs
└── test/
    ├── ecto/
    │   └── erd_test.exs
    └── test_helper.exs
Download .txt
SYMBOL INDEX (99 symbols across 18 files)

FILE: examples_generator.exs
  class Ecto.ERD.ExamplesGenerator (line 1) | defmodule Ecto.ERD.ExamplesGenerator
    method run (line 177) | def run(source_url_root) do
    method generate_doc (line 209) | defp generate_doc({project_name, %{repo: repo, examples: examples}}, s...
    method generate_example (line 277) | defp generate_example(example, project_name) do
    method generate_image (line 328) | defp generate_image(:dot, file) do
    method generate_image (line 332) | defp generate_image(:puml, file) do
    method init_project (line 336) | defp init_project(project_name, repo, commit) do
    method slugify (line 352) | defp slugify(name) do
    method add_ecto_erd_to_dependencies (line 356) | defp add_ecto_erd_to_dependencies(path) do
    method projects (line 372) | def projects, do: Map.keys(@data)
    method as_table (line 374) | defp as_table(rows, header) do

FILE: lib/ecto/erd/color.ex
  class Ecto.ERD.Color (line 1) | defmodule Ecto.ERD.Color
    method get (line 15) | def get(term) do

FILE: lib/ecto/erd/document.ex
  class Ecto.ERD.Document (line 1) | defmodule Ecto.ERD.Document

FILE: lib/ecto/erd/document/dbml.ex
  class Ecto.ERD.Document.DBML (line 1) | defmodule Ecto.ERD.Document.DBML
    method schemaless? (line 8) | def schemaless?, do: true
    method render (line 11) | def render(%Graph{nodes: nodes, edges: edges}, _options) do
    method render_edge (line 61) | defp render_edge(%Edge{to: {nil, _, _}}), do: nil
    method render_edge (line 63) | defp render_edge(%Edge{
    method enums_mapping (line 86) | def enums_mapping(nodes) do
    method render_field (line 122) | defp render_field(%Field{name: name, type: type, primary?: primary?}, ...
    method format_type (line 139) | defp format_type(type) do

FILE: lib/ecto/erd/document/dot.ex
  class Ecto.ERD.Document.Dot (line 1) | defmodule Ecto.ERD.Document.Dot
    method schemaless? (line 7) | def schemaless?, do: false
    method render (line 10) | def render(%Graph{nodes: nodes, edges: edges}, opts) do
    method render_edge (line 44) | defp render_edge(
    method render_position (line 62) | defp render_position({source, schema_module, port}, skip_port?) do
    method render_node (line 67) | defp render_node(
    method format_field (line 142) | defp format_field(%Field{name: name}, :name), do: inspect(name)
    method format_field (line 144) | defp format_field(%Field{type: type}, :type), do: format_type(type)
    method format_type (line 146) | defp format_type({:parameterized, {Ecto.Enum, %{on_dump: on_dump}}}) do
    method format_type (line 150) | defp format_type(
    method format_type (line 157) | defp format_type({:array, type}) do
    method format_type (line 161) | defp format_type(type), do: inspect(type)

FILE: lib/ecto/erd/document/mermaid.ex
  class Ecto.ERD.Document.Mermaid (line 1) | defmodule Ecto.ERD.Document.Mermaid
    method schemaless? (line 8) | def schemaless?, do: true
    method render (line 11) | def render(%Graph{nodes: nodes, edges: edges}, opts) do
    method render_node (line 34) | defp render_node(%Node{source: source, fields: fields}, fields_config) do
    method render_edge (line 59) | defp render_edge(%Edge{
    method render_field (line 83) | defp render_field(%Field{} = field) do
    method format_type (line 107) | defp format_type(type) do
    method name_valid? (line 127) | defp name_valid?(source_or_field) do

FILE: lib/ecto/erd/document/plantuml.ex
  class Ecto.ERD.Document.PlantUML (line 1) | defmodule Ecto.ERD.Document.PlantUML
    method schemaless? (line 9) | def schemaless?, do: false
    method render (line 12) | def render(%Graph{nodes: nodes, edges: edges}, opts) do
    method render_node (line 63) | defp render_node(
    method render_edge (line 107) | defp render_edge(%Edge{
    method format_type (line 127) | defp format_type({:parameterized, {Ecto.Enum, %{on_dump: on_dump}}}) do
    method format_type (line 144) | defp format_type(type) do
    method ensure_cluster_names_valid! (line 153) | defp ensure_cluster_names_valid!(names) do

FILE: lib/ecto/erd/document/quick_dbd.ex
  class Ecto.ERD.Document.QuickDBD (line 1) | defmodule Ecto.ERD.Document.QuickDBD
    method schemaless? (line 7) | def schemaless?, do: true
    method render (line 10) | def render(%Graph{nodes: nodes, edges: edges}, _opts) do
    method render_node (line 19) | defp render_node(%Node{source: source, fields: fields}, foreign_keys_m...
    method render_field (line 31) | defp render_field(%Field{name: name, type: type, primary?: primary?}, ...
    method format_type (line 63) | defp format_type({:parameterized, {Ecto.Enum, %{on_dump: on_dump}}}) do
    method format_type (line 67) | defp format_type(type) do

FILE: lib/ecto/erd/edge.ex
  class Ecto.ERD.Edge (line 1) | defmodule Ecto.ERD.Edge
    method connected_with_node? (line 18) | def connected_with_node?(
    method merge (line 29) | def merge(%__MODULE__{} = edge1, %__MODULE__{} = edge2) do

FILE: lib/ecto/erd/field.ex
  class Ecto.ERD.Field (line 1) | defmodule Ecto.ERD.Field
    method new (line 44) | def new(%{name: name, type: type} = params) do

FILE: lib/ecto/erd/graph.ex
  class Ecto.ERD.Graph (line 1) | defmodule Ecto.ERD.Graph
    method new (line 8) | def new(modules, relation_types) do
    method sort (line 24) | def sort(%__MODULE__{nodes: nodes, edges: edges}) do
    method make_schemaless (line 54) | def make_schemaless(%__MODULE__{nodes: nodes, edges: edges}) do
    method merge_edges_with_same_direction (line 73) | defp merge_edges_with_same_direction(edges) do
    method components (line 79) | defp components(schema_module, relation_types) do
    method components_from_relations (line 109) | defp components_from_relations(module, :associations) do
    method components_from_relations (line 117) | defp components_from_relations(module, :embeds) do
    method from_relation_struct (line 125) | defp from_relation_struct(%Ecto.Embedded{
    method from_relation_struct (line 148) | defp from_relation_struct(%Ecto.Association.BelongsTo{
    method from_relation_struct (line 175) | defp from_relation_struct(%Ecto.Association.Has{
    method from_relation_struct (line 203) | defp from_relation_struct(%Ecto.Association.ManyToMany{
    method from_relation_struct (line 272) | defp from_relation_struct(%Ecto.Association.HasThrough{}) do
    method ecto_schema? (line 276) | defp ecto_schema?(module) do

FILE: lib/ecto/erd/html.ex
  class Ecto.ERD.HTML (line 1) | defmodule Ecto.ERD.HTML
    method to_iodata (line 7) | def to_iodata({tag_name, attrs, content}) do
    method to_iodata (line 17) | def to_iodata(term), do: HtmlEntities.encode(to_string(term))
    method tag (line 19) | defp tag(name, attrs, content) do
    method attrs (line 23) | defp attrs([]), do: []
    method attrs (line 25) | defp attrs(attrs) do

FILE: lib/ecto/erd/node.ex
  class Ecto.ERD.Node (line 1) | defmodule Ecto.ERD.Node
    method new (line 46) | def new(schema_module \\ nil, source, fields) do

FILE: lib/ecto/erd/render.ex
  class Ecto.ERD.Render (line 1) | defmodule Ecto.ERD.Render
    method in_quotes (line 4) | def in_quotes(value, pattern \\ ~r/^[a-z\d_]+$/i) do

FILE: lib/ecto/erd/schema_modules.ex
  class Ecto.ERD.SchemaModules (line 1) | defmodule Ecto.ERD.SchemaModules
    method scan (line 4) | def scan(otp_app) do

FILE: lib/mix/tasks/ecto.gen.erd.ex
  class Mix.Tasks.Ecto.Gen.Erd (line 1) | defmodule Mix.Tasks.Ecto.Gen.Erd
    method run (line 124) | def run(args) do

FILE: mix.exs
  class Ecto.ERD.MixProject (line 11) | defmodule Ecto.ERD.MixProject
    method project (line 16) | def project do
    method description (line 32) | defp description do
    method docs (line 36) | defp docs do
    method package (line 51) | defp package do
    method application (line 60) | def application do
    method generate_examples (line 66) | defp generate_examples(_) do
    method deps (line 74) | defp deps do

FILE: test/ecto/erd_test.exs
  class Ecto.ERDTest (line 1) | defmodule Ecto.ERDTest
Condensed preview — 63 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (755K chars).
[
  {
    "path": ".formatter.exs",
    "chars": 97,
    "preview": "# Used by \"mix format\"\n[\n  inputs: [\"{mix,.formatter}.exs\", \"{config,lib,test}/**/*.{ex,exs}\"]\n]\n"
  },
  {
    "path": ".gitignore",
    "chars": 630,
    "preview": "# The directory Mix will write compiled artifacts to.\n/_build/\n\n# If you run \"mix test --cover\", coverage assets end up "
  },
  {
    "path": "LICENSE.txt",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 2405,
    "preview": "# Ecto.ERD\n\n[![Hex.pm](https://img.shields.io/hexpm/v/ecto_erd.svg)](https://hex.pm/packages/ecto_erd)\n\nA mix task for g"
  },
  {
    "path": "examples/dbml/changelog.com/Clusters.dbml",
    "chars": 10069,
    "preview": "TableGroup EPISODE {\n  episodes\n  episode_guests\n  episode_hosts\n  episode_requests\n  episode_sponsors\n  episode_stats\n "
  },
  {
    "path": "examples/dbml/changelog.com/Default.dbml",
    "chars": 9560,
    "preview": "\n\nTable episodes {\n  id integer [pk]\n  slug varchar\n  guid varchar\n  title varchar\n  subtitle varchar\n  type integer\n  f"
  },
  {
    "path": "examples/dbml/hexpm/Contexts-as-clusters.dbml",
    "chars": 5461,
    "preview": "TableGroup \"Ecto.Migration\" {\n  schema_migrations\n}\nTableGroup \"Hexpm.Accounts\" {\n  audit_logs\n  emails\n  keys\n  organiz"
  },
  {
    "path": "examples/dbml/hexpm/Default.dbml",
    "chars": 4915,
    "preview": "\n\nTable schema_migrations {\n  version integer [pk]\n  inserted_at timestamp\n}\n\nTable audit_logs {\n  id integer [pk]\n  use"
  },
  {
    "path": "examples/dbml/hexpm/Only-selected-cluster-Accounts-context.dbml",
    "chars": 2082,
    "preview": "TableGroup \"Hexpm.Accounts\" {\n  audit_logs\n  emails\n  keys\n  organizations\n  organization_users\n  password_resets\n  sess"
  },
  {
    "path": "examples/dbml/plausible-analytics/Contexts-as-clusters.dbml",
    "chars": 12855,
    "preview": "TableGroup \"Ecto.Migration\" {\n  schema_migrations\n}\nTableGroup \"FunWithFlags.Store\" {\n  fun_with_flags_toggles\n}\nTableGr"
  },
  {
    "path": "examples/dbml/plausible-analytics/Default.dbml",
    "chars": 11712,
    "preview": "\nEnum billing_interval {\n  yearly\n  monthly\n}\n\nEnum currency {\n  KMF\n  AUD\n  SAR\n  BWP\n  BBD\n  EGP\n  YER\n  CDF\n  IQD\n  M"
  },
  {
    "path": "examples/dot/changelog.com/Clusters.dot",
    "chars": 65137,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Changelog.Feed\" [label= <<table a"
  },
  {
    "path": "examples/dot/changelog.com/Default.dot",
    "chars": 64197,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Changelog.Episode\" [label= <<tabl"
  },
  {
    "path": "examples/dot/changelog.com/No-fields.dot",
    "chars": 12343,
    "preview": "strict digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Changelog.Episode\" [label="
  },
  {
    "path": "examples/dot/hexpm/Contexts-as-clusters-no-fields.dot",
    "chars": 13308,
    "preview": "strict digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \n  subgraph \"cluster_Ecto.M"
  },
  {
    "path": "examples/dot/hexpm/Contexts-as-clusters.dot",
    "chars": 40266,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \n  subgraph \"cluster_Ecto.Migratio"
  },
  {
    "path": "examples/dot/hexpm/Default.dot",
    "chars": 39374,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Ecto.Migration.SchemaMigration\" ["
  },
  {
    "path": "examples/dot/hexpm/No-fields.dot",
    "chars": 12416,
    "preview": "strict digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Ecto.Migration.SchemaMigra"
  },
  {
    "path": "examples/dot/hexpm/Only-embedded-schemas.dot",
    "chars": 6672,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Hexpm.Accounts.Key.Use\" [label= <"
  },
  {
    "path": "examples/dot/hexpm/Only-selected-cluster-Accounts-context.dot",
    "chars": 18141,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \n  subgraph \"cluster_Hexpm.Account"
  },
  {
    "path": "examples/dot/plausible-analytics/Contexts-as-clusters-no-fields.dot",
    "chars": 18119,
    "preview": "strict digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \n  subgraph \"cluster_Ecto.M"
  },
  {
    "path": "examples/dot/plausible-analytics/Contexts-as-clusters.dot",
    "chars": 84026,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \n  subgraph \"cluster_Ecto.Migratio"
  },
  {
    "path": "examples/dot/plausible-analytics/Default.dot",
    "chars": 81718,
    "preview": "digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Ecto.Migration.SchemaMigration\" ["
  },
  {
    "path": "examples/dot/plausible-analytics/No-fields.dot",
    "chars": 15811,
    "preview": "strict digraph {\n  ranksep=1.0; rankdir=LR;\n  node [shape = none, fontname=\"Roboto Mono\"];\n  \"Ecto.Migration.SchemaMigra"
  },
  {
    "path": "examples/mermaid/changelog.com/Default.mmd",
    "chars": 9827,
    "preview": "erDiagram\n  episodes {\n    integer id PK\n    varchar slug\n    varchar guid\n    varchar title\n    varchar subtitle\n    in"
  },
  {
    "path": "examples/mermaid/changelog.com/No-fields.mmd",
    "chars": 2119,
    "preview": "erDiagram\n  episodes\n  episode_guests\n  episode_hosts\n  episode_requests\n  episode_sponsors\n  episode_stats\n  episode_to"
  },
  {
    "path": "examples/mermaid/hexpm/Default.mmd",
    "chars": 4869,
    "preview": "erDiagram\n  schema_migrations {\n    integer version PK\n    timestamp inserted_at\n  }\n  audit_logs {\n    integer id PK\n  "
  },
  {
    "path": "examples/mermaid/hexpm/No-fields.mmd",
    "chars": 1518,
    "preview": "erDiagram\n  schema_migrations\n  audit_logs\n  emails\n  keys\n  organizations\n  organization_users\n  password_resets\n  sess"
  },
  {
    "path": "examples/mermaid/plausible-analytics/Default.mmd",
    "chars": 10605,
    "preview": "erDiagram\n  schema_migrations {\n    integer version PK\n    timestamp inserted_at\n  }\n  fun_with_flags_toggles {\n    inte"
  },
  {
    "path": "examples/mermaid/plausible-analytics/No-fields.mmd",
    "chars": 1721,
    "preview": "erDiagram\n  schema_migrations\n  fun_with_flags_toggles\n  oban_jobs\n  api_keys\n  email_activation_codes\n  invitations\n  t"
  },
  {
    "path": "examples/plantuml/changelog.com/Clusters.puml",
    "chars": 12060,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/plantuml/changelog.com/Default.puml",
    "chars": 11125,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/plantuml/hexpm/Contexts-as-clusters-no-fields.puml",
    "chars": 3813,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\nhide fields\nskinparam linetype ortho\nskinparam defaultFo"
  },
  {
    "path": "examples/plantuml/hexpm/Contexts-as-clusters.puml",
    "chars": 8343,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/plantuml/hexpm/Default.puml",
    "chars": 7604,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/plantuml/hexpm/Only-embedded-schemas.puml",
    "chars": 1215,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/plantuml/hexpm/Only-selected-cluster-Accounts-context.puml",
    "chars": 3677,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/plantuml/plausible-analytics/Contexts-as-clusters-no-fields.puml",
    "chars": 3816,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\nhide fields\nskinparam linetype ortho\nskinparam defaultFo"
  },
  {
    "path": "examples/plantuml/plausible-analytics/Contexts-as-clusters.puml",
    "chars": 14890,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/plantuml/plausible-analytics/Default.puml",
    "chars": 13313,
    "preview": "@startuml\n\nset namespaceSeparator none\nhide circle\nhide methods\n\nskinparam linetype ortho\nskinparam defaultFontName Robo"
  },
  {
    "path": "examples/quick_dbd/changelog.com/Default.qdbd",
    "chars": 7513,
    "preview": "episodes\n---\nid integer PK\nslug varchar\nguid varchar\ntitle varchar\nsubtitle varchar\ntype integer\nfeatured boolean\nhighli"
  },
  {
    "path": "examples/quick_dbd/hexpm/Default.qdbd",
    "chars": 3617,
    "preview": "schema_migrations\n---\nversion integer PK\ninserted_at timestamp\n\naudit_logs\n---\nid integer PK\nuser_agent varchar\nremote_i"
  },
  {
    "path": "examples/quick_dbd/hexpm/Only-selected-cluster-Accounts-context.qdbd",
    "chars": 1514,
    "preview": "audit_logs\n---\nid integer PK\nuser_agent varchar\nremote_ip varchar\naction varchar\nparams jsonb\nuser_id integer FK >- user"
  },
  {
    "path": "examples/quick_dbd/plausible-analytics/Default.qdbd",
    "chars": 9395,
    "preview": "schema_migrations\n---\nversion integer PK\ninserted_at timestamp\n\nfun_with_flags_toggles\n---\nid integer PK\nflag_name varch"
  },
  {
    "path": "examples_generator.exs",
    "chars": 12360,
    "preview": "defmodule Ecto.ERD.ExamplesGenerator do\n  require Logger\n\n  @shared_examples [\n    [name: \"Default\", formats: [:dbml, :d"
  },
  {
    "path": "lib/ecto/erd/color.ex",
    "chars": 296,
    "preview": "defmodule Ecto.ERD.Color do\n  @moduledoc false\n  @colors ~w(\n      #eedfcc\n      #f0ffff\n      #eee5de\n      #fffafa\n   "
  },
  {
    "path": "lib/ecto/erd/document/dbml.ex",
    "chars": 4149,
    "preview": "defmodule Ecto.ERD.Document.DBML do\n  @moduledoc false\n  alias Ecto.ERD.{Node, Field, Edge, Graph, Render}\n\n  @behaviour"
  },
  {
    "path": "lib/ecto/erd/document/dot.ex",
    "chars": 4828,
    "preview": "defmodule Ecto.ERD.Document.Dot do\n  @moduledoc false\n  alias Ecto.ERD.{HTML, Edge, Node, Field, Graph, Render}\n  @behav"
  },
  {
    "path": "lib/ecto/erd/document/mermaid.ex",
    "chars": 3168,
    "preview": "defmodule Ecto.ERD.Document.Mermaid do\n  @moduledoc false\n  alias Ecto.ERD.{Node, Field, Edge, Graph}\n  @behaviour Ecto."
  },
  {
    "path": "lib/ecto/erd/document/plantuml.ex",
    "chars": 4076,
    "preview": "defmodule Ecto.ERD.Document.PlantUML do\n  @moduledoc false\n  alias Ecto.ERD.{Node, Edge, Graph, Render, Color}\n\n  @behav"
  },
  {
    "path": "lib/ecto/erd/document/quick_dbd.ex",
    "chars": 2292,
    "preview": "defmodule Ecto.ERD.Document.QuickDBD do\n  @moduledoc false\n  alias Ecto.ERD.{Node, Field, Edge, Graph, Render}\n  @behavi"
  },
  {
    "path": "lib/ecto/erd/document.ex",
    "chars": 1064,
    "preview": "defmodule Ecto.ERD.Document do\n  @moduledoc false\n  @callback render(Ecto.ERD.Graph.t(), opts :: Keyword.t()) :: iodata("
  },
  {
    "path": "lib/ecto/erd/edge.ex",
    "chars": 937,
    "preview": "defmodule Ecto.ERD.Edge do\n  @moduledoc false\n  defstruct [:from, :to, :assoc_types]\n\n  def new(%{\n        from: {_sourc"
  },
  {
    "path": "lib/ecto/erd/field.ex",
    "chars": 1275,
    "preview": "defmodule Ecto.ERD.Field do\n  @moduledoc \"\"\"\n  Field struct.\n\n  Represents the data for an individual field in `Ecto.ERD"
  },
  {
    "path": "lib/ecto/erd/graph.ex",
    "chars": 8136,
    "preview": "defmodule Ecto.ERD.Graph do\n  @moduledoc false\n  alias Ecto.ERD.{Edge, Node, Field}\n  defstruct [:edges, :nodes]\n  requi"
  },
  {
    "path": "lib/ecto/erd/html.ex",
    "chars": 675,
    "preview": "defmodule Ecto.ERD.HTML do\n  @moduledoc false\n  def to_iodata(tuples) when is_list(tuples) do\n    Enum.map(tuples, &to_i"
  },
  {
    "path": "lib/ecto/erd/node.ex",
    "chars": 2475,
    "preview": "defmodule Ecto.ERD.Node do\n  @moduledoc \"\"\"\n  Node struct.\n\n  * If `source` is `nil`, then `schema_module` cannot be `ni"
  },
  {
    "path": "lib/ecto/erd/render.ex",
    "chars": 299,
    "preview": "defmodule Ecto.ERD.Render do\n  @moduledoc false\n\n  def in_quotes(value, pattern \\\\ ~r/^[a-z\\d_]+$/i) do\n    value = to_s"
  },
  {
    "path": "lib/ecto/erd/schema_modules.ex",
    "chars": 532,
    "preview": "defmodule Ecto.ERD.SchemaModules do\n  @moduledoc false\n\n  def scan(otp_app) do\n    {:ok, applications} = :application.ge"
  },
  {
    "path": "lib/mix/tasks/ecto.gen.erd.ex",
    "chars": 6348,
    "preview": "defmodule Mix.Tasks.Ecto.Gen.Erd do\n  @moduledoc \"\"\"\n  A Mix task that generates an ERD (Entity‑Relationship Diagram) in"
  },
  {
    "path": "mix.exs",
    "chars": 1846,
    "preview": "# examples_generator.exs is needed only for docs and is not shipped in package\nif File.exists?(\"examples_generator.exs\")"
  },
  {
    "path": "test/ecto/erd_test.exs",
    "chars": 2678,
    "preview": "defmodule Ecto.ERDTest do\n  use ExUnit.Case\n  alias Ecto.ERD.{Node, Field, Graph}\n  alias Ecto.ERD.Document.{DBML, Dot}\n"
  },
  {
    "path": "test/test_helper.exs",
    "chars": 15,
    "preview": "ExUnit.start()\n"
  }
]

About this extraction

This page contains the full source code of the fuelen/ecto_erd GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 63 files (715.5 KB), approximately 206.0k tokens, and a symbol index with 99 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!