Move CMS-related entities into a “cms” package.

Change-Id: Ie350230552fa6f970f26412b40974ca4af7a9260
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/comments/Comment.java b/src/main/java/eu/mulk/mulkcms2/cms/comments/Comment.java
new file mode 100644
index 0000000..4dc8d9d
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/comments/Comment.java
@@ -0,0 +1,32 @@
+package eu.mulk.mulkcms2.cms.comments;
+
+import eu.mulk.mulkcms2.cms.pages.Article;
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.util.Collection;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "comments", schema = "public", catalog = "mulkcms")
+public class Comment extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "global_id", nullable = true, length = -1)
+  public String globalId;
+
+  @OneToMany(mappedBy = "comment", fetch = FetchType.LAZY)
+  public Collection<CommentRevision> revisions;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "article", referencedColumnName = "id", nullable = false)
+  public Article article;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/comments/CommentRevision.java b/src/main/java/eu/mulk/mulkcms2/cms/comments/CommentRevision.java
new file mode 100644
index 0000000..effa45d
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/comments/CommentRevision.java
@@ -0,0 +1,54 @@
+package eu.mulk.mulkcms2.cms.comments;
+
+import com.vladmihalcea.hibernate.type.basic.Inet;
+import com.vladmihalcea.hibernate.type.basic.PostgreSQLInetType;
+import eu.mulk.mulkcms2.cms.users.User;
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.sql.Timestamp;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.hibernate.annotations.TypeDef;
+
+@Entity
+@Table(name = "comment_revisions", schema = "public", catalog = "mulkcms")
+@TypeDef(name = "inet", typeClass = PostgreSQLInetType.class, defaultForType = Inet.class)
+public class CommentRevision extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "date", nullable = true)
+  public Timestamp date;
+
+  @Column(name = "content", nullable = false, length = -1)
+  public String content;
+
+  @Column(name = "format", nullable = false, length = -1)
+  public String format;
+
+  @Column(name = "status", nullable = false, length = -1)
+  public String status;
+
+  @Column(name = "article_revision", nullable = true)
+  public Integer articleRevision;
+
+  @Column(name = "submitter_ip", nullable = true, columnDefinition = "inet")
+  public Inet submitterIp;
+
+  @Column(name = "submitter_user_agent", nullable = true, length = -1)
+  public String submitterUserAgent;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "comment", referencedColumnName = "id", nullable = false)
+  public Comment comment;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "author", referencedColumnName = "id")
+  public User user;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/comments/UsedTransactionKey.java b/src/main/java/eu/mulk/mulkcms2/cms/comments/UsedTransactionKey.java
new file mode 100644
index 0000000..57dd112
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/comments/UsedTransactionKey.java
@@ -0,0 +1,16 @@
+package eu.mulk.mulkcms2.cms.comments;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "used_transaction_keys", schema = "public", catalog = "mulkcms")
+public class UsedTransactionKey extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "key", nullable = false)
+  public long key;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/journal/Journal.java b/src/main/java/eu/mulk/mulkcms2/cms/journal/Journal.java
new file mode 100644
index 0000000..b3d8bf5
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/journal/Journal.java
@@ -0,0 +1,25 @@
+package eu.mulk.mulkcms2.cms.journal;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.util.Collection;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "journals", schema = "public", catalog = "mulkcms")
+public class Journal extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "path_prefix", nullable = true, length = -1)
+  public String pathPrefix;
+
+  @OneToMany(mappedBy = "journal", fetch = FetchType.LAZY)
+  public Collection<JournalEntry> entries;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/journal/JournalEntry.java b/src/main/java/eu/mulk/mulkcms2/cms/journal/JournalEntry.java
new file mode 100644
index 0000000..ed4aeed
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/journal/JournalEntry.java
@@ -0,0 +1,39 @@
+package eu.mulk.mulkcms2.cms.journal;
+
+import eu.mulk.mulkcms2.cms.pages.Article;
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "journal_entries", schema = "public", catalog = "mulkcms")
+@IdClass(JournalEntryPK.class)
+public class JournalEntry extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "journal", nullable = false)
+  public int journalId;
+
+  @Id
+  @Column(name = "index", nullable = false)
+  public int index;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(
+      name = "journal",
+      referencedColumnName = "id",
+      nullable = false,
+      insertable = false,
+      updatable = false)
+  public Journal journal;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "article", referencedColumnName = "id", nullable = false)
+  public Article article;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/journal/JournalEntryPK.java b/src/main/java/eu/mulk/mulkcms2/cms/journal/JournalEntryPK.java
new file mode 100644
index 0000000..88eb083
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/journal/JournalEntryPK.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.journal;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class JournalEntryPK implements Serializable {
+
+  private int journalId;
+  private int index;
+
+  @Column(name = "journal", nullable = false)
+  @Id
+  public int getJournalId() {
+    return journalId;
+  }
+
+  public void setJournalId(int journalId) {
+    this.journalId = journalId;
+  }
+
+  @Column(name = "index", nullable = false)
+  @Id
+  public int getIndex() {
+    return index;
+  }
+
+  public void setIndex(int index) {
+    this.index = index;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    JournalEntryPK that = (JournalEntryPK) o;
+    return journalId == that.journalId && index == that.index;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(journalId, index);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalCategory.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalCategory.java
new file mode 100644
index 0000000..76d7b94
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalCategory.java
@@ -0,0 +1,19 @@
+package eu.mulk.mulkcms2.cms.legacyjournal;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "journal_category", schema = "public", catalog = "mulkcms")
+public class LegacyJournalCategory extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "uuid", nullable = false, length = 36)
+  public String uuid;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalComment.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalComment.java
new file mode 100644
index 0000000..0e28e71
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalComment.java
@@ -0,0 +1,50 @@
+package eu.mulk.mulkcms2.cms.legacyjournal;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "journal_comment", schema = "public", catalog = "mulkcms")
+public class LegacyJournalComment extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "uuid", nullable = false, length = 36)
+  public String uuid;
+
+  @Column(name = "date", nullable = false)
+  public long date;
+
+  @Column(name = "body", nullable = false, length = -1)
+  public String body;
+
+  @Column(name = "author", nullable = true, length = -1)
+  public String author;
+
+  @Column(name = "email", nullable = true, length = -1)
+  public String email;
+
+  @Column(name = "website", nullable = true, length = -1)
+  public String website;
+
+  @Column(name = "spam_p", nullable = true)
+  public Boolean spamP;
+
+  @Column(name = "submitter_ip", nullable = false, length = -1)
+  public String submitterIp;
+
+  @Column(name = "submitter_user_agent", nullable = false, length = -1)
+  public String submitterUserAgent;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "entry_id", referencedColumnName = "id", nullable = false)
+  public LegacyJournalEntry journalEntry;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalEntry.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalEntry.java
new file mode 100644
index 0000000..df2e8cf
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalEntry.java
@@ -0,0 +1,46 @@
+package eu.mulk.mulkcms2.cms.legacyjournal;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.util.Collection;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "journal_entry", schema = "public", catalog = "mulkcms")
+public class LegacyJournalEntry extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "uuid", nullable = false, length = 36)
+  public String uuid;
+
+  @Column(name = "title", nullable = false, length = -1)
+  public String title;
+
+  @Column(name = "date", nullable = false)
+  public long date;
+
+  @Column(name = "last_modification", nullable = true)
+  public Long lastModification;
+
+  @Column(name = "body", nullable = false, length = -1)
+  public String body;
+
+  @Column(name = "type", nullable = false, length = -1)
+  public String type;
+
+  @OneToMany(mappedBy = "journalEntry", fetch = FetchType.LAZY)
+  public Collection<LegacyJournalComment> comments;
+
+  @OneToMany(mappedBy = "journalEntry", fetch = FetchType.LAZY)
+  public Collection<LegacyJournalPingback> pingbacks;
+
+  @OneToMany(mappedBy = "journalEntry", fetch = FetchType.LAZY)
+  public Collection<LegacyJournalTrackback> trackbacks;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalPingback.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalPingback.java
new file mode 100644
index 0000000..5052ee1
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalPingback.java
@@ -0,0 +1,41 @@
+package eu.mulk.mulkcms2.cms.legacyjournal;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "journal_pingback", schema = "public", catalog = "mulkcms")
+public class LegacyJournalPingback extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "uuid", nullable = false, length = 36)
+  public String uuid;
+
+  @Column(name = "date", nullable = false)
+  public long date;
+
+  @Column(name = "url", nullable = true, length = -1)
+  public String url;
+
+  @Column(name = "spam_p", nullable = true)
+  public Boolean spamP;
+
+  @Column(name = "submitter_ip", nullable = false, length = -1)
+  public String submitterIp;
+
+  @Column(name = "submitter_user_agent", nullable = false, length = -1)
+  public String submitterUserAgent;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "entry_id", referencedColumnName = "id", nullable = false)
+  public LegacyJournalEntry journalEntry;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalTrackback.java b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalTrackback.java
new file mode 100644
index 0000000..daf4c2d
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/legacyjournal/LegacyJournalTrackback.java
@@ -0,0 +1,50 @@
+package eu.mulk.mulkcms2.cms.legacyjournal;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "journal_trackback", schema = "public", catalog = "mulkcms")
+public class LegacyJournalTrackback extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "uuid", nullable = false, length = 36)
+  public String uuid;
+
+  @Column(name = "date", nullable = false)
+  public long date;
+
+  @Column(name = "excerpt", nullable = false, length = -1)
+  public String excerpt;
+
+  @Column(name = "title", nullable = true, length = -1)
+  public String title;
+
+  @Column(name = "blog_name", nullable = true, length = -1)
+  public String blogName;
+
+  @Column(name = "url", nullable = true, length = -1)
+  public String url;
+
+  @Column(name = "spam_p", nullable = true)
+  public Boolean spamP;
+
+  @Column(name = "submitter_ip", nullable = false, length = -1)
+  public String submitterIp;
+
+  @Column(name = "submitter_user_agent", nullable = false, length = -1)
+  public String submitterUserAgent;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "entry_id", referencedColumnName = "id", nullable = false)
+  public LegacyJournalEntry journalEntry;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/Article.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/Article.java
new file mode 100644
index 0000000..5110558
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/Article.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import eu.mulk.mulkcms2.cms.comments.Comment;
+import eu.mulk.mulkcms2.cms.journal.JournalEntry;
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.util.Collection;
+import java.util.Set;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "articles", schema = "public", catalog = "mulkcms")
+public class Article extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @OneToMany(mappedBy = "article", fetch = FetchType.LAZY)
+  public Collection<ArticleAlias> aliases;
+
+  @ManyToMany(fetch = FetchType.LAZY)
+  @JoinTable(
+      name = "article_category_memberships",
+      joinColumns = @JoinColumn(name = "article"),
+      inverseJoinColumns = @JoinColumn(name = "category"))
+  public Set<Category> categories;
+
+  @OneToMany(mappedBy = "article", fetch = FetchType.LAZY)
+  public Collection<ArticleRevision> revisions;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "type", referencedColumnName = "id", nullable = false)
+  public ArticleType type;
+
+  @OneToMany(mappedBy = "article", fetch = FetchType.LAZY)
+  public Collection<Comment> comments;
+
+  @OneToMany(mappedBy = "article", fetch = FetchType.LAZY)
+  public Collection<JournalEntry> journalEntries;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleAlias.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleAlias.java
new file mode 100644
index 0000000..de8d443
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleAlias.java
@@ -0,0 +1,23 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "article_aliases", schema = "public", catalog = "mulkcms")
+public class ArticleAlias extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "alias", nullable = false, length = -1)
+  public String alias;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "article", referencedColumnName = "id", nullable = false)
+  public Article article;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTip.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTip.java
new file mode 100644
index 0000000..0417b7d
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTip.java
@@ -0,0 +1,24 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+import org.hibernate.annotations.Immutable;
+
+@Entity
+@Table(name = "article_branch_tips", schema = "public", catalog = "mulkcms")
+@IdClass(ArticleBranchTipPK.class)
+@Immutable
+public class ArticleBranchTip extends PanacheEntityBase {
+
+  @Column(name = "article", nullable = true)
+  @Id
+  private Integer articleId;
+
+  @Column(name = "revision", nullable = true)
+  @Id
+  private Integer revisionId;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTipPK.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTipPK.java
new file mode 100644
index 0000000..2d93b54
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleBranchTipPK.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class ArticleBranchTipPK implements Serializable {
+
+  private int articleId;
+  private int revisionId;
+
+  @Id
+  @Column(name = "article", nullable = false)
+  public int getArticleId() {
+    return articleId;
+  }
+
+  @Id
+  @Column(name = "revision", nullable = false)
+  public int getRevisionId() {
+    return revisionId;
+  }
+
+  public void setArticleId(int articleId) {
+    this.articleId = articleId;
+  }
+
+  public void setRevisionId(int revisionId) {
+    this.revisionId = revisionId;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof ArticleBranchTipPK)) {
+      return false;
+    }
+    ArticleBranchTipPK that = (ArticleBranchTipPK) o;
+    return articleId == that.articleId && revisionId == that.revisionId;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(articleId, revisionId);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleCommentCount.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleCommentCount.java
new file mode 100644
index 0000000..a476188
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleCommentCount.java
@@ -0,0 +1,21 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.hibernate.annotations.Immutable;
+
+@Entity
+@Table(name = "article_comment_counts", schema = "public", catalog = "mulkcms")
+@Immutable
+public class ArticleCommentCount extends PanacheEntityBase {
+
+  @Column(name = "article", nullable = true)
+  @Id
+  public Integer article;
+
+  @Column(name = "comment_count", nullable = true)
+  public Long commentCount;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticlePublishingDate.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticlePublishingDate.java
new file mode 100644
index 0000000..22abf59
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticlePublishingDate.java
@@ -0,0 +1,22 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.sql.Timestamp;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.hibernate.annotations.Immutable;
+
+@Entity
+@Table(name = "article_publishing_dates", schema = "public", catalog = "mulkcms")
+@Immutable
+public class ArticlePublishingDate extends PanacheEntityBase {
+
+  @Column(name = "article", nullable = true)
+  @Id
+  public Integer article;
+
+  @Column(name = "publishing_date", nullable = true)
+  public Timestamp publishingDate;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevision.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevision.java
new file mode 100644
index 0000000..ebb2b9e
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevision.java
@@ -0,0 +1,65 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import eu.mulk.mulkcms2.cms.users.User;
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.Set;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "article_revisions", schema = "public", catalog = "mulkcms")
+public class ArticleRevision extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "date", nullable = true)
+  public Timestamp date;
+
+  @Column(name = "title", nullable = false, length = -1)
+  public String title;
+
+  @Column(name = "content", nullable = false, length = -1)
+  public String content;
+
+  @Column(name = "format", nullable = false, length = -1)
+  public String format;
+
+  @Column(name = "status", nullable = false, length = -1)
+  public String status;
+
+  @Column(name = "global_id", nullable = true, length = -1)
+  public String globalId;
+
+  @OneToMany(mappedBy = "articleRevision", fetch = FetchType.LAZY)
+  public Collection<ArticleRevisionCharacteristic> characteristics;
+
+  @ManyToMany(fetch = FetchType.LAZY)
+  @JoinTable(
+      name = "article_revision_parenthood",
+      joinColumns = @JoinColumn(name = "parent"),
+      inverseJoinColumns = @JoinColumn(name = "child"))
+  public Set<ArticleRevision> children;
+
+  @ManyToMany(mappedBy = "children")
+  public Set<ArticleRevision> parents;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "article", referencedColumnName = "id", nullable = false)
+  public Article article;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "author", referencedColumnName = "id")
+  public User authors;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristic.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristic.java
new file mode 100644
index 0000000..eed2fb6
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristic.java
@@ -0,0 +1,37 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "article_revision_characteristics", schema = "public", catalog = "mulkcms")
+@IdClass(ArticleRevisionCharacteristicPK.class)
+public class ArticleRevisionCharacteristic extends PanacheEntityBase {
+
+  @Column(name = "characteristic", nullable = false, length = -1)
+  @Id
+  public String characteristic;
+
+  @Id
+  @Column(name = "revision", nullable = false)
+  public int articleRevisionId;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(
+      name = "revision",
+      referencedColumnName = "id",
+      nullable = false,
+      insertable = false,
+      updatable = false)
+  public ArticleRevision articleRevision;
+
+  @Column(name = "value", nullable = true, length = -1)
+  public String value;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristicPK.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristicPK.java
new file mode 100644
index 0000000..7f9b61a
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleRevisionCharacteristicPK.java
@@ -0,0 +1,46 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Id;
+
+public class ArticleRevisionCharacteristicPK implements Serializable {
+  private String characteristic;
+  private int articleRevisionId;
+
+  @Id
+  public String getCharacteristic() {
+    return characteristic;
+  }
+
+  public void setCharacteristic(String characteristic) {
+    this.characteristic = characteristic;
+  }
+
+  @Id
+  public int getArticleRevisionId() {
+    return articleRevisionId;
+  }
+
+  public void setArticleRevisionId(int articleRevisionId) {
+    this.articleRevisionId = articleRevisionId;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof ArticleRevisionCharacteristicPK)) {
+      return false;
+    }
+    ArticleRevisionCharacteristicPK that = (ArticleRevisionCharacteristicPK) o;
+    return articleRevisionId == that.articleRevisionId
+        && Objects.equals(characteristic, that.characteristic);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(characteristic, articleRevisionId);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleType.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleType.java
new file mode 100644
index 0000000..7233b92
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/ArticleType.java
@@ -0,0 +1,28 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.util.Collection;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "article_types", schema = "public", catalog = "mulkcms")
+public class ArticleType extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "name", nullable = true, length = -1)
+  public String name;
+
+  @Column(name = "page_template", nullable = true, length = -1)
+  public String pageTemplate;
+
+  @OneToMany(mappedBy = "type", fetch = FetchType.LAZY)
+  public Collection<Article> articles;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/CachedPage.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/CachedPage.java
new file mode 100644
index 0000000..4217053
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/CachedPage.java
@@ -0,0 +1,29 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.sql.Timestamp;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "cached_pages", schema = "public", catalog = "mulkcms")
+@IdClass(CachedPagePK.class)
+public class CachedPage extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "alias", nullable = false, length = -1)
+  public String alias;
+
+  @Id
+  @Column(name = "characteristic_hash", nullable = false)
+  public int characteristicHash;
+
+  @Column(name = "date", nullable = false)
+  public Timestamp date;
+
+  @Column(name = "content", nullable = false, length = -1)
+  public String content;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/CachedPagePK.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/CachedPagePK.java
new file mode 100644
index 0000000..1a72aea
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/CachedPagePK.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class CachedPagePK implements Serializable {
+
+  private String alias;
+  private int characteristicHash;
+
+  @Column(name = "alias", nullable = false, length = -1)
+  @Id
+  public String getAlias() {
+    return alias;
+  }
+
+  public void setAlias(String alias) {
+    this.alias = alias;
+  }
+
+  @Column(name = "characteristic_hash", nullable = false)
+  @Id
+  public int getCharacteristicHash() {
+    return characteristicHash;
+  }
+
+  public void setCharacteristicHash(int characteristicHash) {
+    this.characteristicHash = characteristicHash;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    CachedPagePK that = (CachedPagePK) o;
+    return characteristicHash == that.characteristicHash && Objects.equals(alias, that.alias);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(alias, characteristicHash);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/pages/Category.java b/src/main/java/eu/mulk/mulkcms2/cms/pages/Category.java
new file mode 100644
index 0000000..5171453
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/pages/Category.java
@@ -0,0 +1,37 @@
+package eu.mulk.mulkcms2.cms.pages;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.util.Set;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "categories", schema = "public", catalog = "mulkcms")
+public class Category extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "name", nullable = false, length = -1)
+  public String name;
+
+  @ManyToMany(fetch = FetchType.LAZY)
+  @JoinTable(
+      name = "category_inclusions",
+      joinColumns = @JoinColumn(name = "category"),
+      inverseJoinColumns = @JoinColumn(name = "supercategory"))
+  public Set<Category> supercategories;
+
+  @ManyToMany(mappedBy = "supercategories", fetch = FetchType.LAZY)
+  public Set<Category> subcategories;
+
+  @ManyToMany(fetch = FetchType.LAZY, mappedBy = "categories")
+  public Set<Article> articles;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/LoginCertificate.java b/src/main/java/eu/mulk/mulkcms2/cms/users/LoginCertificate.java
new file mode 100644
index 0000000..4e6f047
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/LoginCertificate.java
@@ -0,0 +1,34 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "login_certificates", schema = "public", catalog = "mulkcms")
+@IdClass(LoginCertificatePK.class)
+public class LoginCertificate extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "user", nullable = false)
+  public int userId;
+
+  @Id
+  @Column(name = "certificate", nullable = false)
+  public byte[] certificate;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(
+      name = "user",
+      referencedColumnName = "id",
+      nullable = false,
+      insertable = false,
+      updatable = false)
+  public User user;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/LoginCertificatePK.java b/src/main/java/eu/mulk/mulkcms2/cms/users/LoginCertificatePK.java
new file mode 100644
index 0000000..8bb5f44
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/LoginCertificatePK.java
@@ -0,0 +1,52 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class LoginCertificatePK implements Serializable {
+
+  private int userId;
+  private byte[] certificate;
+
+  @Column(name = "user", nullable = false)
+  @Id
+  public int getUserId() {
+    return userId;
+  }
+
+  public void setUserId(int userId) {
+    this.userId = userId;
+  }
+
+  @Column(name = "certificate", nullable = false)
+  @Id
+  public byte[] getCertificate() {
+    return certificate;
+  }
+
+  public void setCertificate(byte[] certificate) {
+    this.certificate = certificate;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    LoginCertificatePK that = (LoginCertificatePK) o;
+    return userId == that.userId && Arrays.equals(certificate, that.certificate);
+  }
+
+  @Override
+  public int hashCode() {
+    int result = Objects.hash(userId);
+    result = 31 * result + Arrays.hashCode(certificate);
+    return result;
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/OpenId.java b/src/main/java/eu/mulk/mulkcms2/cms/users/OpenId.java
new file mode 100644
index 0000000..0cc7407
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/OpenId.java
@@ -0,0 +1,34 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "openids", schema = "public", catalog = "mulkcms")
+@IdClass(OpenIdPK.class)
+public class OpenId extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "user", nullable = false)
+  public int userId;
+
+  @Id
+  @Column(name = "openid", nullable = false, length = -1)
+  public String openid;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(
+      name = "user",
+      referencedColumnName = "id",
+      nullable = false,
+      insertable = false,
+      updatable = false)
+  public User user;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/OpenIdPK.java b/src/main/java/eu/mulk/mulkcms2/cms/users/OpenIdPK.java
new file mode 100644
index 0000000..e80fb25
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/OpenIdPK.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class OpenIdPK implements Serializable {
+
+  private int userId;
+  private String openid;
+
+  @Column(name = "user", nullable = false)
+  @Id
+  public int getUserId() {
+    return userId;
+  }
+
+  public void setUserId(int userId) {
+    this.userId = userId;
+  }
+
+  @Column(name = "openid", nullable = false, length = -1)
+  @Id
+  public String getOpenid() {
+    return openid;
+  }
+
+  public void setOpenid(String openid) {
+    this.openid = openid;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    OpenIdPK openIdPK = (OpenIdPK) o;
+    return userId == openIdPK.userId && Objects.equals(openid, openIdPK.openid);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(userId, openid);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/Password.java b/src/main/java/eu/mulk/mulkcms2/cms/users/Password.java
new file mode 100644
index 0000000..632284e
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/Password.java
@@ -0,0 +1,34 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "passwords", schema = "public", catalog = "mulkcms")
+@IdClass(PasswordPK.class)
+public class Password extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "user", nullable = false)
+  public int userId;
+
+  @Id
+  @Column(name = "password", nullable = false, length = -1)
+  public String password;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(
+      name = "user",
+      referencedColumnName = "id",
+      nullable = false,
+      insertable = false,
+      updatable = false)
+  public User user;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/PasswordPK.java b/src/main/java/eu/mulk/mulkcms2/cms/users/PasswordPK.java
new file mode 100644
index 0000000..c43cd5e
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/PasswordPK.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class PasswordPK implements Serializable {
+
+  private int userId;
+  private String password;
+
+  @Column(name = "user", nullable = false)
+  @Id
+  public int getUserId() {
+    return userId;
+  }
+
+  public void setUserId(int userId) {
+    this.userId = userId;
+  }
+
+  @Column(name = "password", nullable = false, length = -1)
+  @Id
+  public String getPassword() {
+    return password;
+  }
+
+  public void setPassword(String password) {
+    this.password = password;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    PasswordPK that = (PasswordPK) o;
+    return userId == that.userId && Objects.equals(password, that.password);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(userId, password);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/User.java b/src/main/java/eu/mulk/mulkcms2/cms/users/User.java
new file mode 100644
index 0000000..a84462f
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/User.java
@@ -0,0 +1,54 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import eu.mulk.mulkcms2.cms.comments.CommentRevision;
+import eu.mulk.mulkcms2.cms.pages.ArticleRevision;
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import java.util.Collection;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "users", schema = "public", catalog = "mulkcms")
+public class User extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "id", nullable = false)
+  public int id;
+
+  @Column(name = "name", nullable = true, length = -1)
+  public String name;
+
+  @Column(name = "status", nullable = false, length = -1)
+  public String status;
+
+  @Column(name = "email", nullable = true, length = -1)
+  public String email;
+
+  @Column(name = "website", nullable = true, length = -1)
+  public String website;
+
+  @OneToMany(mappedBy = "authors", fetch = FetchType.LAZY)
+  public Collection<ArticleRevision> articleRevisions;
+
+  @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
+  public Collection<CommentRevision> commentRevisions;
+
+  @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
+  public Collection<LoginCertificate> loginCertificates;
+
+  @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
+  public Collection<OpenId> openids;
+
+  @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
+  public Collection<Password> passwords;
+
+  @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
+  public Collection<UserPermission> userPermissions;
+
+  @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
+  public Collection<UserSetting> userSettings;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermission.java b/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermission.java
new file mode 100644
index 0000000..a580813
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermission.java
@@ -0,0 +1,37 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "user_permissions", schema = "public", catalog = "mulkcms")
+@IdClass(UserPermissionPK.class)
+public class UserPermission extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "user", nullable = false)
+  public int userId;
+
+  @Id
+  @Column(name = "permission", nullable = false, length = -1)
+  public String permission;
+
+  @Column(name = "status", nullable = true)
+  public Boolean status;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(
+      name = "user",
+      referencedColumnName = "id",
+      nullable = false,
+      insertable = false,
+      updatable = false)
+  public User user;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermissionPK.java b/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermissionPK.java
new file mode 100644
index 0000000..406178e
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/UserPermissionPK.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class UserPermissionPK implements Serializable {
+
+  private int userId;
+  private String permission;
+
+  @Column(name = "user", nullable = false)
+  @Id
+  public int getUserId() {
+    return userId;
+  }
+
+  public void setUserId(int userId) {
+    this.userId = userId;
+  }
+
+  @Column(name = "permission", nullable = false, length = -1)
+  @Id
+  public String getPermission() {
+    return permission;
+  }
+
+  public void setPermission(String permission) {
+    this.permission = permission;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    UserPermissionPK that = (UserPermissionPK) o;
+    return userId == that.userId && Objects.equals(permission, that.permission);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(userId, permission);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/UserSetting.java b/src/main/java/eu/mulk/mulkcms2/cms/users/UserSetting.java
new file mode 100644
index 0000000..f4ec234
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/UserSetting.java
@@ -0,0 +1,37 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "user_settings", schema = "public", catalog = "mulkcms")
+@IdClass(UserSettingPK.class)
+public class UserSetting extends PanacheEntityBase {
+
+  @Id
+  @Column(name = "user", nullable = false)
+  public int userId;
+
+  @Id
+  @Column(name = "setting", nullable = false, length = -1)
+  public String setting;
+
+  @Column(name = "value", nullable = true, length = -1)
+  public String value;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(
+      name = "user",
+      referencedColumnName = "id",
+      nullable = false,
+      insertable = false,
+      updatable = false)
+  public User user;
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/users/UserSettingPK.java b/src/main/java/eu/mulk/mulkcms2/cms/users/UserSettingPK.java
new file mode 100644
index 0000000..b7c28ea
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/users/UserSettingPK.java
@@ -0,0 +1,49 @@
+package eu.mulk.mulkcms2.cms.users;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+public class UserSettingPK implements Serializable {
+
+  private int userId;
+  private String setting;
+
+  @Column(name = "user", nullable = false)
+  @Id
+  public int getUserId() {
+    return userId;
+  }
+
+  public void setUserId(int userId) {
+    this.userId = userId;
+  }
+
+  @Column(name = "setting", nullable = false, length = -1)
+  @Id
+  public String getSetting() {
+    return setting;
+  }
+
+  public void setSetting(String setting) {
+    this.setting = setting;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    UserSettingPK that = (UserSettingPK) o;
+    return userId == that.userId && Objects.equals(setting, that.setting);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(userId, setting);
+  }
+}
diff --git a/src/main/java/eu/mulk/mulkcms2/cms/web/ExampleResource.java b/src/main/java/eu/mulk/mulkcms2/cms/web/ExampleResource.java
new file mode 100644
index 0000000..fc504c8
--- /dev/null
+++ b/src/main/java/eu/mulk/mulkcms2/cms/web/ExampleResource.java
@@ -0,0 +1,14 @@
+package eu.mulk.mulkcms2.cms.web;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+public class ExampleResource {
+
+  @GET
+  @Produces({MediaType.TEXT_PLAIN})
+  public String hello() {
+    return "hello!";
+  }
+}