diff --git a/Gemfile.lock b/Gemfile.lock
index 7bc762f5d2d38bf20f70172f112b20353a54a7f3..c3bd4d1f7a42ce219d896052fbaac53ae33ffc30 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -9,9 +9,9 @@ GIT
 
 GIT
   remote: https://github.com/noesya/two_factor_authentication.git
-  revision: 4574ece65da41397dd852001e22a0c3b9ee3d01e
+  revision: 852a0ea0b1c755fdf52a423aea0538e7013773b1
   specs:
-    two_factor_authentication (4.0.0)
+    two_factor_authentication (4.1.0)
       devise
       encryptor
       rails (>= 3.1.1)
@@ -103,7 +103,7 @@ GEM
     autoprefixer-rails (10.4.7.0)
       execjs (~> 2)
     aws-eventstream (1.2.0)
-    aws-partitions (1.688.0)
+    aws-partitions (1.689.0)
     aws-sdk-core (3.168.4)
       aws-eventstream (~> 1, >= 1.0.2)
       aws-partitions (~> 1, >= 1.651.0)
@@ -187,7 +187,7 @@ GEM
     ethon (0.16.0)
       ffi (>= 1.15.0)
     execjs (2.8.1)
-    faceted_search (3.5.16)
+    faceted_search (3.6.0)
       font-awesome-sass
       rails (>= 5.2.0)
     faraday (2.7.2)
@@ -456,7 +456,7 @@ GEM
     snaky_hash (2.0.1)
       hashie
       version_gem (~> 1.1, >= 1.1.1)
-    spring (4.1.0)
+    spring (4.1.1)
     sprockets (4.2.0)
       concurrent-ruby (~> 1.0)
       rack (>= 2.2.4, < 4)
diff --git a/app/controllers/admin/research/journals/papers/kinds_controller.rb b/app/controllers/admin/research/journals/papers/kinds_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3740b69ca5566a790dc829bc0c18d6c4375e081c
--- /dev/null
+++ b/app/controllers/admin/research/journals/papers/kinds_controller.rb
@@ -0,0 +1,75 @@
+class Admin::Research::Journals::Papers::KindsController < Admin::Research::Journals::ApplicationController
+  load_and_authorize_resource class: Research::Journal::Paper::Kind, through: :journal
+
+  def index
+    breadcrumb
+  end
+  
+  def show
+    @papers = @kind.papers.page params[:page]
+    breadcrumb
+    add_breadcrumb @kind
+  end
+
+  def static
+    @about = @kind
+    @website = @journal.websites.first
+    if @website.nil?
+      render plain: "Pas de site Web lié au journal"
+    else
+      render layout: false
+    end
+  end
+
+  def new
+    breadcrumb
+    add_breadcrumb t('create')
+  end
+  
+  def edit
+    breadcrumb
+    add_breadcrumb @kind, admin_research_journal_kind_path(@kind)
+    add_breadcrumb t('edit')
+  end
+
+  def create
+    @kind.assign_attributes(
+      journal: @journal,
+      university: current_university
+    )
+    if @kind.save_and_sync
+      redirect_to admin_research_journal_kind_path(@kind), notice: t('admin.successfully_created_html', model: @paper_kind.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('create')
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @kind.update_and_sync(kind_params)
+      redirect_to admin_research_journal_kind_path(@kind), notice: t('admin.successfully_updated_html', model: @paper_kind.to_s)
+    else
+      breadcrumb
+      add_breadcrumb @kind, admin_research_journal_kind_path(@kind)
+      add_breadcrumb t('edit')
+      render :edit, status: :unprocessable_entity
+    end
+  end
+
+  def destroy
+    @kind.destroy_and_sync
+    redirect_to admin_research_journal_path(@journal), notice: t('admin.successfully_destroyed_html', model: @paper_kind.to_s)
+  end
+
+  private
+
+  def breadcrumb
+    super
+    add_breadcrumb Research::Journal::Paper::Kind.model_name.human(count: 2), admin_research_journal_kinds_path
+  end
+
+  def kind_params
+    params.require(:research_journal_paper_kind).permit(:title, :slug)
+  end
+end
diff --git a/app/controllers/admin/research/journals/papers_controller.rb b/app/controllers/admin/research/journals/papers_controller.rb
index fc8dc28e94debde1f36dc3691c1093a9c61b7b43..10c257c714da884213aab71bb64984b8faef87c7 100644
--- a/app/controllers/admin/research/journals/papers_controller.rb
+++ b/app/controllers/admin/research/journals/papers_controller.rb
@@ -11,6 +11,16 @@ class Admin::Research::Journals::PapersController < Admin::Research::Journals::A
     breadcrumb
   end
 
+  def static
+    @about = @paper
+    @website = @journal.websites.first
+    if @website.nil?
+      render plain: "Pas de site Web lié au journal"
+    else
+      render layout: false
+    end
+  end
+
   def new
     breadcrumb
   end
@@ -42,7 +52,7 @@ class Admin::Research::Journals::PapersController < Admin::Research::Journals::A
       breadcrumb
       add_breadcrumb t('edit')
       render :edit, status: :unprocessable_entity
-  end
+    end
   end
 
   def destroy
@@ -60,7 +70,9 @@ class Admin::Research::Journals::PapersController < Admin::Research::Journals::A
 
   def paper_params
     params.require(:research_journal_paper)
-          .permit(:title, :slug, :text, :published, :published_at, :summary, :abstract, :meta_description, :pdf, :references, :keywords, :research_journal_volume_id, person_ids: [])
+          .permit(
+            :title, :slug, :text, :published, :published_at, :summary, :abstract, :meta_description, 
+            :pdf, :references, :keywords, :research_journal_volume_id, :kind_id, person_ids: [])
           .merge(university_id: current_university.id)
   end
 end
diff --git a/app/controllers/admin/research/journals/volumes_controller.rb b/app/controllers/admin/research/journals/volumes_controller.rb
index f8395fa9e4b26030e03aada3affe0c50cb8f0b69..34af4361e191c471b94552603c35d26f1ff2022e 100644
--- a/app/controllers/admin/research/journals/volumes_controller.rb
+++ b/app/controllers/admin/research/journals/volumes_controller.rb
@@ -11,6 +11,16 @@ class Admin::Research::Journals::VolumesController < Admin::Research::Journals::
     breadcrumb
   end
 
+  def static
+    @about = @volume
+    @website = @journal.websites.first
+    if @website.nil?
+      render plain: "Pas de site Web lié au journal"
+    else
+      render layout: false
+    end
+  end
+
   def new
     breadcrumb
   end
diff --git a/app/controllers/admin/research/journals_controller.rb b/app/controllers/admin/research/journals_controller.rb
index 6ccc4ead71e421ea263a734aa51386caeadff3fd..1dd99dea3435a14964106026aff16fa4e0359f16 100644
--- a/app/controllers/admin/research/journals_controller.rb
+++ b/app/controllers/admin/research/journals_controller.rb
@@ -13,6 +13,7 @@ class Admin::Research::JournalsController < Admin::Research::ApplicationControll
 
   def show
     @papers = @journal.papers.ordered.limit(10)
+    @kinds = @journal.kinds.ordered
     breadcrumb
   end
 
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 1823110847763618c8c981661ee11182a5c73fa1..78c91ac1be684c53d5a3dbf26a38b60044cfdb61 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -92,6 +92,7 @@ class Ability
     can :manage, :all_programs # needed to prevent program_manager to access specific global screens
     can :manage, Research::Journal, university_id: @user.university_id
     can :manage, Research::Journal::Paper, university_id: @user.university_id
+    can :manage, Research::Journal::Paper::Kind, university_id: @user.university_id
     can :manage, Research::Journal::Volume, university_id: @user.university_id
     can :manage, Research::Laboratory, university_id: @user.university_id
     can :manage, Research::Laboratory::Axis, university_id: @user.university_id
diff --git a/app/models/communication/website/page/sitemap.rb b/app/models/communication/website/page/sitemap.rb
index a8a3d366a791d3c7bed8dcba5d62833836ea9694..f5243a667939e1518d543a735691096370064fe1 100644
--- a/app/models/communication/website/page/sitemap.rb
+++ b/app/models/communication/website/page/sitemap.rb
@@ -51,6 +51,14 @@ class Communication::Website::Page::Sitemap < Communication::Website::Page
   def draftable?
     false
   end
+
+  def full_width
+    false
+  end
+
+  def show_toc?
+    true
+  end
   
   def static_layout
     'sitemap'
diff --git a/app/models/communication/website/permalink.rb b/app/models/communication/website/permalink.rb
index 993dc56ff39d14f614b7c384dee1184845c81dc2..276d8df83af5f599212cc2f6cc269c287ae73505 100644
--- a/app/models/communication/website/permalink.rb
+++ b/app/models/communication/website/permalink.rb
@@ -30,6 +30,8 @@ class Communication::Website::Permalink < ApplicationRecord
     "Communication::Website::Post" => Communication::Website::Permalink::Post,
     "Education::Diploma" => Communication::Website::Permalink::Diploma,
     "Education::Program" => Communication::Website::Permalink::Program,
+    "Research::Journal::Paper" => Communication::Website::Permalink::Paper,
+    "Research::Journal::Volume" => Communication::Website::Permalink::Volume,
     "University::Organization" => Communication::Website::Permalink::Organization,
     "University::Person" => Communication::Website::Permalink::Person,
     "University::Person::Administrator" => Communication::Website::Permalink::Administrator,
diff --git a/app/models/communication/website/permalink/paper.rb b/app/models/communication/website/permalink/paper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..430fee83b4743d2f765a2391b1576e27da5fd88a
--- /dev/null
+++ b/app/models/communication/website/permalink/paper.rb
@@ -0,0 +1,50 @@
+# == Schema Information
+#
+# Table name: communication_website_permalinks
+#
+#  id            :uuid             not null, primary key
+#  about_type    :string           not null, indexed => [about_id]
+#  is_current    :boolean          default(TRUE)
+#  path          :string
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  about_id      :uuid             not null, indexed => [about_type]
+#  university_id :uuid             not null, indexed
+#  website_id    :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_communication_website_permalinks_on_about          (about_type,about_id)
+#  index_communication_website_permalinks_on_university_id  (university_id)
+#  index_communication_website_permalinks_on_website_id     (website_id)
+#
+# Foreign Keys
+#
+#  fk_rails_e9646cce64  (university_id => universities.id)
+#  fk_rails_f389ba7d45  (website_id => communication_websites.id)
+#
+class Communication::Website::Permalink::Paper < Communication::Website::Permalink
+  def self.required_in_config?(website)
+    website.about.is_a? Research::Journal
+  end
+
+  def self.static_config_key
+    :papers
+  end
+
+  # /papiers/:slug/
+  def self.pattern_in_website(website)
+    "/#{website.special_page(Communication::Website::Page::ResearchPaper).slug_with_ancestors}/:year-:month-:day-:slug/"
+  end
+
+  protected
+
+  def substitutions
+    {
+      year: about.published_at.strftime("%Y"),
+      month: about.published_at.strftime("%m"),
+      day: about.published_at.strftime("%d"),
+      slug: about.slug
+    }
+  end
+end
diff --git a/app/models/communication/website/permalink/volume.rb b/app/models/communication/website/permalink/volume.rb
new file mode 100644
index 0000000000000000000000000000000000000000..96774e65de72512b292fee2ca322f3c8ae6790f6
--- /dev/null
+++ b/app/models/communication/website/permalink/volume.rb
@@ -0,0 +1,48 @@
+# == Schema Information
+#
+# Table name: communication_website_permalinks
+#
+#  id            :uuid             not null, primary key
+#  about_type    :string           not null, indexed => [about_id]
+#  is_current    :boolean          default(TRUE)
+#  path          :string
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  about_id      :uuid             not null, indexed => [about_type]
+#  university_id :uuid             not null, indexed
+#  website_id    :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_communication_website_permalinks_on_about          (about_type,about_id)
+#  index_communication_website_permalinks_on_university_id  (university_id)
+#  index_communication_website_permalinks_on_website_id     (website_id)
+#
+# Foreign Keys
+#
+#  fk_rails_e9646cce64  (university_id => universities.id)
+#  fk_rails_f389ba7d45  (website_id => communication_websites.id)
+#
+class Communication::Website::Permalink::Volume < Communication::Website::Permalink
+  def self.required_in_config?(website)
+    website.about.is_a? Research::Journal
+  end
+
+  def self.static_config_key
+    :volumes
+  end
+
+  # /volumes/:slug/
+  def self.pattern_in_website(website)
+    "/#{website.special_page(Communication::Website::Page::ResearchVolume).slug_with_ancestors}/:year-:slug/"
+  end
+
+  protected
+
+  def substitutions
+    {
+      year: about.published_at.strftime("%Y"),
+      slug: about.slug
+    }
+  end
+end
diff --git a/app/models/research/journal.rb b/app/models/research/journal.rb
index 2cf68b7922040236d1c417deb01a3ed36976d67d..21149af299ea637529ad441c4c9af6eb6960c15a 100644
--- a/app/models/research/journal.rb
+++ b/app/models/research/journal.rb
@@ -31,6 +31,7 @@ class Research::Journal < ApplicationRecord
   has_many :published_papers, -> { published }, class_name: 'Research::Journal::Paper', foreign_key: :research_journal_id, dependent: :destroy
   has_many :people, -> { distinct }, through: :papers
   has_many :people_through_published_papers, -> { distinct }, through: :published_papers, source: :people
+  has_many :kinds, class_name: 'Research::Journal::Paper::Kind'
 
   scope :ordered, -> { order(:title) }
   scope :for_search_term, -> (term) {
diff --git a/app/models/research/journal/paper.rb b/app/models/research/journal/paper.rb
index baf4e402acbc66eba5f5233a53e234fc1aac8b05..1b0e1502fe7eaa5055af5dae71727c212363ba48 100644
--- a/app/models/research/journal/paper.rb
+++ b/app/models/research/journal/paper.rb
@@ -16,6 +16,7 @@
 #  title                      :string
 #  created_at                 :datetime         not null
 #  updated_at                 :datetime         not null
+#  kind_id                    :uuid             indexed
 #  research_journal_id        :uuid             not null, indexed
 #  research_journal_volume_id :uuid             indexed
 #  university_id              :uuid             not null, indexed
@@ -23,6 +24,7 @@
 #
 # Indexes
 #
+#  index_research_journal_papers_on_kind_id                     (kind_id)
 #  index_research_journal_papers_on_research_journal_id         (research_journal_id)
 #  index_research_journal_papers_on_research_journal_volume_id  (research_journal_volume_id)
 #  index_research_journal_papers_on_university_id               (university_id)
@@ -34,12 +36,14 @@
 #  fk_rails_22f161a6a7  (research_journal_volume_id => research_journal_volumes.id)
 #  fk_rails_2713063b85  (updated_by_id => users.id)
 #  fk_rails_935541e014  (university_id => universities.id)
+#  fk_rails_db4e38788c  (kind_id => research_journal_paper_kinds.id)
 #
 class Research::Journal::Paper < ApplicationRecord
   include Sanitizable
   include WithUniversity
   include WithGit
   include WithBlobs
+  include WithPermalink
   include WithPosition
   include WithSlug
 
@@ -48,6 +52,7 @@ class Research::Journal::Paper < ApplicationRecord
 
   belongs_to :journal, foreign_key: :research_journal_id
   belongs_to :volume, foreign_key: :research_journal_volume_id, optional: true
+  belongs_to :kind, class_name: 'Research::Journal::Paper::Kind', optional: true
   belongs_to :updated_by, class_name: 'User'
   has_and_belongs_to_many :people,
                           class_name: 'University::Person',
@@ -62,8 +67,20 @@ class Research::Journal::Paper < ApplicationRecord
   scope :published, -> { where(published: true) }
   scope :ordered, -> { order(published_at: :desc, created_at: :desc) }
 
+  def published?
+    published && published_at && published_at.to_date <= Date.today
+  end
+
+  def for_website?(website)
+    journal == website.about
+  end
+
   def git_path(website)
-    "#{git_path_content_prefix(website)}papers/#{published_at.year}/#{published_at.strftime "%Y-%m-%d"}-#{slug}.html" if (volume.nil? || volume.published_at) && published_at
+    "#{git_path_content_prefix(website)}papers/#{static_path}.html" if published?
+  end
+
+  def static_path
+    "#{published_at.year}/#{published_at.strftime "%Y-%m-%d"}-#{slug}"
   end
 
   def template_static
@@ -84,10 +101,6 @@ class Research::Journal::Paper < ApplicationRecord
     "#{ title }"
   end
 
-  def path
-    "/#{slug}"
-  end
-
   protected
 
   def other_papers_in_the_volume
diff --git a/app/models/research/journal/paper/kind.rb b/app/models/research/journal/paper/kind.rb
new file mode 100644
index 0000000000000000000000000000000000000000..da961c04fcc36061726831a3d8b4d67e2e6324d2
--- /dev/null
+++ b/app/models/research/journal/paper/kind.rb
@@ -0,0 +1,36 @@
+# == Schema Information
+#
+# Table name: research_journal_paper_kinds
+#
+#  id            :uuid             not null, primary key
+#  slug          :string
+#  title         :string
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  journal_id    :uuid             not null, indexed
+#  university_id :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_research_journal_paper_kinds_on_journal_id     (journal_id)
+#  index_research_journal_paper_kinds_on_university_id  (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_57217513c3  (journal_id => research_journals.id)
+#  fk_rails_8e6f992b9d  (university_id => universities.id)
+#
+class Research::Journal::Paper::Kind < ApplicationRecord
+  include WithUniversity
+  include WithGit
+  include WithSlug
+
+  belongs_to :journal, class_name: 'Research::Journal'
+  has_many :papers
+
+  scope :ordered, -> { order(:title) }
+
+  def to_s
+    "#{title}"
+  end
+end
diff --git a/app/models/research/journal/volume.rb b/app/models/research/journal/volume.rb
index 7954879f64c50607d1a5c0b6ccf18ae3eb2599e0..ea545dcd8db282f43e66bfdc90345fd6eded2fd9 100644
--- a/app/models/research/journal/volume.rb
+++ b/app/models/research/journal/volume.rb
@@ -35,6 +35,7 @@ class Research::Journal::Volume < ApplicationRecord
   include WithGit
   include WithBlobs
   include WithFeaturedImage
+  include WithPermalink
   include WithSlug
 
   has_summernote :text
@@ -49,12 +50,16 @@ class Research::Journal::Volume < ApplicationRecord
   scope :published, -> { where(published: true) }
   scope :ordered, -> { order(number: :desc, published_at: :desc) }
 
-  def website
-    journal.website
+  def published?
+    published && published_at && published_at.to_date <= Date.today
+  end
+
+  def for_website?(website)
+    journal == website.about
   end
 
   def git_path(website)
-    "#{git_path_content_prefix(website)}volumes/#{published_at.year}/#{slug}/_index.html" if published_at
+    "#{git_path_content_prefix(website)}volumes#{path}/_index.html" if published_at
   end
 
   def template_static
@@ -77,7 +82,7 @@ class Research::Journal::Volume < ApplicationRecord
   end
 
   def path
-    "/#{published_at&.year}/#{slug}" if published_at
+    "/#{published_at&.year}-#{slug}" if published_at
   end
 
   def to_s
diff --git a/app/models/university/person/administrator.rb b/app/models/university/person/administrator.rb
index f571677467809e27395c27b3a05118582292eea8..0dc611b6739e2482d57981b1c97ae7bfa2b9d8af 100644
--- a/app/models/university/person/administrator.rb
+++ b/app/models/university/person/administrator.rb
@@ -1,4 +1,52 @@
-  # == Schema Information
+# == Schema Information
+#
+# Table name: university_people
+#
+#  id                    :uuid             not null, primary key
+#  address               :string
+#  biography             :text
+#  birthdate             :date
+#  city                  :string
+#  country               :string
+#  email                 :string
+#  first_name            :string
+#  gender                :integer
+#  habilitation          :boolean          default(FALSE)
+#  is_administration     :boolean
+#  is_alumnus            :boolean          default(FALSE)
+#  is_author             :boolean
+#  is_researcher         :boolean
+#  is_teacher            :boolean
+#  last_name             :string
+#  linkedin              :string
+#  mastodon              :string
+#  meta_description      :text
+#  name                  :string
+#  phone_mobile          :string
+#  phone_personal        :string
+#  phone_professional    :string
+#  slug                  :string
+#  summary               :text
+#  tenure                :boolean          default(FALSE)
+#  twitter               :string
+#  url                   :string
+#  zipcode               :string
+#  created_at            :datetime         not null
+#  updated_at            :datetime         not null
+#  university_id         :uuid             not null, indexed
+#  user_id               :uuid             indexed
+#
+# Indexes
+#
+#  index_university_people_on_university_id  (university_id)
+#  index_university_people_on_user_id        (user_id)
+#
+# Foreign Keys
+#
+#  fk_rails_b47a769440  (user_id => users.id)
+#  fk_rails_da35e70d61  (university_id => universities.id)
+#
+# == Schema Information
 #
 # Table name: university_people
 #
diff --git a/app/models/university/with_identifier.rb b/app/models/university/with_identifier.rb
index 1e7815b69b4d3f25356d8101dfb5ed53141a0515..32133d44f8743770c75eaf4e8521e068606ef87a 100644
--- a/app/models/university/with_identifier.rb
+++ b/app/models/university/with_identifier.rb
@@ -35,6 +35,10 @@ module University::WithIdentifier
       ENV['OSUNY_STAGING'] || '.osuny.dev'
     end
 
+    def self.test_domain
+      ENV['OSUNY_TEST'] || '.osuny.test'
+    end
+
     def self.development_domain
       ENV['OSUNY_DEV'] || '.osuny'
     end
diff --git a/app/views/admin/research/journals/papers/_form.html.erb b/app/views/admin/research/journals/papers/_form.html.erb
index e733d046260ff095c6d6c84b583ea7bbfd570496..d476a711028f2d8b38c644e0581687dfa8c524d6 100644
--- a/app/views/admin/research/journals/papers/_form.html.erb
+++ b/app/views/admin/research/journals/papers/_form.html.erb
@@ -13,8 +13,16 @@
           <%= render 'admin/application/summary/form', f: f, about: paper %>
           <%= f.input :abstract, as: :text, input_html: { rows: 8 } %>
           <%= f.input :pdf %>
-          <%= f.input :text, as: :summernote %>
-          <%= f.input :references, as: :text, input_html: { rows: 10 } %>
+          <%= f.input :text, 
+                      as: :summernote,
+                      input_html: {
+                        data: { 'summernote-config' => 'mini' }
+                      } %>
+          <%= f.input :references, 
+                      as: :summernote,
+                      input_html: {
+                        data: { 'summernote-config' => 'mini' }
+                      } %>
         </div>
       </div>
     </div>
@@ -35,6 +43,7 @@
           <%= f.input :published_at, html5: true %>
           <%= f.input :keywords, as: :text, input_html: { rows: 2 } %>
           <%= f.association :people, collection: current_university.people.researchers.ordered, as: :check_boxes %>
+          <%= f.association :kind, collection: @journal.kinds.ordered if @journal.kinds.any? %>
         </div>
       </div>
       <%= render 'admin/application/meta_description/form', f: f, about: paper %>
diff --git a/app/views/admin/research/journals/papers/_list.html.erb b/app/views/admin/research/journals/papers/_list.html.erb
index 92e82aa45cec31a969562e9b313a131a46019e02..aae767ac2b8b319769010821e6873a2f74786c99 100644
--- a/app/views/admin/research/journals/papers/_list.html.erb
+++ b/app/views/admin/research/journals/papers/_list.html.erb
@@ -2,7 +2,8 @@
   <table class="<%= table_classes %>">
     <thead>
       <tr>
-        <th><%= Research::Journal::Paper.model_name.human %></th>
+        <th><%= Research::Journal::Paper.human_attribute_name('title') %></th>
+        <th><%= Research::Journal::Paper.human_attribute_name('volume') %></th>
         <th><%= Research::Journal::Paper.human_attribute_name('published_at') %></th>
         <th></th>
       </tr>
@@ -15,6 +16,7 @@
                         admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
                         class: "#{'draft' unless paper.published?}" %>
           </td>
+          <td><%= link_to paper.volume, admin_research_journal_volume_path(paper.volume) if paper.volume %></td>
           <td><%= l(paper.published_at.to_time, format: :date_with_explicit_month) if paper.published_at.present? %></td>
           <td class="text-end">
             <div class="btn-group" role="group">
diff --git a/app/views/admin/research/journals/papers/kinds/_form.html.erb b/app/views/admin/research/journals/papers/kinds/_form.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..853d1f38afa3b8fe779dbf9e9dafa55c65004936
--- /dev/null
+++ b/app/views/admin/research/journals/papers/kinds/_form.html.erb
@@ -0,0 +1,38 @@
+<%
+url = kind.new_record?  ? admin_research_journal_kinds_path
+                        : admin_research_journal_kind_path(kind)
+%>
+<%= simple_form_for kind, url: url do |f| %>
+  <%= f.error_notification %>
+  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+  <div class="row">
+    <div class="col-md-8">
+      <div class="card flex-fill w-100">
+        <div class="card-header">
+          <h5 class="card-title mb-0"><%= t('content') %></h5>
+        </div>
+        <div class="card-body">
+          <%= f.input :title %>
+        </div>
+      </div>
+    </div>
+    <div class="col-md-4">
+      <div class="card flex-fill w-100">
+        <div class="card-header">
+          <h5 class="card-title mb-0"><%= t('metadata') %></h5>
+        </div>
+        <div class="card-body">
+          <%= f.input :slug,
+                      as: :string,
+                      input_html: kind.persisted? ? {} : {
+                        class: 'js-slug-input',
+                        data: { source: '#research_journal_paper_kind_title' }
+                      } %>
+        </div>
+      </div>
+    </div>
+  </div>
+  <% content_for :action_bar_right do %>
+    <%= submit f %>
+  <% end %>
+<% end %>
diff --git a/app/views/admin/research/journals/papers/kinds/_list.html.erb b/app/views/admin/research/journals/papers/kinds/_list.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..df45956d7bb811bdb61ff7064da9ae014afbbadc
--- /dev/null
+++ b/app/views/admin/research/journals/papers/kinds/_list.html.erb
@@ -0,0 +1,34 @@
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
+      <tr>
+        <th><%= Research::Journal::Paper::Kind.human_attribute_name('title') %></th>
+        <th><%= Research::Journal::Paper.model_name.human(count: 2) %></th>
+        <th></th>
+      </tr>
+    </thead>
+    <tbody>
+      <% kinds.each do |kind| %>
+        <tr>
+          <td>
+            <%= link_to kind,
+                        admin_research_journal_kind_path(journal_id: kind.journal, id: kind) %>
+          </td>
+          <td><%= kind.papers.count %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_research_journal_kind_path(journal_id: kind.journal, id: kind),
+                          class: button_classes %>
+              <%= link_to t('delete'),
+                          admin_research_journal_kind_path(journal_id: kind.journal, id: kind),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/research/journals/papers/kinds/edit.html.erb b/app/views/admin/research/journals/papers/kinds/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..23e01d488bce530df4610865b6df39909a126891
--- /dev/null
+++ b/app/views/admin/research/journals/papers/kinds/edit.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @kind %>
+
+<%= render 'form', kind: @kind %>
diff --git a/app/views/admin/research/journals/papers/kinds/index.html.erb b/app/views/admin/research/journals/papers/kinds/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..81ac607bbd41bec6874545502e3632dd592109b0
--- /dev/null
+++ b/app/views/admin/research/journals/papers/kinds/index.html.erb
@@ -0,0 +1,7 @@
+<% content_for :title, Research::Journal::Paper::Kind.model_name.human(count: 2) %>
+
+<%= render 'admin/research/journals/papers/kinds/list', kinds: @kinds %>
+
+<% content_for :action_bar_right do %>
+  <%= link_to t('create'), new_admin_research_journal_kind_path, class: button_classes %>
+<% end %>
diff --git a/app/views/admin/research/journals/papers/kinds/new.html.erb b/app/views/admin/research/journals/papers/kinds/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..1dbb60dda17bc324b93976c3b70971f4fc747264
--- /dev/null
+++ b/app/views/admin/research/journals/papers/kinds/new.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, Research::Journal::Paper::Kind.model_name.human %>
+
+<%= render 'form', kind: @kind %>
diff --git a/app/views/admin/research/journals/papers/kinds/show.html.erb b/app/views/admin/research/journals/papers/kinds/show.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b4f8798a4b8572bef813e791ceb9cc65c051d3c0
--- /dev/null
+++ b/app/views/admin/research/journals/papers/kinds/show.html.erb
@@ -0,0 +1,19 @@
+<% content_for :title, @kind %>
+
+<%= render 'admin/research/journals/papers/list', papers: @papers %>
+
+<% content_for :action_bar_left do %>
+  <%= link_to t('destroy'), 
+              admin_research_journal_kind_path(@kind),
+              data: { confirm: t('please_confirm') },
+              class: button_classes_danger %>
+  <%= link_to t('static'),
+              static_admin_research_journal_kind_path(@kind),
+              class: button_classes('btn-light') if current_user.server_admin? %>
+<% end %>
+
+<% content_for :action_bar_right do %>
+  <%= link_to t('edit'), 
+              edit_admin_research_journal_kind_path(@kind),
+              class: button_classes %>
+<% end %>
diff --git a/app/views/admin/research/journals/papers/kinds/static.html.erb b/app/views/admin/research/journals/papers/kinds/static.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..2e4291d1fa4fa8b077ea425bee0ea0340edca156
--- /dev/null
+++ b/app/views/admin/research/journals/papers/kinds/static.html.erb
@@ -0,0 +1,5 @@
+---
+title: >-
+  <%= prepare_text_for_static @about.title %>
+slug: "<%= @about.slug %>"
+---
diff --git a/app/views/admin/research/journals/papers/show.html.erb b/app/views/admin/research/journals/papers/show.html.erb
index f3bf6ca7c1dfc7c1eb0527c5ba3a449ebf8a44df..a4ab2037d7da3cb5eb430fa5c27ea0650ef90e41 100644
--- a/app/views/admin/research/journals/papers/show.html.erb
+++ b/app/views/admin/research/journals/papers/show.html.erb
@@ -47,6 +47,12 @@
           </h3>
           <p><%= @paper.keywords %></p>
         <% end %>
+        <% if @paper.kind %>
+          <h3 class="h5">
+            <%= Research::Journal::Paper.human_attribute_name('kind') %>
+          </h3>
+          <p><%= link_to @paper.kind, admin_research_journal_kind_path(@paper.kind) %></p>
+        <% end %>
         <% if @paper.people.any? %>
           <h3 class="h5">
             <%= Research::Journal::Paper.human_attribute_name('people') %>
@@ -65,6 +71,9 @@
 
 <% content_for :action_bar_left do %>
   <%= destroy_link @paper %>
+  <%= link_to t('static'),
+            static_admin_research_journal_paper_path(@paper),
+            class: button_classes('btn-light') if current_user.server_admin? %>
 <% end %>
 
 <% content_for :action_bar_right do %>
diff --git a/app/views/admin/research/journals/papers/static.html.erb b/app/views/admin/research/journals/papers/static.html.erb
index 3e38a4349020456c7c991042ffeb36951b823b27..b0fa46c0610b5f95f9d54d1a1ff47bca673020c6 100644
--- a/app/views/admin/research/journals/papers/static.html.erb
+++ b/app/views/admin/research/journals/papers/static.html.erb
@@ -1,9 +1,16 @@
 ---
-title: "<%= @about.title %>"
-slug: "<%= @about.slug %>"
+title: >-
+  <%= prepare_text_for_static @about.title %>
+<%= render 'admin/application/static/permalink' %>
+<% if @about.kind %>
+paper_kind: >-
+  <%= prepare_text_for_static @about.kind %>
+paper_kinds: 
+  - "<%= @about.kind.slug %>"
+<% end %>
 <% if @about.volume && @about.volume.path %>
 volumes:
-  - "<%= @about.volume.path %>"
+  - "<%= @about.volume.path.delete_prefix('/') %>"
 <% end %>
 weight: <%= @about.position %>
 date: "<%= @about.published_at.iso8601 %>"
diff --git a/app/views/admin/research/journals/show.html.erb b/app/views/admin/research/journals/show.html.erb
index 4cf2893c0aabc906c5052480805a21efce60aa54..d3a88ddf1c0a69badfb2954a989878f82fde4351 100644
--- a/app/views/admin/research/journals/show.html.erb
+++ b/app/views/admin/research/journals/show.html.erb
@@ -11,52 +11,72 @@
   <% if @journal.issn %><%= Research::Journal.human_attribute_name('issn') %> <%= @journal.issn %><% end %>
 <% end %>
 
-<%= render 'admin/application/summary/show', about: @journal %>
-<div class="card mt-5">
-  <div class="card-header">
-    <div class="float-end">
-      <%= link_to t('create'),
-                  new_admin_research_journal_volume_path(journal_id: @journal),
-                  class: button_classes %>
-    </div>
-    <h2 class="card-title">
-      <%= link_to Research::Journal::Volume.model_name.human(count: 2),
-                  admin_research_journal_volumes_path(journal_id: @journal) %></h2>
+<div class="row">
+  <div class="col-md-8">
+    <%= render 'admin/application/summary/show', about: @journal %>
+  </div>
+  <div class="col-md-4">
+    <%= render 'admin/application/meta_description/show', about: @journal %>
   </div>
-  <div class="card-body">
-    <div class="row">
-      <% @journal.volumes.ordered.limit(4).each do |volume| %>
-        <div class="col-md-3 mt-4">
-          <div class="card">
-            <%= image_tag volume.featured_image, class: 'img-fluid' if volume.featured_image.attached? %>
-            <div class="card-body">
-              <%= link_to volume,
-                          admin_research_journal_volume_path(journal_id: @journal, id: volume),
-                          class: "stretched-link #{'draft' unless volume.published?}" %>
-            </div>
-          </div>
+</div>
+
+<div class="float-end">
+  <%= link_to t('create'),
+              new_admin_research_journal_volume_path(journal_id: @journal),
+              class: button_classes %>
+</div>
+<h2 class="h4">
+  <%= link_to Research::Journal::Volume.model_name.human(count: 2),
+              admin_research_journal_volumes_path(journal_id: @journal) %>
+</h2>
+<div class="row">
+  <% @journal.volumes.ordered.limit(4).each do |volume| %>
+    <div class="col-md-3 mt-4 p-0">
+      <div class="card">
+        <%= kamifusen_tag volume.featured_image, width: 600, class: 'img-fluid' if volume.featured_image.attached? %>
+        <div class="card-body">
+          <%= link_to volume,
+                      admin_research_journal_volume_path(journal_id: @journal, id: volume),
+                      class: "stretched-link #{'draft' unless volume.published?}" %>
         </div>
-      <% end %>
+      </div>
     </div>
-  </div>
+  <% end %>
 </div>
 
-<div class="card mt-5">
-  <div class="card-header">
-    <div class="float-end">
-      <%= link_to t('create'),
-                  new_admin_research_journal_paper_path(journal_id: @journal),
-                  class: button_classes %>
+<div class="row">
+  <div class="col-md-8">
+    <div class="card mt-5">
+      <div class="card-header">
+        <div class="float-end">
+          <%= link_to t('create'),
+                      new_admin_research_journal_paper_path(journal_id: @journal),
+                      class: button_classes %>
+        </div>
+        <h2 class="card-title">
+          <%= link_to Research::Journal::Paper.model_name.human(count: 2),
+                      admin_research_journal_papers_path(journal_id: @journal) %></h2>
+      </div>
+      <%= render 'admin/research/journals/papers/list', papers: @papers %>
+    </div>
+  </div>
+  <div class="col-md-4">
+    <div class="card mt-5">
+      <div class="card-header">
+        <div class="float-end">
+          <%= link_to t('create'),
+                      new_admin_research_journal_kind_path(journal_id: @journal),
+                      class: button_classes %>
+        </div>
+        <h2 class="card-title">
+          <%= link_to Research::Journal::Paper::Kind.model_name.human(count: 2),
+                      admin_research_journal_kind_path(journal_id: @journal) %></h2>
+      </div>
+      <%= render 'admin/research/journals/papers/kinds/list', kinds: @kinds %>
     </div>
-    <h2 class="card-title">
-      <%= link_to Research::Journal::Paper.model_name.human(count: 2),
-                  admin_research_journal_papers_path(journal_id: @journal) %></h2>
   </div>
-  <%= render 'admin/research/journals/papers/list', papers: @papers %>
 </div>
 
-<%= render 'admin/application/meta_description/show', about: @journal %>
-
 <% content_for :action_bar_left do %>
   <%= destroy_link @journal %>
 <% end %>
diff --git a/app/views/admin/research/journals/volumes/show.html.erb b/app/views/admin/research/journals/volumes/show.html.erb
index 3294c87dc9f948c429d38adb63cf23e119dff031..1872da74cef693b7fde577f38866b0bd6b54e390 100644
--- a/app/views/admin/research/journals/volumes/show.html.erb
+++ b/app/views/admin/research/journals/volumes/show.html.erb
@@ -3,57 +3,50 @@
 <div class="row">
   <div class="col-md-9">
     <%= render 'admin/application/summary/show', about: @volume %>
-    <div class="card flex-fill w-100">
-      <div class="card-header">
-        <h2 class="card-title mb-0 h5"><%= t('content') %></h2>
-      </div>
-      <div class="card-body">
-        <% if @papers.any? %>
-          <h3 class="h5 mt-4"><%= Research::Journal::Volume.human_attribute_name('papers') %></h3>
-          <div class="table-responsive">
-            <table class="<%= table_classes %>">
-              <thead>
-                <tr>
-                  <% if can? :reorder, Research::Journal::Paper %>
-                    <th width="20" class="ps-0">&nbsp;</th>
-                  <% end %>
-                  <th class="ps-0"><%= Research::Journal::Paper.model_name.human %></th>
-                  <th><%= Research::Journal::Paper.human_attribute_name('published_at') %></th>
-                  <th></th>
-                </tr>
-              </thead>
-              <tbody data-sortable data-sort-url="<%= reorder_admin_research_journal_papers_path(journal_id: @journal.id) %>">
-                <% @papers.each do |paper| %>
-                  <tr data-id="<%= paper.id %>">
-                    <% if can? :reorder, Research::Journal::Paper %>
-                      <td><i class="fa fa-bars handle"></i></td>
-                    <% end %>
-                    <td>
-                      <%= link_to paper,
-                                  admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                                  class: "#{'draft' unless paper.published?}" %>
-                    </td>
-                    <td><%= l(paper.published_at.to_time, format: :date_with_explicit_month) if paper.published_at.present? %></td>
-                    <td class="text-end">
-                      <div class="btn-group" role="group">
-                        <%= link_to t('edit'),
-                                    edit_admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                                    class: button_classes %>
-                        <%= link_to t('delete'),
-                                    admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                                    method: :delete,
-                                    data: { confirm: t('please_confirm') },
-                                    class: button_classes_danger %>
-                      </div>
-                    </td>
-                  </tr>
+    <% if @papers.any? %>
+      <h3 class="h5 mt-5"><%= Research::Journal::Paper.model_name.human(count: 2) %></h3>
+      <div class="table-responsive">
+        <table class="<%= table_classes %>">
+          <thead>
+            <tr>
+              <% if can? :reorder, Research::Journal::Paper %>
+                <th width="20" class="ps-0">&nbsp;</th>
+              <% end %>
+              <th class="ps-0"><%= Research::Journal::Paper.human_attribute_name('title') %></th>
+              <th><%= Research::Journal::Paper.human_attribute_name('published_at') %></th>
+              <th></th>
+            </tr>
+          </thead>
+          <tbody data-sortable data-sort-url="<%= reorder_admin_research_journal_papers_path(journal_id: @journal.id) %>">
+            <% @papers.each do |paper| %>
+              <tr data-id="<%= paper.id %>">
+                <% if can? :reorder, Research::Journal::Paper %>
+                  <td><i class="fa fa-bars handle"></i></td>
                 <% end %>
-              </tbody>
-            </table>
-          </div>
-        <% end %>
+                <td>
+                  <%= link_to paper,
+                              admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                              class: "#{'draft' unless paper.published?}" %>
+                </td>
+                <td><%= l(paper.published_at.to_time, format: :date_with_explicit_month) if paper.published_at.present? %></td>
+                <td class="text-end">
+                  <div class="btn-group" role="group">
+                    <%= link_to t('edit'),
+                                edit_admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                                class: button_classes %>
+                    <%= link_to t('delete'),
+                                admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                                method: :delete,
+                                data: { confirm: t('please_confirm') },
+                                class: button_classes_danger %>
+                  </div>
+                </td>
+              </tr>
+            <% end %>
+          </tbody>
+        </table>
       </div>
-    </div>
+    <% end %>
   </div>
   <div class="col-md-3">
     <div class="card flex-fill w-100">
@@ -74,6 +67,9 @@
 
 <% content_for :action_bar_left do %>
   <%= destroy_link @volume %>
+  <%= link_to t('static'),
+        static_admin_research_journal_volume_path(@volume),
+        class: button_classes('btn-light') if current_user.server_admin? %>
 <% end %>
 
 <% content_for :action_bar_right do %>
diff --git a/app/views/admin/research/journals/volumes/static.html.erb b/app/views/admin/research/journals/volumes/static.html.erb
index 284cefba7cc7a2268aa2ad1271fa97c9d65798f9..88870d95459bb9240f1ca556dc5dea4d921e1fc7 100644
--- a/app/views/admin/research/journals/volumes/static.html.erb
+++ b/app/views/admin/research/journals/volumes/static.html.erb
@@ -1,6 +1,7 @@
 ---
-title: "<%= @about.title %>"
-slug: "<%= @about.slug %>"
+title: >-
+  <%= prepare_text_for_static @about.title %>
+<%= render 'admin/application/static/permalink' %>
 number: <%= @about.number %>
 issn: "<%= @about.journal.issn %>"
 keywords: >
diff --git a/app/views/server/blocks/show.html.erb b/app/views/server/blocks/show.html.erb
index b56285d126ae23d1b69fca2f8add0894e7acb6bb..44e5518481def89fcc85bfa308c2466794dd3afa 100644
--- a/app/views/server/blocks/show.html.erb
+++ b/app/views/server/blocks/show.html.erb
@@ -38,7 +38,7 @@
 
 <% content_for :action_bar_right do %>
   <%= link_to t('resave'),
-              server_resave_block_path(@template),
+              resave_server_block_path(@template),
               method: :post,
               class: button_classes %>
 <% end %>
diff --git a/config/locales/research/en.yml b/config/locales/research/en.yml
index 7e0270965abc5b8d78550366fbf035c41ff09f3c..4ac3f87f6e41abfd7ed54e47c57380af2400dcfe 100644
--- a/config/locales/research/en.yml
+++ b/config/locales/research/en.yml
@@ -10,6 +10,9 @@ en:
       research/journal/paper:
         one: Paper
         other: Papers
+      research/journal/paper/kind:
+        one: Kind of paper
+        other: Kinds of paper
       research/journal/volume:
         one: Volume
         other: Volumes
@@ -33,9 +36,12 @@ en:
         published: Published?
         published_at: Published at
         references: References
+        kind: Kind of paper
         people: Authors
         text: Text
         title: Title
+      research/journal/paper/kind:
+        title: Title
       research/journal/volume:
         featured_image: Cover
         featured_image_alt: Alt text
diff --git a/config/locales/research/fr.yml b/config/locales/research/fr.yml
index 2b5e8e04aa3bca8f8bf0d8be788c77d68dcb0c91..baa9d39da0b2063d69f970cb75eb4c8ce6818ece 100644
--- a/config/locales/research/fr.yml
+++ b/config/locales/research/fr.yml
@@ -10,6 +10,9 @@ fr:
       research/journal/paper:
         one: Papier
         other: Papiers
+      research/journal/paper/kind:
+        one: Type de papier
+        other: Types de papier
       research/journal/volume:
         one: Volumes
         other: Volumes
@@ -33,9 +36,12 @@ fr:
         published: Publié ?
         published_at: Publié le
         references: Références
+        kind: Type de papier
         people: Auteu·rs·rices
         text: Texte
         title: Titre
+      research/journal/paper/kind:
+        title: Titre
       research/journal/volume:
         featured_image: Couverture
         featured_image_alt: Texte alternatif
diff --git a/config/routes/admin/research.rb b/config/routes/admin/research.rb
index 7a1189c6039be5fd66838d756ef9429487bcda61..024239d0f6c7c1eca66573baa71689122ef27de3 100644
--- a/config/routes/admin/research.rb
+++ b/config/routes/admin/research.rb
@@ -1,11 +1,23 @@
 namespace :research do
   resources :researchers, only: [:index, :show]
   resources :journals do
-    resources :volumes, controller: 'journals/volumes'
+    resources :volumes, controller: 'journals/volumes' do
+      member do
+        get :static
+      end
+    end
     resources :papers, controller: 'journals/papers' do
       collection do
+        resources :kinds, controller: 'journals/papers/kinds' do
+          member do
+            get :static
+          end
+        end
         post :reorder
       end
+      member do
+        get :static
+      end
     end
   end
   resources :laboratories do
diff --git a/config/routes/server.rb b/config/routes/server.rb
index a73ae7b34377a243a0a51475e09766e810e5523d..576fba530c50028275c2641e6dd7ffdf10610731 100644
--- a/config/routes/server.rb
+++ b/config/routes/server.rb
@@ -2,12 +2,10 @@ namespace :server do
   resources :universities
   resources :languages
   resources :websites, only: :index do
-    member do
-      post :refresh
-    end
+    post :refresh, on: :member
+  end
+  resources :blocks, only: [:index, :show] do
+    post :resave, on: :member
   end
-  get 'blocks' => 'blocks#index', as: :blocks
-  get 'blocks/:id' => 'blocks#show', as: :block
-  post 'blocks/:id' => 'blocks#resave', as: :resave_block
   root to: 'dashboard#index'
 end
diff --git a/db/migrate/20230118175136_create_research_journal_paper_kinds.rb b/db/migrate/20230118175136_create_research_journal_paper_kinds.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a9d214686c5c812a1cc06d26e67c62e8468d84ed
--- /dev/null
+++ b/db/migrate/20230118175136_create_research_journal_paper_kinds.rb
@@ -0,0 +1,12 @@
+class CreateResearchJournalPaperKinds < ActiveRecord::Migration[7.0]
+  def change
+    create_table :research_journal_paper_kinds, id: :uuid do |t|
+      t.references :university, null: false, foreign_key: true, type: :uuid
+      t.references :journal, null: false, foreign_key: {to_table: :research_journals}, type: :uuid
+      t.string :title
+      t.string :slug
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20230118201432_add_paper_kind_to_research_journal_paper.rb b/db/migrate/20230118201432_add_paper_kind_to_research_journal_paper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f0f82bd2f4494902db9d4313e423acb8dbf71ebb
--- /dev/null
+++ b/db/migrate/20230118201432_add_paper_kind_to_research_journal_paper.rb
@@ -0,0 +1,5 @@
+class AddPaperKindToResearchJournalPaper < ActiveRecord::Migration[7.0]
+  def change
+    add_reference :research_journal_papers, :paper_kind, foreign_key: {to_table: :research_journal_paper_kinds}, type: :uuid
+  end
+end
diff --git a/db/migrate/20230119164205_rename_paper_kind_id_to_kind_id.rb b/db/migrate/20230119164205_rename_paper_kind_id_to_kind_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4fca97166c078845a6e628cd4074309d24bf12fc
--- /dev/null
+++ b/db/migrate/20230119164205_rename_paper_kind_id_to_kind_id.rb
@@ -0,0 +1,5 @@
+class RenamePaperKindIdToKindId < ActiveRecord::Migration[7.0]
+  def change
+    rename_column :research_journal_papers, :paper_kind_id, :kind_id
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3b10bbf28c158e52663b7a0cd518d969a91b49a5..000140485ee26f62f4579bbfe3c24306ca432a69 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.0].define(version: 2023_01_13_164208) do
+ActiveRecord::Schema[7.0].define(version: 2023_01_19_164205) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
   enable_extension "plpgsql"
@@ -581,6 +581,17 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_164208) do
     t.index ["university_person_id"], name: "index_research_documents_on_university_person_id"
   end
 
+  create_table "research_journal_paper_kinds", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.uuid "university_id", null: false
+    t.uuid "journal_id", null: false
+    t.string "title"
+    t.string "slug"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["journal_id"], name: "index_research_journal_paper_kinds_on_journal_id"
+    t.index ["university_id"], name: "index_research_journal_paper_kinds_on_university_id"
+  end
+
   create_table "research_journal_papers", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
     t.string "title"
     t.datetime "published_at", precision: nil
@@ -599,6 +610,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_164208) do
     t.text "text"
     t.text "meta_description"
     t.text "summary"
+    t.uuid "kind_id"
+    t.index ["kind_id"], name: "index_research_journal_papers_on_kind_id"
     t.index ["research_journal_id"], name: "index_research_journal_papers_on_research_journal_id"
     t.index ["research_journal_volume_id"], name: "index_research_journal_papers_on_research_journal_volume_id"
     t.index ["university_id"], name: "index_research_journal_papers_on_university_id"
@@ -655,13 +668,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_164208) do
     t.index ["university_id"], name: "index_research_laboratories_on_university_id"
   end
 
-  create_table "research_laboratories_publications", id: false, force: :cascade do |t|
-    t.uuid "research_publication_id", null: false
-    t.uuid "research_laboratory_id", null: false
-    t.index ["research_laboratory_id", "research_publication_id"], name: "index_laboratory_publication"
-    t.index ["research_publication_id", "research_laboratory_id"], name: "index_publication_laboratory"
-  end
-
   create_table "research_laboratory_axes", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
     t.uuid "university_id", null: false
     t.uuid "research_laboratory_id", null: false
@@ -676,27 +682,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_164208) do
     t.index ["university_id"], name: "index_research_laboratory_axes_on_university_id"
   end
 
-  create_table "research_publications", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
-    t.string "docid"
-    t.jsonb "data"
-    t.string "title"
-    t.string "url"
-    t.string "ref"
-    t.datetime "created_at", null: false
-    t.datetime "updated_at", null: false
-    t.string "hal_url"
-    t.date "publication_date"
-    t.string "doi"
-    t.string "slug"
-  end
-
-  create_table "research_publications_university_people", id: false, force: :cascade do |t|
-    t.uuid "research_publication_id", null: false
-    t.uuid "university_person_id", null: false
-    t.index ["research_publication_id", "university_person_id"], name: "index_publication_person"
-    t.index ["university_person_id", "research_publication_id"], name: "index_person_publication"
-  end
-
   create_table "research_theses", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
     t.uuid "university_id", null: false
     t.uuid "research_laboratory_id", null: false
@@ -949,6 +934,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_164208) do
   add_foreign_key "imports", "users"
   add_foreign_key "research_documents", "universities"
   add_foreign_key "research_documents", "university_people"
+  add_foreign_key "research_journal_paper_kinds", "research_journals", column: "journal_id"
+  add_foreign_key "research_journal_paper_kinds", "universities"
+  add_foreign_key "research_journal_papers", "research_journal_paper_kinds", column: "kind_id"
   add_foreign_key "research_journal_papers", "research_journal_volumes"
   add_foreign_key "research_journal_papers", "research_journals"
   add_foreign_key "research_journal_papers", "universities"
diff --git a/test/controllers/.keep b/test/controllers/.keep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/test/controllers/extranet/academic_years_controller_test.rb b/test/controllers/extranet/academic_years_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f4b820116447d53bb1a019315143d3bc0b6cb0e6
--- /dev/null
+++ b/test/controllers/extranet/academic_years_controller_test.rb
@@ -0,0 +1,15 @@
+require "test_helper"
+
+class Extranet::AcademicYearsControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_index
+    get education_academic_years_path
+    assert_response(:success)
+  end
+
+  def test_show
+    get education_academic_year_path(education_academic_years(:twenty_two))
+    assert_response(:success)
+  end
+end
diff --git a/test/controllers/extranet/account_controller_test.rb b/test/controllers/extranet/account_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..058100d742c8be09e59726de228462d0a0beaae2
--- /dev/null
+++ b/test/controllers/extranet/account_controller_test.rb
@@ -0,0 +1,27 @@
+require "test_helper"
+
+class Extranet::AccountControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_show
+    get account_path
+    assert_response(:success)
+  end
+
+  def test_edit
+    get edit_account_path
+    assert_response(:success)
+  end
+
+  def test_update
+    assert_equal("Alumnus", alumnus.first_name)
+    patch account_path, params: { user: { first_name: "New Alumnus" } }
+    assert_redirected_to(account_path)
+    assert_equal("New Alumnus", alumnus.first_name)
+  end
+
+  def test_update_password
+    patch account_path, params: { user: { password: "NewPassw0rd!" } }
+    assert_redirected_to(account_path)
+  end
+end
diff --git a/test/controllers/extranet/cohorts_controller_test.rb b/test/controllers/extranet/cohorts_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f925d1782d23748fa6b6020908755153d2a9ae4e
--- /dev/null
+++ b/test/controllers/extranet/cohorts_controller_test.rb
@@ -0,0 +1,15 @@
+require "test_helper"
+
+class Extranet::CohortsControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_index
+    get education_cohorts_path
+    assert_response(:success)
+  end
+
+  def test_show
+    get education_cohort_path(education_cohorts(:default_cohort))
+    assert_response(:success)
+  end
+end
diff --git a/test/controllers/extranet/experiences_controller_test.rb b/test/controllers/extranet/experiences_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a46eed81b602b6568defc4d0c932d42e116ba143
--- /dev/null
+++ b/test/controllers/extranet/experiences_controller_test.rb
@@ -0,0 +1,67 @@
+require "test_helper"
+
+class Extranet::ExperiencesControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_new
+    get new_experience_path
+    assert_response(:success)
+  end
+
+  def test_create
+    assert_difference("alumnus.experiences.count") do
+      post experiences_path, params: {
+        university_person_experience: {
+          description: "Stage",
+          from_year: 2022,
+          to_year: 2022,
+          organization_id: university_organizations(:default_organization).id
+        }
+      }
+      assert_redirected_to(account_path)
+    end
+  end
+
+  def test_create_invalid
+    assert_no_difference("alumnus.experiences.count") do
+      post experiences_path, params: {
+        university_person_experience: {
+          description: "Stage",
+          from_year: 2022,
+          to_year: 2022
+        }
+      }
+      assert_response(:success)
+    end
+  end
+
+  def test_edit
+    get edit_experience_path(university_person_experiences(:default_experience))
+    assert_response(:success)
+  end
+
+  def test_update
+    experience = university_person_experiences(:default_experience)
+
+    assert(experience.description.blank?)
+    patch experience_path(experience), params: {
+      university_person_experience: {
+        description: "Alternance"
+      }
+    }
+    assert_redirected_to(account_path)
+    assert_equal("Alternance", experience.reload.description)
+  end
+
+  def test_update_invalid
+    experience = university_person_experiences(:default_experience)
+
+    patch experience_path(experience), params: {
+      university_person_experience: {
+        organization_id: ""
+      }
+    }
+    assert_response(:success)
+  end
+
+end
diff --git a/test/controllers/extranet/home_controller_test.rb b/test/controllers/extranet/home_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..54066658cead1bc9beef751897201af41f6b7380
--- /dev/null
+++ b/test/controllers/extranet/home_controller_test.rb
@@ -0,0 +1,22 @@
+require "test_helper"
+
+class Extranet::HomeControllerTest < ActionDispatch::IntegrationTest
+  def test_index_unknown_context
+    host! "example.com"
+    get(root_path)
+    assert_response(:forbidden)
+  end
+
+  def test_index_unauthenticated
+    host! default_extranet.host
+    get(root_path)
+    assert_redirected_to(new_user_session_path)
+  end
+
+  def test_index
+    host! default_extranet.host
+    sign_in_with_2fa(alumnus)
+    get(root_path)
+    assert_response(:success)
+  end
+end
diff --git a/test/controllers/extranet/organizations_controller_test.rb b/test/controllers/extranet/organizations_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5e3edacefa33e6b2a66bae06b287bad50dad458b
--- /dev/null
+++ b/test/controllers/extranet/organizations_controller_test.rb
@@ -0,0 +1,23 @@
+require "test_helper"
+
+class Extranet::OrganizationsControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_index
+    get university_organizations_path
+    assert_response(:success)
+  end
+
+  def test_search
+    get search_university_organizations_path(term: "Organisation de test")
+    assert_response(:success)
+    results = JSON.parse(response.body)
+    assert_equal(1, results.size)
+    assert_equal("Organisation de test", results.first["label"])
+  end
+
+  def test_show
+    get university_organization_path(university_organizations(:default_organization))
+    assert_response(:success)
+  end
+end
diff --git a/test/controllers/extranet/pages_controller_test.rb b/test/controllers/extranet/pages_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..54c8e76d31aa3ecc66d7f763b0121e6511554efa
--- /dev/null
+++ b/test/controllers/extranet/pages_controller_test.rb
@@ -0,0 +1,25 @@
+require "test_helper"
+
+class Extranet::PagesControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_terms
+    get terms_path
+    assert_response(:success)
+  end
+
+  def test_cookies_policy
+    get cookies_policy_path
+    assert_response(:success)
+  end
+
+  def test_privacy_policy
+    get privacy_policy_path
+    assert_response(:success)
+  end
+
+  def test_data
+    get data_path
+    assert_response(:success)
+  end
+end
diff --git a/test/controllers/extranet/personal_data_controller_test.rb b/test/controllers/extranet/personal_data_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..493849e3cc7a0127d6177cca7c147786e65f9c68
--- /dev/null
+++ b/test/controllers/extranet/personal_data_controller_test.rb
@@ -0,0 +1,17 @@
+require "test_helper"
+
+class Extranet::PersonalDataControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_edit
+    get edit_personal_data_path
+    assert_response(:success)
+  end
+
+  def test_update
+    assert(alumnus_person.biography.blank?)
+    patch personal_data_path, params: { university_person: { biography: "<p>Je suis un ancien étudiant.</p>" } }
+    assert_redirected_to(account_path)
+    assert(alumnus_person.reload.biography.to_s.include?("Je suis un ancien étudiant."))
+  end
+end
diff --git a/test/controllers/extranet/persons_controller_test.rb b/test/controllers/extranet/persons_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1b4d10523048015f6f3f1f3d6abcdcf8f7c227d4
--- /dev/null
+++ b/test/controllers/extranet/persons_controller_test.rb
@@ -0,0 +1,15 @@
+require "test_helper"
+
+class Extranet::PersonsControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_index
+    get university_persons_path
+    assert_response(:success)
+  end
+
+  def test_show
+    get university_person_path(university_people(:alumnus))
+    assert_response(:success)
+  end
+end
diff --git a/test/controllers/server/blocks_controller_test.rb b/test/controllers/server/blocks_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e3d3d4f7fddeeaf8c8818fc42dd9826dfecd0872
--- /dev/null
+++ b/test/controllers/server/blocks_controller_test.rb
@@ -0,0 +1,20 @@
+require "test_helper"
+
+class Server::BlocksControllerTest < ActionDispatch::IntegrationTest
+  include ServerSetup
+
+  def test_index
+    get server_blocks_path
+    assert_response(:success)
+  end
+
+  def test_show
+    get(server_block_path("chapter"))
+    assert_response(:success)
+  end
+
+  def test_resave
+    post(resave_server_block_path("chapter"))
+    assert_redirected_to(server_block_path("chapter"))
+  end
+end
diff --git a/test/controllers/server/dashboard_controller_test.rb b/test/controllers/server/dashboard_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6d8882ab319a6b4aee7f23d492ed9c72d5cc2854
--- /dev/null
+++ b/test/controllers/server/dashboard_controller_test.rb
@@ -0,0 +1,10 @@
+require "test_helper"
+
+class Server::DashboardControllerTest < ActionDispatch::IntegrationTest
+  include ServerSetup
+
+  def test_index
+    get server_root_path
+    assert_response(:success)
+  end
+end
diff --git a/test/controllers/server/languages_controller_test.rb b/test/controllers/server/languages_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1e1fdadd49f860ff22ec164cd82513eadb9d5829
--- /dev/null
+++ b/test/controllers/server/languages_controller_test.rb
@@ -0,0 +1,71 @@
+require "test_helper"
+
+class Server::LanguagesControllerTest < ActionDispatch::IntegrationTest
+  include ServerSetup
+
+  def test_index
+    get server_languages_path
+    assert_response(:success)
+  end
+
+  def test_show
+    get server_language_path(languages(:fr))
+    assert_response(:success)
+  end
+
+  def test_new
+    get new_server_language_path
+    assert_response(:success)
+  end
+
+  def test_edit
+    get edit_server_language_path(languages(:fr))
+    assert_response(:success)
+  end
+
+  def test_create
+    assert_difference("Language.count") do
+      post server_languages_path, params: {
+        language: {
+          name: "Español",
+          iso_code: "es"
+        }
+      }
+      language = Language.find_by(iso_code: "es")
+      assert_redirected_to(server_language_path(language))
+    end
+  end
+
+  def test_create_invalid
+    assert_no_difference("Language.count") do
+      post server_languages_path, params: {
+        language: {
+          name: "Français",
+          iso_code: "fr"
+        }
+      }
+      assert_response(:unprocessable_entity)
+    end
+  end
+
+  def test_update
+    language = languages(:fr)
+    assert(language.summernote_locale.blank?)
+    patch server_language_path(language), params: { language: { summernote_locale: "fr-FR" } }
+    assert_redirected_to(server_language_path(language))
+    assert_equal "fr-FR", language.reload.summernote_locale
+  end
+
+  def test_update_invalid
+    language = languages(:fr)
+    patch server_language_path(language), params: { language: { iso_code: "" } }
+    assert_response(:unprocessable_entity)
+  end
+
+  def test_destroy
+    assert_difference("Language.count", -1) do
+      delete server_language_path(languages(:it))
+      assert_redirected_to(server_languages_path)
+    end
+  end
+end
diff --git a/test/controllers/server/universities_controller_test.rb b/test/controllers/server/universities_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b68f98caf705d19e40061400faa38353b04c893e
--- /dev/null
+++ b/test/controllers/server/universities_controller_test.rb
@@ -0,0 +1,73 @@
+require "test_helper"
+
+class Server::UniversitiesControllerTest < ActionDispatch::IntegrationTest
+  include ServerSetup
+
+  def test_index
+    get server_universities_path
+    assert_response(:success)
+  end
+
+  def test_show
+    get server_university_path(universities(:default_university))
+    assert_response(:success)
+  end
+
+  def test_new
+    get new_server_university_path
+    assert_response(:success)
+  end
+
+  def test_edit
+    get edit_server_university_path(universities(:default_university))
+    assert_response(:success)
+  end
+
+  def test_create
+    assert_difference("University.count") do
+      post server_universities_path, params: {
+        university: {
+          name: "Nouvelle université",
+          identifier: "my-second-university",
+          sms_sender_name: "unitest2"
+        }
+      }
+      university = University.find_by(identifier: "my-second-university")
+      assert_redirected_to(server_university_path(university))
+    end
+  end
+
+  def test_create_invalid
+    assert_no_difference("University.count") do
+      post server_universities_path, params: {
+        university: {
+          name: "Nouvelle université",
+          sms_sender_name: "unitest2"
+        }
+      }
+      assert_response(:unprocessable_entity)
+    end
+  end
+
+  def test_update
+    university = universities(:default_university)
+    assert_equal "Université de test", university.name
+    patch server_university_path(university), params: { university: { name: "Mon université" } }
+    assert_redirected_to(server_university_path(university))
+    assert_equal "Mon université", university.reload.name
+  end
+
+  def test_update_invalid
+    university = universities(:default_university)
+    patch server_university_path(university), params: { university: { identifier: "" } }
+    assert_response(:unprocessable_entity)
+  end
+
+  def test_destroy
+    assert_difference("University.count", -1) do
+      # TODO: Replace by default university with correct dependent: :destroy associations
+      delete server_university_path(universities(:stale_university))
+      assert_redirected_to(server_universities_path)
+    end
+  end
+end
diff --git a/test/controllers/server/websites_controller_test.rb b/test/controllers/server/websites_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..aad867f2bf210edc879663d501dba29b97bbc4db
--- /dev/null
+++ b/test/controllers/server/websites_controller_test.rb
@@ -0,0 +1,15 @@
+require "test_helper"
+
+class Server::WebsitesControllerTest < ActionDispatch::IntegrationTest
+  include ServerSetup
+
+  def test_index
+    get server_websites_path
+    assert_response(:success)
+  end
+
+  def test_refresh
+    post(refresh_server_website_path(communication_websites(:website_with_github)))
+    assert_redirected_to(server_websites_path)
+  end
+end
diff --git a/test/fixtures/communication/extranets.yml b/test/fixtures/communication/extranets.yml
index fa530b05dc39e3bba0a50ce627f0bc81732644ee..c11ef9e9fbf6dbb1fcb38a1d4f7106c7ca2c0d8b 100644
--- a/test/fixtures/communication/extranets.yml
+++ b/test/fixtures/communication/extranets.yml
@@ -33,12 +33,8 @@
 #  fk_rails_c2268c7ebd  (university_id => universities.id)
 #
 
-one:
-  name: MyString
-  university: default_university
-  host: MyString
-
-two:
-  name: MyString
-  university: default_university
-  host: MyString
+default_extranet:
+  name: Extranet de test
+  host: extranet.osuny.test
+  about: default_program (Education::Program)
+  university: default_university
\ No newline at end of file
diff --git a/test/fixtures/education/academic_years.yml b/test/fixtures/education/academic_years.yml
index ede802b5266f17befabe1b26fffb7af3fb9d08bf..569a5d2a15640f8f57b39d42e0f039f4bfa7c53f 100644
--- a/test/fixtures/education/academic_years.yml
+++ b/test/fixtures/education/academic_years.yml
@@ -17,10 +17,10 @@
 #  fk_rails_7d376afe35  (university_id => universities.id)
 #
 
-one:
+twenty_two:
   university: default_university
   year: 2022
 
-two:
+twenty_three:
   university: default_university
   year: 2023
diff --git a/test/fixtures/education/cohorts.yml b/test/fixtures/education/cohorts.yml
index 9299e067deb71190564efb9f5b0f2d3db370e8c4..7e9d752e8762e39a1ea0717787f8d49c454d6e3a 100644
--- a/test/fixtures/education/cohorts.yml
+++ b/test/fixtures/education/cohorts.yml
@@ -26,16 +26,9 @@
 #  fk_rails_c2d725cabd  (academic_year_id => education_academic_years.id)
 #
 
-one:
+default_cohort:
+  name: Formation de test 2022
   university: default_university
   school: default_school
-  program: one
-  academic_year: one
-  name: MyString
-
-two:
-  university: default_university
-  school: default_school
-  program: two
-  academic_year: two
-  name: MyString
+  program: default_program
+  academic_year: twenty_two
diff --git a/test/fixtures/education/diplomas.yml b/test/fixtures/education/diplomas.yml
index 03ebcb6c3c2b335da001641ef79b055312b49ed7..9c46a831c5b29066e9e054d15b6adddd093f8e0e 100644
--- a/test/fixtures/education/diplomas.yml
+++ b/test/fixtures/education/diplomas.yml
@@ -23,16 +23,7 @@
 #  fk_rails_6cb2e9fa90  (university_id => universities.id)
 #
 
-one:
+default_diploma:
+  name: Diplôme de test
+  short_name: DT
   university: default_university
-  name: MyString
-  short_name: MyString
-  level: 1
-  slug: MyString
-
-two:
-  university: default_university
-  name: MyString
-  short_name: MyString
-  level: 1
-  slug: MyString
diff --git a/test/fixtures/education/programs.yml b/test/fixtures/education/programs.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d57e55b11b61fe5a9a69c741e4a1dc4cca973947
--- /dev/null
+++ b/test/fixtures/education/programs.yml
@@ -0,0 +1,59 @@
+# == Schema Information
+#
+# Table name: education_programs
+#
+#  id                    :uuid             not null, primary key
+#  accessibility         :text
+#  apprenticeship        :boolean
+#  capacity              :integer
+#  contacts              :text
+#  content               :text
+#  continuing            :boolean
+#  duration              :text
+#  evaluation            :text
+#  featured_image_alt    :string
+#  featured_image_credit :text
+#  initial               :boolean
+#  meta_description      :text
+#  name                  :string
+#  objectives            :text
+#  opportunities         :text
+#  other                 :text
+#  path                  :string
+#  pedagogy              :text
+#  position              :integer          default(0)
+#  prerequisites         :text
+#  presentation          :text
+#  pricing               :text
+#  published             :boolean          default(FALSE)
+#  registration          :text
+#  registration_url      :string
+#  results               :text
+#  short_name            :string
+#  slug                  :string
+#  summary               :text
+#  created_at            :datetime         not null
+#  updated_at            :datetime         not null
+#  diploma_id            :uuid             indexed
+#  parent_id             :uuid             indexed
+#  university_id         :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_education_programs_on_diploma_id     (diploma_id)
+#  index_education_programs_on_parent_id      (parent_id)
+#  index_education_programs_on_university_id  (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_08b351087c  (university_id => universities.id)
+#  fk_rails_ec1f16f607  (parent_id => education_programs.id)
+#
+
+default_program:
+  name: Formation de test
+  published: true
+  diploma: default_diploma
+  schools:
+    - default_school
+  university: default_university
diff --git a/test/fixtures/education/schools.yml b/test/fixtures/education/schools.yml
index c8a131ca199b79365c37ff32222a464da85f073b..e0f957684160759345546501322ce012c2156cb4 100644
--- a/test/fixtures/education/schools.yml
+++ b/test/fixtures/education/schools.yml
@@ -25,4 +25,8 @@
 #
 default_school:
   name: École de test
-  university: default_university
+  address: 1 Rue Jacques Ellul
+  zipcode: 33080
+  city: Bordeaux
+  country: FR
+  university: default_university
\ No newline at end of file
diff --git a/test/fixtures/languages.yml b/test/fixtures/languages.yml
index 7927df719648b1e74869ee705ee9228d8451a56c..d185db7fb28ab5866aea2f8048a9db2730f4036c 100644
--- a/test/fixtures/languages.yml
+++ b/test/fixtures/languages.yml
@@ -16,3 +16,7 @@ en:
 fr:
   name: Français
   iso_code: fr
+
+it:
+  name: Italiano
+  iso_code: it
diff --git a/test/fixtures/research/journal/paper/kinds.yml b/test/fixtures/research/journal/paper/kinds.yml
new file mode 100644
index 0000000000000000000000000000000000000000..70e0e791df4d71edfc2999ee0e6125994c469f0b
--- /dev/null
+++ b/test/fixtures/research/journal/paper/kinds.yml
@@ -0,0 +1,34 @@
+# == Schema Information
+#
+# Table name: research_journal_paper_kinds
+#
+#  id            :uuid             not null, primary key
+#  slug          :string
+#  title         :string
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  journal_id    :uuid             not null, indexed
+#  university_id :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_research_journal_paper_kinds_on_journal_id     (journal_id)
+#  index_research_journal_paper_kinds_on_university_id  (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_57217513c3  (journal_id => research_journals.id)
+#  fk_rails_8e6f992b9d  (university_id => universities.id)
+#
+
+one:
+  university: default_university
+  journal: default_journal
+  title: Articles
+  slug: articles
+
+two:
+  university: default_university
+  journal: default_journal
+  title: Recensions
+  slug: recensions
diff --git a/test/fixtures/research/journals.yml b/test/fixtures/research/journals.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4ee7c0c8f20c84367c67c6c82a237c5f72cffa42
--- /dev/null
+++ b/test/fixtures/research/journals.yml
@@ -0,0 +1,24 @@
+# == Schema Information
+#
+# Table name: research_journals
+#
+#  id               :uuid             not null, primary key
+#  issn             :string
+#  meta_description :text
+#  summary          :text
+#  title            :string
+#  created_at       :datetime         not null
+#  updated_at       :datetime         not null
+#  university_id    :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_research_journals_on_university_id  (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_96097d5f10  (university_id => universities.id)
+#
+default_journal:
+  university: default_university
+  title: Journal
diff --git a/test/fixtures/universities.yml b/test/fixtures/universities.yml
index e51e10e50f4ca8868060a634b4aaa7e0562acc38..a472c793d596ee8d5ebee66ac613a32d6c9ff02d 100644
--- a/test/fixtures/universities.yml
+++ b/test/fixtures/universities.yml
@@ -28,3 +28,10 @@
 #
 default_university:
   name: Université de test
+  identifier: my-university
+  sms_sender_name: "unitest"
+
+stale_university:
+  name: Université obsolète
+  identifier: stale-university
+  sms_sender_name: "unistale"
\ No newline at end of file
diff --git a/test/fixtures/university/organizations.yml b/test/fixtures/university/organizations.yml
index a684cda0bc2ac7ee17bc8505652fb23c069af8b6..08514e6ab2b50be732b4a828a535e525f17036fc 100644
--- a/test/fixtures/university/organizations.yml
+++ b/test/fixtures/university/organizations.yml
@@ -36,32 +36,7 @@
 #  fk_rails_35fcd198e0  (university_id => universities.id)
 #
 
-one:
+default_organization:
+  name: Organisation de test
+  active: true
   university: default_university
-  name: MyString
-  meta_description: MyText
-  address: MyString
-  zipcode: MyString
-  city: MyString
-  country: MyString
-  url: MyString
-  phone: MyString
-  email: MyString
-  active: false
-  siren: MyString
-  kind: 1
-
-two:
-  university: default_university
-  name: MyString
-  meta_description: MyText
-  address: MyString
-  zipcode: MyString
-  city: MyString
-  country: MyString
-  url: MyString
-  phone: MyString
-  email: MyString
-  active: false
-  siren: MyString
-  kind: 1
diff --git a/test/fixtures/university/people.yml b/test/fixtures/university/people.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4e8fe14b399071b394c160ebcdebd46339a1fd36
--- /dev/null
+++ b/test/fixtures/university/people.yml
@@ -0,0 +1,59 @@
+# == Schema Information
+#
+# Table name: university_people
+#
+#  id                    :uuid             not null, primary key
+#  address               :string
+#  biography             :text
+#  birthdate             :date
+#  city                  :string
+#  country               :string
+#  email                 :string
+#  first_name            :string
+#  gender                :integer
+#  habilitation          :boolean          default(FALSE)
+#  is_administration     :boolean
+#  is_alumnus            :boolean          default(FALSE)
+#  is_author             :boolean
+#  is_researcher         :boolean
+#  is_teacher            :boolean
+#  last_name             :string
+#  linkedin              :string
+#  mastodon              :string
+#  meta_description      :text
+#  name                  :string
+#  phone_mobile          :string
+#  phone_personal        :string
+#  phone_professional    :string
+#  slug                  :string
+#  summary               :text
+#  tenure                :boolean          default(FALSE)
+#  twitter               :string
+#  url                   :string
+#  zipcode               :string
+#  created_at            :datetime         not null
+#  updated_at            :datetime         not null
+#  university_id         :uuid             not null, indexed
+#  user_id               :uuid             indexed
+#
+# Indexes
+#
+#  index_university_people_on_university_id  (university_id)
+#  index_university_people_on_user_id        (user_id)
+#
+# Foreign Keys
+#
+#  fk_rails_b47a769440  (user_id => users.id)
+#  fk_rails_da35e70d61  (university_id => universities.id)
+#
+
+alumnus:
+  email: alumnus@osuny.org
+  first_name: Alumnus
+  is_alumnus: true
+  last_name: Osuny
+  name: Alumnus Osuny
+  cohorts:
+    - default_cohort
+  university: default_university
+  user: alumnus
diff --git a/test/fixtures/university/person/experiences.yml b/test/fixtures/university/person/experiences.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8aa8f8850da1f347aeb54204a567a90809601382
--- /dev/null
+++ b/test/fixtures/university/person/experiences.yml
@@ -0,0 +1,33 @@
+# == Schema Information
+#
+# Table name: university_person_experiences
+#
+#  id              :uuid             not null, primary key
+#  description     :text
+#  from_year       :integer
+#  to_year         :integer
+#  created_at      :datetime         not null
+#  updated_at      :datetime         not null
+#  organization_id :uuid             not null, indexed
+#  person_id       :uuid             not null, indexed
+#  university_id   :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_university_person_experiences_on_organization_id  (organization_id)
+#  index_university_person_experiences_on_person_id        (person_id)
+#  index_university_person_experiences_on_university_id    (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_18125d90df  (person_id => university_people.id)
+#  fk_rails_38aaa18a3b  (organization_id => university_organizations.id)
+#  fk_rails_923d0b71fd  (university_id => universities.id)
+#
+
+default_experience:
+  from_year: 2022
+  to_year: 2023
+  person: alumnus
+  organization: default_organization
+  university: default_university
\ No newline at end of file
diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a830b4a709a9983cab0485b93ac91578d7508d7e
--- /dev/null
+++ b/test/fixtures/users.yml
@@ -0,0 +1,84 @@
+# == Schema Information
+#
+# Table name: users
+#
+#  id                            :uuid             not null, primary key
+#  admin_theme                   :integer          default("appstack")
+#  confirmation_sent_at          :datetime
+#  confirmation_token            :string           indexed
+#  confirmed_at                  :datetime
+#  current_sign_in_at            :datetime
+#  current_sign_in_ip            :string
+#  direct_otp                    :string
+#  direct_otp_delivery_method    :string
+#  direct_otp_sent_at            :datetime
+#  email                         :string           default(""), not null, indexed => [university_id]
+#  encrypted_otp_secret_key      :string           indexed
+#  encrypted_otp_secret_key_iv   :string
+#  encrypted_otp_secret_key_salt :string
+#  encrypted_password            :string           default(""), not null
+#  failed_attempts               :integer          default(0), not null
+#  first_name                    :string
+#  last_name                     :string
+#  last_sign_in_at               :datetime
+#  last_sign_in_ip               :string
+#  locked_at                     :datetime
+#  mobile_phone                  :string
+#  picture_url                   :string
+#  remember_created_at           :datetime
+#  reset_password_sent_at        :datetime
+#  reset_password_token          :string           indexed
+#  role                          :integer          default("visitor")
+#  second_factor_attempts_count  :integer          default(0)
+#  session_token                 :string
+#  sign_in_count                 :integer          default(0), not null
+#  totp_timestamp                :datetime
+#  unconfirmed_email             :string
+#  unlock_token                  :string           indexed
+#  created_at                    :datetime         not null
+#  updated_at                    :datetime         not null
+#  language_id                   :uuid             indexed
+#  university_id                 :uuid             not null, indexed => [email], indexed
+#
+# Indexes
+#
+#  index_users_on_confirmation_token        (confirmation_token) UNIQUE
+#  index_users_on_email_and_university_id   (email,university_id) UNIQUE
+#  index_users_on_encrypted_otp_secret_key  (encrypted_otp_secret_key) UNIQUE
+#  index_users_on_language_id               (language_id)
+#  index_users_on_reset_password_token      (reset_password_token) UNIQUE
+#  index_users_on_university_id             (university_id)
+#  index_users_on_unlock_token              (unlock_token) UNIQUE
+#
+# Foreign Keys
+#
+#  fk_rails_45f4f12508  (language_id => languages.id)
+#  fk_rails_bd6f7212a9  (university_id => universities.id)
+#
+
+alumnus:
+  confirmed_at: <%= Time.zone.now %>
+  email: alumnus@osuny.org
+  first_name: Alumnus
+  last_name: Osuny
+  role: user
+  language: fr
+  university: default_university
+
+admin:
+  confirmed_at: <%= Time.zone.now %>
+  email: admin@osuny.org
+  first_name: Admin
+  last_name: Osuny
+  role: admin
+  language: fr
+  university: default_university
+
+server_admin:
+  confirmed_at: <%= Time.zone.now %>
+  email: serveradmin@osuny.org
+  first_name: Server Admin
+  last_name: Osuny
+  role: server_admin
+  language: fr
+  university: default_university
\ No newline at end of file
diff --git a/test/models/research/journal/paper/kind_test.rb b/test/models/research/journal/paper/kind_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3eed2b6d5f60b69c6b9c22bbb82f9babf565049d
--- /dev/null
+++ b/test/models/research/journal/paper/kind_test.rb
@@ -0,0 +1,29 @@
+# == Schema Information
+#
+# Table name: research_journal_paper_kinds
+#
+#  id            :uuid             not null, primary key
+#  slug          :string
+#  title         :string
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  journal_id    :uuid             not null, indexed
+#  university_id :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_research_journal_paper_kinds_on_journal_id     (journal_id)
+#  index_research_journal_paper_kinds_on_university_id  (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_57217513c3  (journal_id => research_journals.id)
+#  fk_rails_8e6f992b9d  (university_id => universities.id)
+#
+require "test_helper"
+
+class Research::Journal::Paper::KindTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end
diff --git a/test/support/extranet_setup.rb b/test/support/extranet_setup.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0f3a7ec06d1fce34139b13fc6da40eaa9ea92675
--- /dev/null
+++ b/test/support/extranet_setup.rb
@@ -0,0 +1,6 @@
+module ExtranetSetup
+  def setup
+    host! default_extranet.host
+    sign_in_with_2fa(alumnus)
+  end
+end
\ No newline at end of file
diff --git a/test/support/server_setup.rb b/test/support/server_setup.rb
new file mode 100644
index 0000000000000000000000000000000000000000..288d3d376695ad39911a254668b26454c0f95a54
--- /dev/null
+++ b/test/support/server_setup.rb
@@ -0,0 +1,5 @@
+module ServerSetup
+  def setup
+    sign_in_with_2fa(server_admin)
+  end
+end
\ No newline at end of file
diff --git a/test/system/research/journal/paper/kinds_test.rb b/test/system/research/journal/paper/kinds_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2eb2ed93afebc9e1563501f00f548bbfbb27c50a
--- /dev/null
+++ b/test/system/research/journal/paper/kinds_test.rb
@@ -0,0 +1,43 @@
+require "application_system_test_case"
+
+class Research::Journal::Paper::KindsTest < ApplicationSystemTestCase
+  setup do
+    @research_journal_paper_kind = research_journal_paper_kinds(:one)
+  end
+
+  test "visiting the index" do
+    visit research_journal_paper_kinds_url
+    assert_selector "h1", text: "Kinds"
+  end
+
+  test "should create kind" do
+    visit research_journal_paper_kinds_url
+    click_on "New kind"
+
+    fill_in "Slug", with: @research_journal_paper_kind.slug
+    fill_in "Title", with: @research_journal_paper_kind.title
+    click_on "Create Kind"
+
+    assert_text "Kind was successfully created"
+    click_on "Back"
+  end
+
+  test "should update Kind" do
+    visit research_journal_paper_kind_url(@research_journal_paper_kind)
+    click_on "Edit this kind", match: :first
+
+    fill_in "Slug", with: @research_journal_paper_kind.slug
+    fill_in "Title", with: @research_journal_paper_kind.title
+    click_on "Update Kind"
+
+    assert_text "Kind was successfully updated"
+    click_on "Back"
+  end
+
+  test "should destroy Kind" do
+    visit research_journal_paper_kind_url(@research_journal_paper_kind)
+    click_on "Destroy this kind", match: :first
+
+    assert_text "Kind was successfully destroyed"
+  end
+end
diff --git a/test/system/university/organizations_test.rb b/test/system/university/organizations_test.rb
index f97585ce0389365f13ae117ec3529078c0e39ba4..d31d32daf930c17a5a0318115c369748534cb60a 100644
--- a/test/system/university/organizations_test.rb
+++ b/test/system/university/organizations_test.rb
@@ -2,7 +2,7 @@ require "application_system_test_case"
 
 class University::OrganizationsTest < ApplicationSystemTestCase
   setup do
-    @university_organization = university_organizations(:one)
+    @university_organization = university_organizations(:default_organization)
   end
 
   test "visiting the index" do
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 35caf45857176187fc4d21786fb9eac41bda08c2..8994704e482e6be7fa71977353992da4e3f4af46 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -8,6 +8,37 @@ require "rails/test_help"
 Dir["./test/support/**/*.rb"].each { |f| require f }
 
 class ActiveSupport::TestCase
-  parallelize(workers: :number_of_processors)
+  include Devise::Test::IntegrationHelpers
+  include TwoFactorAuthentication::Test::IntegrationHelpers
+
   fixtures :all
+
+  setup do
+    ENV.update(ENV.to_h.merge('APPLICATION_ENV' => 'test'))
+    try(:host!, default_university.host)
+  end
+
+  def default_university
+    @default_university ||= universities(:default_university)
+  end
+
+  def default_extranet
+    @default_extranet ||= communication_extranets(:default_extranet)
+  end
+
+  def alumnus
+    @alumnus ||= users(:alumnus)
+  end
+
+  def alumnus_person
+    @alumnus_person ||= university_people(:alumnus)
+  end
+
+  def admin
+    @admin ||= users(:admin)
+  end
+
+  def server_admin
+    @server_admin ||= users(:server_admin)
+  end
 end