diff --git a/app/controllers/admin/research/application_controller.rb b/app/controllers/admin/research/application_controller.rb
index 438eafb32ce50d10cbe3e8fdcad708068b161555..181ceaa185af59ab1dc650034edbee62ee94bbd5 100644
--- a/app/controllers/admin/research/application_controller.rb
+++ b/app/controllers/admin/research/application_controller.rb
@@ -6,6 +6,9 @@ class Admin::Research::ApplicationController < Admin::ApplicationController
     if @journal
       short_breadcrumb
       breadcrumb_for @journal
+    elsif @laboratory
+      short_breadcrumb
+      breadcrumb_for @laboratory
     else
       super
       add_breadcrumb Research.model_name.human
diff --git a/app/controllers/admin/research/laboratories_controller.rb b/app/controllers/admin/research/laboratories_controller.rb
index 58f78a82af8488e3ee2f3fb9c07fc7455248b52d..49cb0d3f3a2b5a590c2f026fe69efeb25128634f 100644
--- a/app/controllers/admin/research/laboratories_controller.rb
+++ b/app/controllers/admin/research/laboratories_controller.rb
@@ -6,9 +6,11 @@ class Admin::Research::LaboratoriesController < Admin::Research::ApplicationCont
   def index
     @laboratories = @laboratories.ordered.page(params[:page])
     breadcrumb
+    add_breadcrumb Research::Laboratory.model_name.human(count: 2), admin_research_laboratories_path
   end
 
   def show
+    @axes = @laboratory.axes.ordered
     breadcrumb
   end
 
@@ -52,11 +54,4 @@ class Admin::Research::LaboratoriesController < Admin::Research::ApplicationCont
           .permit(:name, :address, :zipcode, :city, :country)
           .merge(university_id: current_university.id)
   end
-
-  def breadcrumb
-    super
-    add_breadcrumb Research::Laboratory.model_name.human(count: 2),
-                   admin_research_laboratories_path
-    breadcrumb_for @laboratory
-  end
 end
diff --git a/app/controllers/admin/research/laboratory/application_controller.rb b/app/controllers/admin/research/laboratory/application_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a43dc2d32f33bd9a68f99c258ee09b3d7830bcb0
--- /dev/null
+++ b/app/controllers/admin/research/laboratory/application_controller.rb
@@ -0,0 +1,15 @@
+class Admin::Research::Laboratory::ApplicationController < Admin::Research::ApplicationController
+  load_and_authorize_resource :laboratory,
+                              class: Research::Laboratory,
+                              through: :current_university,
+                              through_association: :research_laboratories
+
+  protected
+
+  def default_url_options
+    return {} unless params.has_key? :laboratory_id
+    {
+      laboratory_id: params[:laboratory_id]
+    }
+  end
+end
diff --git a/app/controllers/admin/research/laboratory/axes_controller.rb b/app/controllers/admin/research/laboratory/axes_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4405e1334becc3774ecaa91c0b18be9ad14be9e9
--- /dev/null
+++ b/app/controllers/admin/research/laboratory/axes_controller.rb
@@ -0,0 +1,61 @@
+class Admin::Research::Laboratory::AxesController < Admin::Research::Laboratory::ApplicationController
+  load_and_authorize_resource class: Research::Laboratory::Axis, through: :laboratory
+
+  include Admin::Reorderable
+
+  def index
+    breadcrumb
+  end
+
+  def show
+    breadcrumb
+  end
+
+  def new
+    breadcrumb
+  end
+
+  def edit
+    breadcrumb
+    add_breadcrumb t('edit')
+  end
+
+  def create
+    @axis.laboratory = @laboratory
+    if @axis.save
+      redirect_to admin_research_laboratory_axis_path(@axis), notice: t('admin.successfully_created_html', model: @axis.to_s)
+    else
+      breadcrumb
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @axis.update(axis_params)
+      redirect_to admin_research_laboratory_axis_path(@axis), notice: t('admin.successfully_updated_html', model: @axis.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('edit')
+      render :edit, status: :unprocessable_entity
+  end
+  end
+
+  def destroy
+    @axis.destroy
+    redirect_to admin_research_laboratory_path(@laboratory), notice: t('admin.successfully_destroyed_html', model: @axis.to_s)
+  end
+
+  private
+
+  def breadcrumb
+    super
+    add_breadcrumb Research::Laboratory::Axis.model_name.human(count: 2), admin_research_laboratory_axes_path
+    breadcrumb_for @axis
+  end
+
+  def axis_params
+    params.require(:research_laboratory_axis)
+          .permit(:name, :description, :text)
+          .merge(university_id: current_university.id)
+  end
+end
diff --git a/app/controllers/admin/research/theses_controller.rb b/app/controllers/admin/research/theses_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..114e1238eaa8678df4aad233399a57df836acf4c
--- /dev/null
+++ b/app/controllers/admin/research/theses_controller.rb
@@ -0,0 +1,62 @@
+class Admin::Research::ThesesController < Admin::Research::ApplicationController
+  load_and_authorize_resource class: Research::Thesis,
+                              through: :current_university,
+                              through_association: :research_theses
+
+  def index
+    @theses = @theses.ordered.page(params[:page])
+    breadcrumb
+  end
+
+  def show
+    breadcrumb
+  end
+
+  def new
+    breadcrumb
+  end
+
+  def edit
+    breadcrumb
+    add_breadcrumb t('edit')
+  end
+
+  def create
+    if @thesis.save
+      redirect_to [:admin, @thesis], notice: t('admin.successfully_created_html', model: @thesis.to_s)
+    else
+      breadcrumb
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @thesis.update(thesis_params)
+      redirect_to [:admin, @thesis], notice: t('admin.successfully_updated_html', model: @thesis.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('edit')
+      render :edit, status: :unprocessable_entity
+    end
+  end
+
+  def destroy
+    @thesis.destroy
+    redirect_to admin_research_theses_url, notice: t('admin.successfully_destroyed_html', model: @thesis.to_s)
+  end
+
+  protected
+
+  def thesis_params
+    params.require(:research_thesis).permit(
+      :title, :abstract, :started_at, :completed, :completed_at,
+      :research_laboratory_id, :author_id, :director_id
+    ).merge(university_id: current_university.id)
+  end
+
+  def breadcrumb
+    super
+    add_breadcrumb Research::Thesis.model_name.human(count: 2), admin_research_theses_path
+    breadcrumb_for @thesis
+  end
+end
diff --git a/app/models/research/laboratory.rb b/app/models/research/laboratory.rb
index f81db88aebd7b7db8827609ec0d3a3ca7a2dd22d..89574a529eb03fe1d126dd2a86ea1624290ef545 100644
--- a/app/models/research/laboratory.rb
+++ b/app/models/research/laboratory.rb
@@ -23,7 +23,11 @@
 class Research::Laboratory < ApplicationRecord
   include WithGit
 
-  belongs_to :university
+  belongs_to  :university
+  has_many    :axes,
+              class_name: "Research::Laboratory::Axis",
+              foreign_key: :research_laboratory_id,
+              dependent: :destroy
 
   scope :ordered, -> { order(:name) }
 
diff --git a/app/models/research/laboratory/axis.rb b/app/models/research/laboratory/axis.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6d8a63d94b6b64cd84251501e12d0980a4603e48
--- /dev/null
+++ b/app/models/research/laboratory/axis.rb
@@ -0,0 +1,44 @@
+# == Schema Information
+#
+# Table name: research_laboratory_axes
+#
+#  id                     :uuid             not null, primary key
+#  description            :text
+#  name                   :string
+#  position               :integer
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+#  research_laboratory_id :uuid             not null
+#  university_id          :uuid             not null
+#
+# Indexes
+#
+#  index_research_laboratory_axes_on_research_laboratory_id  (research_laboratory_id)
+#  index_research_laboratory_axes_on_university_id           (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (research_laboratory_id => research_laboratories.id)
+#  fk_rails_...  (university_id => universities.id)
+#
+class Research::Laboratory::Axis < ApplicationRecord
+  include WithPosition
+
+  has_rich_text :text
+
+  belongs_to :university
+  belongs_to :laboratory, foreign_key: :research_laboratory_id
+
+  def to_s
+    "#{name}"
+  end
+
+  protected
+
+  def last_ordered_element
+    Research::Laboratory::Axis.where(
+      university_id: university_id,
+      research_laboratory_id: research_laboratory_id
+    ).ordered.last
+  end
+end
diff --git a/app/models/research/thesis.rb b/app/models/research/thesis.rb
new file mode 100644
index 0000000000000000000000000000000000000000..739ba8ecc3b3756ea374b9187b530898a5318019
--- /dev/null
+++ b/app/models/research/thesis.rb
@@ -0,0 +1,43 @@
+# == Schema Information
+#
+# Table name: research_theses
+#
+#  id                     :uuid             not null, primary key
+#  abstract               :text
+#  completed              :boolean          default(FALSE)
+#  completed_at           :date
+#  started_at             :date
+#  title                  :string
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+#  author_id              :uuid             not null
+#  director_id            :uuid             not null
+#  research_laboratory_id :uuid             not null
+#  university_id          :uuid             not null
+#
+# Indexes
+#
+#  index_research_theses_on_author_id               (author_id)
+#  index_research_theses_on_director_id             (director_id)
+#  index_research_theses_on_research_laboratory_id  (research_laboratory_id)
+#  index_research_theses_on_university_id           (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (author_id => university_people.id)
+#  fk_rails_...  (director_id => university_people.id)
+#  fk_rails_...  (research_laboratory_id => research_laboratories.id)
+#  fk_rails_...  (university_id => universities.id)
+#
+class Research::Thesis < ApplicationRecord
+  belongs_to :university
+  belongs_to :laboratory, foreign_key: :research_laboratory_id
+  belongs_to :author, class_name: 'University::Person'
+  belongs_to :director, class_name: 'University::Person'
+
+  scope :ordered, -> { order(:title) }
+
+  def to_s
+    "#{title}"
+  end
+end
diff --git a/app/models/university/with_research.rb b/app/models/university/with_research.rb
index 9dc0565a2289676c122add9f7ecc251ed03ba4cd..7169a92242738687ef2d4ceb79eeda5846355ca2 100644
--- a/app/models/university/with_research.rb
+++ b/app/models/university/with_research.rb
@@ -2,7 +2,8 @@ module University::WithResearch
   extend ActiveSupport::Concern
 
   included do
-    has_many :research_laboratories, class_name: 'Research::Laboratory', dependent: :destroy
     has_many :research_journals, class_name: 'Research::Journal', dependent: :destroy
+    has_many :research_laboratories, class_name: 'Research::Laboratory', dependent: :destroy
+    has_many :research_theses, class_name: 'Research::Thesis', dependent: :destroy
   end
 end
diff --git a/app/views/admin/research/laboratories/show.html.erb b/app/views/admin/research/laboratories/show.html.erb
index b10698500adfa827a24c08c6accef3205535f929..1dc1c44b0d3e2107d47280853b82af91de13b7a2 100644
--- a/app/views/admin/research/laboratories/show.html.erb
+++ b/app/views/admin/research/laboratories/show.html.erb
@@ -1,5 +1,19 @@
 <% content_for :title, @laboratory %>
 
+<div class="card mt-5">
+  <div class="card-header">
+    <div class="float-end">
+      <%= link_to t('create'),
+                  new_admin_research_laboratory_axis_path(laboratory_id: @laboratory),
+                  class: button_classes %>
+    </div>
+    <h2 class="card-title">
+      <%= link_to Research::Laboratory::Axis.model_name.human(count: 2),
+                  admin_research_laboratory_axes_path(laboratory_id: @laboratory) %></h2>
+  </div>
+  <%= render 'admin/research/laboratory/axes/list', axes: @axes %>
+</div>
+
 <% content_for :action_bar_right do %>
   <%= edit_link @laboratory %>
 <% end %>
diff --git a/app/views/admin/research/laboratory/axes/_form.html.erb b/app/views/admin/research/laboratory/axes/_form.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..90a3730ae806d44e57b2f9ebc255d95561ba2d0c
--- /dev/null
+++ b/app/views/admin/research/laboratory/axes/_form.html.erb
@@ -0,0 +1,19 @@
+<%= simple_form_for [:admin, axis] do |f| %>
+  <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 :name %>
+          <%= f.input :description, as: :text, input_html: { rows: 8 } %>
+          <%= f.input :text, as: :rich_text_area %>
+        </div>
+      </div>
+    </div>
+  </div>
+  <% content_for :action_bar_right do %>
+    <%= submit f %>
+  <% end %>
+<% end %>
diff --git a/app/views/admin/research/laboratory/axes/_list.html.erb b/app/views/admin/research/laboratory/axes/_list.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..659fe3fa89253a778d81e7b3244b073c6c48f48a
--- /dev/null
+++ b/app/views/admin/research/laboratory/axes/_list.html.erb
@@ -0,0 +1,29 @@
+<table class="table table-sortable">
+  <thead>
+    <tr>
+      <th><%= Research::Laboratory::Axis.model_name.human %></th>
+      <th></th>
+    </tr>
+  </thead>
+  <tbody data-reorder-url="<%= reorder_admin_research_laboratory_axes_path(laboratory_id: @laboratory.id) %>">
+    <% axes.each do |axis| %>
+      <tr class="handle" data-id="<%= axis.id %>">
+        <td>
+          <%= link_to axis, admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis) %>
+        </td>
+        <td class="text-end">
+          <div class="btn-group" role="group">
+            <%= link_to t('edit'),
+                        edit_admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis),
+                        class: button_classes %>
+            <%= link_to t('delete'),
+                        admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis),
+                        method: :delete,
+                        data: { confirm: t('please_confirm') },
+                        class: button_classes_danger %>
+          </div>
+        </td>
+      </tr>
+    <% end %>
+  </tbody>
+</table>
diff --git a/app/views/admin/research/laboratory/axes/edit.html.erb b/app/views/admin/research/laboratory/axes/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..078bcc9a159d0f1510828a03b0073449e35cce37
--- /dev/null
+++ b/app/views/admin/research/laboratory/axes/edit.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @axis %>
+
+<%= render 'form', axis: @axis %>
diff --git a/app/views/admin/research/laboratory/axes/index.html.erb b/app/views/admin/research/laboratory/axes/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..dfe60dc90513a75553c2ee3b201d0eabbfe65b02
--- /dev/null
+++ b/app/views/admin/research/laboratory/axes/index.html.erb
@@ -0,0 +1,7 @@
+<% content_for :title, Research::Laboratory::Axis.model_name.human(count: 2) %>
+
+<%= render 'admin/research/laboratory/axes/list', axes: @axes %>
+
+<% content_for :action_bar_right do %>
+  <%= create_link Research::Laboratory::Axis %>
+<% end %>
diff --git a/app/views/admin/research/laboratory/axes/new.html.erb b/app/views/admin/research/laboratory/axes/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..efb0a6c26d509ca7262aa0d111f9d94b148e6cef
--- /dev/null
+++ b/app/views/admin/research/laboratory/axes/new.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, Research::Laboratory::Axis.model_name.human %>
+
+<%= render 'form', axis: @axis %>
diff --git a/app/views/admin/research/laboratory/axes/show.html.erb b/app/views/admin/research/laboratory/axes/show.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..fe8467edb0297e386bd7f721231dfdf0d02bc421
--- /dev/null
+++ b/app/views/admin/research/laboratory/axes/show.html.erb
@@ -0,0 +1,21 @@
+<% content_for :title, @axis %>
+
+<div class="row">
+  <div class="col-md-8">
+    <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">
+        <h3 class="h5"><%= Research::Laboratory::Axis.human_attribute_name('description') %></h3>
+        <%= simple_format @axis.description %>
+        <h3 class="h5 mt-4"><%= Research::Laboratory::Axis.human_attribute_name('text') %></h3>
+        <%= @axis.text %>
+      </div>
+    </div>
+  </div>
+</div>
+
+<% content_for :action_bar_right do %>
+  <%= edit_link @axis %>
+<% end %>
diff --git a/app/views/admin/research/theses/_form.html.erb b/app/views/admin/research/theses/_form.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..91747995912a496694435b47e3f0f8d0699f63a8
--- /dev/null
+++ b/app/views/admin/research/theses/_form.html.erb
@@ -0,0 +1,24 @@
+<%= simple_form_for [:admin, thesis] do |f| %>
+  <div class="row">
+    <div class="col-md-6">
+      <div class="card flex-fill w-100">
+        <div class="card-body">
+          <%= f.input :title %>
+          <%= f.input :abstract %>
+          <%= f.input :started_at, html5: true %>
+          <%= f.input :completed %>
+          <%= f.input :completed_at, html5: true %>
+          <%= f.association :laboratory,
+                            collection: current_university.research_laboratories.ordered %>
+          <%= f.association :author,
+                            collection: current_university.people.researchers.ordered %>
+          <%= f.association :director,
+                            collection: current_university.people.researchers.ordered %>
+        </div>
+      </div>
+    </div>
+  </div>
+  <% content_for :action_bar_right do %>
+    <%= submit f %>
+  <% end %>
+<% end %>
diff --git a/app/views/admin/research/theses/edit.html.erb b/app/views/admin/research/theses/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..705cd0c8386950222317cce22da1023bef11f8f6
--- /dev/null
+++ b/app/views/admin/research/theses/edit.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @thesis %>
+
+<%= render 'form', thesis: @thesis %>
diff --git a/app/views/admin/research/theses/index.html.erb b/app/views/admin/research/theses/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..bba33c839d94a9d02684d5a30273044b7d3d78ab
--- /dev/null
+++ b/app/views/admin/research/theses/index.html.erb
@@ -0,0 +1,30 @@
+<% content_for :title, Research::Thesis.model_name.human(count: 2) %>
+
+<table class="table">
+  <thead>
+    <tr>
+      <th><%= Research::Thesis.human_attribute_name('title') %></th>
+      <th></th>
+    </tr>
+  </thead>
+
+  <tbody>
+    <% @theses.each do |thesis| %>
+      <tr>
+        <td><%= link_to thesis, [:admin, thesis] %></td>
+        <td class="text-end">
+          <div class="btn-group" role="group">
+            <%= edit_link thesis %>
+            <%= destroy_link thesis %>
+          </div>
+        </td>
+      </tr>
+    <% end %>
+  </tbody>
+</table>
+<%= paginate @theses, theme: 'bootstrap-5' %>
+
+
+<% content_for :action_bar_right do %>
+  <%= create_link Research::Thesis %>
+<% end %>
diff --git a/app/views/admin/research/theses/new.html.erb b/app/views/admin/research/theses/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..8875117bdcbf7abc2ed9cded83a17f85dfcac4ae
--- /dev/null
+++ b/app/views/admin/research/theses/new.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, Research::Thesis.model_name.human %>
+
+<%= render 'form', thesis: @thesis %>
diff --git a/app/views/admin/research/theses/show.html.erb b/app/views/admin/research/theses/show.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b8d8ef53c9aeefdad2e106affc0163fda655e268
--- /dev/null
+++ b/app/views/admin/research/theses/show.html.erb
@@ -0,0 +1,5 @@
+<% content_for :title, @thesis %>
+
+<% content_for :action_bar_right do %>
+  <%= edit_link @thesis %>
+<% end %>
diff --git a/config/admin_navigation.rb b/config/admin_navigation.rb
index 7b273cad7c93cda518943d2877a3dd422ad1eeac..7ba64197bcf9f76bc0316eacd6f706ae5d98180d 100644
--- a/config/admin_navigation.rb
+++ b/config/admin_navigation.rb
@@ -24,6 +24,7 @@ SimpleNavigation::Configuration.run do |navigation|
       primary.item :research, Research.model_name.human, nil, { kind: :header }
       primary.item :research_researchers, t('research.researchers', count: 2), admin_research_researchers_path(journal_id: nil), { icon: 'microscope' } if can?(:read, University::Person)
       primary.item :research_laboratories, Research::Laboratory.model_name.human(count: 2), admin_research_laboratories_path, { icon: 'flask' } if can?(:read, Research::Laboratory)
+      primary.item :research_theses, Research::Thesis.model_name.human(count: 2), admin_research_theses_path, { icon: 'scroll' } if can?(:read, Research::Thesis)
       primary.item :research, 'Veille', nil, { icon: 'eye' }
       primary.item :research_journals, Research::Journal.model_name.human(count: 2), admin_research_journals_path, { icon: 'newspaper' } if can?(:read, Research::Journal)
     end
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
index ac033bf9dc846101320c96a5ce8aceb8c96ec098..2f804f76171aff60b900d7dcf71294194cfbea26 100644
--- a/config/initializers/inflections.rb
+++ b/config/initializers/inflections.rb
@@ -3,12 +3,12 @@
 # Add new inflection rules using the following format. Inflections
 # are locale specific, and you may define rules for as many different
 # locales as you wish. All of these examples are active by default:
-# ActiveSupport::Inflector.inflections(:en) do |inflect|
-#   inflect.plural /^(ox)$/i, '\1en'
-#   inflect.singular /^(ox)en/i, '\1'
-#   inflect.irregular 'person', 'people'
-#   inflect.uncountable %w( fish sheep )
-# end
+ActiveSupport::Inflector.inflections(:en) do |inflect|
+  # inflect.plural /^(ox)$/i, '\1en'
+  # inflect.singular /^(ox)en/i, '\1'
+  # inflect.uncountable %w( fish sheep )
+  inflect.irregular 'axis', 'axes'
+end
 
 # These inflection rules are supported but not enabled by default:
 # ActiveSupport::Inflector.inflections(:en) do |inflect|
diff --git a/config/locales/research/en.yml b/config/locales/research/en.yml
index b5396fc33657fdf3923880b4b91070f6ba026c68..a19815bd57fd0b42c7944c2acbfdef500cc844e7 100644
--- a/config/locales/research/en.yml
+++ b/config/locales/research/en.yml
@@ -16,6 +16,12 @@ en:
       research/laboratory:
         one: Laboratory
         other: Laboratories
+      research/laboratory/axis:
+        one: Axis
+        other: Axes
+      research/thesis:
+        one: Thesis
+        other: Theses
     attributes:
       research/journal:
         issn: ISSN
@@ -45,6 +51,19 @@ en:
         city: City
         name: Name
         zipcode: Zipcode
+      research/laboratory/axis:
+        description: Description
+        name: Name
+        text: Text
+      research/thesis:
+        abstract: Abstract
+        author: Author
+        completed: Completed?
+        completed_at: Completed at
+        director: Director
+        laboratory: Laboratory
+        started_at: Started at
+        title: Title
   research:
     manage_researchers: Managege researchers
     number_of_articles: Number of articles
diff --git a/config/locales/research/fr.yml b/config/locales/research/fr.yml
index 7035ea43220976e2145c377484312dffb26cff87..926719c2219f03232241e942207b067689e592f7 100644
--- a/config/locales/research/fr.yml
+++ b/config/locales/research/fr.yml
@@ -16,6 +16,12 @@ fr:
       research/laboratory:
         one: Laboratoire
         other: Laboratoires
+      research/laboratory/axis:
+        one: Axe
+        other: Axes
+      research/thesis:
+        one: Thèse
+        other: Thèses
     attributes:
       research/journal:
         issn: ISSN
@@ -45,6 +51,19 @@ fr:
         city: Ville
         name: Nom
         zipcode: Code postal
+      research/laboratory/axis:
+        description: Description
+        name: Nom
+        text: Texte
+      research/thesis:
+        abstract: Résumé
+        author: Auteur·rice
+        completed: Complétée ?
+        completed_at: Complétée le
+        director: Directeur·rice
+        laboratory: Laboratoire
+        started_at: Commencée le
+        title: Titre
   research:
     manage_researchers: Gérer les Chercheu·rs·ses
     number_of_articles: Nombre d'articles
diff --git a/config/routes/admin/research.rb b/config/routes/admin/research.rb
index e8bdb55df2a66a57af75989b652a4bee34de84f4..3557586e7b881e7472eedcdbf1ba1ecd461bc3fc 100644
--- a/config/routes/admin/research.rb
+++ b/config/routes/admin/research.rb
@@ -8,5 +8,12 @@ namespace :research do
       end
     end
   end
-  resources :laboratories
+  resources :laboratories do
+    resources :axes, controller: 'laboratory/axes' do
+      collection do
+        post :reorder
+      end
+    end
+  end
+  resources :theses
 end
diff --git a/db/migrate/20220119174230_create_research_laboratory_axes.rb b/db/migrate/20220119174230_create_research_laboratory_axes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8be8ac682a7faeff7db11c339921160c98948112
--- /dev/null
+++ b/db/migrate/20220119174230_create_research_laboratory_axes.rb
@@ -0,0 +1,13 @@
+class CreateResearchLaboratoryAxes < ActiveRecord::Migration[6.1]
+  def change
+    create_table :research_laboratory_axes, id: :uuid do |t|
+      t.references :university, null: false, foreign_key: true, type: :uuid
+      t.references :research_laboratory, null: false, foreign_key: true, type: :uuid
+      t.string :name
+      t.text :description
+      t.integer :position
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20220120111315_create_research_theses.rb b/db/migrate/20220120111315_create_research_theses.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5d099f1dad7fee5344de0f8b925b5225f938acb9
--- /dev/null
+++ b/db/migrate/20220120111315_create_research_theses.rb
@@ -0,0 +1,17 @@
+class CreateResearchTheses < ActiveRecord::Migration[6.1]
+  def change
+    create_table :research_theses, id: :uuid do |t|
+      t.references :university, null: false, foreign_key: true, type: :uuid
+      t.references :research_laboratory, null: false, foreign_key: true, type: :uuid
+      t.references :author, null: false, foreign_key: { to_table: :university_people }, type: :uuid
+      t.references :director, null: false, foreign_key: { to_table: :university_people }, type: :uuid
+      t.string :title
+      t.text :abstract
+      t.date :started_at
+      t.boolean :completed, default: false
+      t.date :completed_at
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4c661a49e80694af57bac72d46ec6b16ed66bf2c..4e703ecb111faf7cb87e7c38c4c0afdb4f06ade3 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.define(version: 2022_01_19_164036) do
+ActiveRecord::Schema.define(version: 2022_01_20_111315) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -511,6 +511,36 @@ ActiveRecord::Schema.define(version: 2022_01_19_164036) do
     t.index ["university_id"], name: "index_research_laboratories_on_university_id"
   end
 
+  create_table "research_laboratory_axes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.uuid "university_id", null: false
+    t.uuid "research_laboratory_id", null: false
+    t.string "name"
+    t.text "description"
+    t.integer "position"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["research_laboratory_id"], name: "index_research_laboratory_axes_on_research_laboratory_id"
+    t.index ["university_id"], name: "index_research_laboratory_axes_on_university_id"
+  end
+
+  create_table "research_theses", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.uuid "university_id", null: false
+    t.uuid "research_laboratory_id", null: false
+    t.uuid "author_id", null: false
+    t.uuid "director_id", null: false
+    t.string "title"
+    t.text "abstract"
+    t.date "started_at"
+    t.boolean "completed", default: false
+    t.date "completed_at"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["author_id"], name: "index_research_theses_on_author_id"
+    t.index ["director_id"], name: "index_research_theses_on_director_id"
+    t.index ["research_laboratory_id"], name: "index_research_theses_on_research_laboratory_id"
+    t.index ["university_id"], name: "index_research_theses_on_university_id"
+  end
+
   create_table "universities", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.string "name"
     t.string "identifier"
@@ -652,6 +682,12 @@ ActiveRecord::Schema.define(version: 2022_01_19_164036) do
   add_foreign_key "research_journal_volumes", "universities"
   add_foreign_key "research_journals", "universities"
   add_foreign_key "research_laboratories", "universities"
+  add_foreign_key "research_laboratory_axes", "research_laboratories"
+  add_foreign_key "research_laboratory_axes", "universities"
+  add_foreign_key "research_theses", "research_laboratories"
+  add_foreign_key "research_theses", "universities"
+  add_foreign_key "research_theses", "university_people", column: "author_id"
+  add_foreign_key "research_theses", "university_people", column: "director_id"
   add_foreign_key "university_people", "universities"
   add_foreign_key "university_people", "users"
   add_foreign_key "users", "languages"
diff --git a/test/fixtures/research/laboratories.yml b/test/fixtures/research/laboratories.yml
index e39ae63490bbdf89ba4879257c1a3b623b33e595..ced250caf792e144439fafa9ff141e6cfcaeb4fd 100644
--- a/test/fixtures/research/laboratories.yml
+++ b/test/fixtures/research/laboratories.yml
@@ -20,7 +20,6 @@
 #
 #  fk_rails_...  (university_id => universities.id)
 #
-# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
 
 one:
   university: one
diff --git a/test/fixtures/research/laboratory/axes.yml b/test/fixtures/research/laboratory/axes.yml
new file mode 100644
index 0000000000000000000000000000000000000000..15041de82fbb748805e3c18296ce133f242841d4
--- /dev/null
+++ b/test/fixtures/research/laboratory/axes.yml
@@ -0,0 +1,37 @@
+# == Schema Information
+#
+# Table name: research_laboratory_axes
+#
+#  id                     :uuid             not null, primary key
+#  description            :text
+#  name                   :string
+#  position               :integer
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+#  research_laboratory_id :uuid             not null
+#  university_id          :uuid             not null
+#
+# Indexes
+#
+#  index_research_laboratory_axes_on_research_laboratory_id  (research_laboratory_id)
+#  index_research_laboratory_axes_on_university_id           (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (research_laboratory_id => research_laboratories.id)
+#  fk_rails_...  (university_id => universities.id)
+#
+
+one:
+  university: one
+  research_laboratory: one
+  name: MyString
+  description: MyText
+  position: 1
+
+two:
+  university: two
+  research_laboratory: two
+  name: MyString
+  description: MyText
+  position: 1
diff --git a/test/fixtures/research/theses.yml b/test/fixtures/research/theses.yml
new file mode 100644
index 0000000000000000000000000000000000000000..922ad551186185fba909d504daac46b20e74989c
--- /dev/null
+++ b/test/fixtures/research/theses.yml
@@ -0,0 +1,54 @@
+# == Schema Information
+#
+# Table name: research_theses
+#
+#  id                     :uuid             not null, primary key
+#  abstract               :text
+#  completed              :boolean          default(FALSE)
+#  completed_at           :date
+#  started_at             :date
+#  title                  :string
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+#  author_id              :uuid             not null
+#  director_id            :uuid             not null
+#  research_laboratory_id :uuid             not null
+#  university_id          :uuid             not null
+#
+# Indexes
+#
+#  index_research_theses_on_author_id               (author_id)
+#  index_research_theses_on_director_id             (director_id)
+#  index_research_theses_on_research_laboratory_id  (research_laboratory_id)
+#  index_research_theses_on_university_id           (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (author_id => university_people.id)
+#  fk_rails_...  (director_id => university_people.id)
+#  fk_rails_...  (research_laboratory_id => research_laboratories.id)
+#  fk_rails_...  (university_id => universities.id)
+#
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  university: one
+  research_laboratory: one
+  author: one
+  director: one
+  title: MyString
+  abstract: MyText
+  started_at: 2022-01-20
+  completed: false
+  completed_at: 2022-01-20
+
+two:
+  university: two
+  research_laboratory: two
+  author: two
+  director: two
+  title: MyString
+  abstract: MyText
+  started_at: 2022-01-20
+  completed: false
+  completed_at: 2022-01-20
diff --git a/test/models/research/laboratory/axis_test.rb b/test/models/research/laboratory/axis_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a4228e54f88da6ffe7c98ab7f1690e6f50061fae
--- /dev/null
+++ b/test/models/research/laboratory/axis_test.rb
@@ -0,0 +1,30 @@
+# == Schema Information
+#
+# Table name: research_laboratory_axes
+#
+#  id                     :uuid             not null, primary key
+#  description            :text
+#  name                   :string
+#  position               :integer
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+#  research_laboratory_id :uuid             not null
+#  university_id          :uuid             not null
+#
+# Indexes
+#
+#  index_research_laboratory_axes_on_research_laboratory_id  (research_laboratory_id)
+#  index_research_laboratory_axes_on_university_id           (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (research_laboratory_id => research_laboratories.id)
+#  fk_rails_...  (university_id => universities.id)
+#
+require "test_helper"
+
+class Research::Laboratory::AxisTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end
diff --git a/test/models/research/thesis_test.rb b/test/models/research/thesis_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2a2b480df968b0a41b3844a5c4e6488e1894cec3
--- /dev/null
+++ b/test/models/research/thesis_test.rb
@@ -0,0 +1,38 @@
+# == Schema Information
+#
+# Table name: research_theses
+#
+#  id                     :uuid             not null, primary key
+#  abstract               :text
+#  completed              :boolean          default(FALSE)
+#  completed_at           :date
+#  started_at             :date
+#  title                  :string
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+#  author_id              :uuid             not null
+#  director_id            :uuid             not null
+#  research_laboratory_id :uuid             not null
+#  university_id          :uuid             not null
+#
+# Indexes
+#
+#  index_research_theses_on_author_id               (author_id)
+#  index_research_theses_on_director_id             (director_id)
+#  index_research_theses_on_research_laboratory_id  (research_laboratory_id)
+#  index_research_theses_on_university_id           (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (author_id => university_people.id)
+#  fk_rails_...  (director_id => university_people.id)
+#  fk_rails_...  (research_laboratory_id => research_laboratories.id)
+#  fk_rails_...  (university_id => universities.id)
+#
+require "test_helper"
+
+class Research::ThesisTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end