From e0e1cf25be171c04505f81ea5742ccd66674c603 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Wed, 5 Jan 2022 15:38:56 +0100
Subject: [PATCH] University::Person

---
 .../administration/members_controller.rb      | 63 -------------------
 .../website/authors_controller.rb             |  4 +-
 .../admin/education/teachers_controller.rb    |  6 +-
 .../admin/research/researchers_controller.rb  |  4 +-
 .../university/application_controller.rb      |  6 ++
 .../admin/university/people_controller.rb     | 63 +++++++++++++++++++
 app/models/ability.rb                         |  4 +-
 app/models/communication/website.rb           |  2 +-
 .../communication/website/imported/author.rb  |  6 +-
 .../communication/website/imported/website.rb |  6 +-
 app/models/communication/website/post.rb      |  4 +-
 .../communication/website/with_abouts.rb      |  6 +-
 app/models/education/program.rb               |  2 +-
 app/models/education/program/member.rb        |  4 +-
 app/models/research/journal/article.rb        |  2 +-
 app/models/university.rb                      |  2 +-
 .../member.rb => university/person.rb}        |  8 +--
 app/models/university/with_administration.rb  |  7 ---
 app/models/university/with_people.rb          |  7 +++
 app/models/user.rb                            |  2 +-
 .../members/_main_infos.html.erb              | 36 -----------
 .../members/administrator.html.erb            |  7 ---
 .../administration/members/author.html.erb    |  7 ---
 .../administration/members/edit.html.erb      |  3 -
 .../administration/members/index.html.erb     |  8 ---
 .../admin/administration/members/new.html.erb |  3 -
 .../members/researcher.html.erb               |  7 ---
 .../administration/members/show.html.erb      |  7 ---
 .../administration/members/static.html.erb    | 23 -------
 .../administration/members/teacher.html.erb   |  7 ---
 .../website/authors/_list.html.erb            |  4 +-
 .../website/authors/index.html.erb            |  2 +-
 .../website/authors/show.html.erb             |  2 +-
 .../website/posts/_form.html.erb              |  2 +-
 .../communication/websites/import.html.erb    |  2 +-
 .../admin/education/programs/_form.html.erb   |  6 +-
 .../admin/education/teachers/_list.html.erb   |  4 +-
 .../admin/education/teachers/index.html.erb   |  2 +-
 .../admin/education/teachers/show.html.erb    |  2 +-
 .../research/journal/articles/_form.html.erb  |  2 +-
 .../admin/research/researchers/index.html.erb |  6 +-
 .../admin/research/researchers/show.html.erb  |  2 +-
 .../people}/_form.html.erb                    |  8 +--
 .../people}/_list.html.erb                    | 14 ++---
 .../university/people/_main_infos.html.erb    | 36 +++++++++++
 .../university/people/administrator.html.erb  |  7 +++
 .../admin/university/people/author.html.erb   |  7 +++
 .../admin/university/people/edit.html.erb     |  3 +
 .../admin/university/people/index.html.erb    |  8 +++
 .../admin/university/people/new.html.erb      |  3 +
 .../university/people/researcher.html.erb     |  7 +++
 .../admin/university/people/show.html.erb     |  7 +++
 .../admin/university/people/static.html.erb   | 23 +++++++
 .../admin/university/people/teacher.html.erb  |  7 +++
 app/views/admin/users/show.html.erb           |  6 +-
 config/admin_navigation.rb                    | 12 ++--
 config/locales/administration/en.yml          | 27 --------
 config/locales/administration/fr.yml          | 27 --------
 config/locales/en.yml                         | 20 +-----
 config/locales/fr.yml                         | 20 +-----
 config/locales/university/en.yml              | 49 +++++++++++++++
 config/locales/university/fr.yml              | 49 +++++++++++++++
 config/routes.rb                              |  1 +
 config/routes/admin/administration.rb         |  2 -
 config/routes/admin/university.rb             |  3 +
 ...105135913_rename_administration_members.rb |  5 ++
 db/schema.rb                                  | 52 +++++++--------
 test/fixtures/education/program/members.yml   |  2 +-
 test/models/education/program/member_test.rb  |  2 +-
 69 files changed, 392 insertions(+), 367 deletions(-)
 delete mode 100644 app/controllers/admin/administration/members_controller.rb
 create mode 100644 app/controllers/admin/university/application_controller.rb
 create mode 100644 app/controllers/admin/university/people_controller.rb
 rename app/models/{administration/member.rb => university/person.rb} (94%)
 delete mode 100644 app/models/university/with_administration.rb
 create mode 100644 app/models/university/with_people.rb
 delete mode 100644 app/views/admin/administration/members/_main_infos.html.erb
 delete mode 100644 app/views/admin/administration/members/administrator.html.erb
 delete mode 100644 app/views/admin/administration/members/author.html.erb
 delete mode 100644 app/views/admin/administration/members/edit.html.erb
 delete mode 100644 app/views/admin/administration/members/index.html.erb
 delete mode 100644 app/views/admin/administration/members/new.html.erb
 delete mode 100644 app/views/admin/administration/members/researcher.html.erb
 delete mode 100644 app/views/admin/administration/members/show.html.erb
 delete mode 100644 app/views/admin/administration/members/static.html.erb
 delete mode 100644 app/views/admin/administration/members/teacher.html.erb
 rename app/views/admin/{administration/members => university/people}/_form.html.erb (84%)
 rename app/views/admin/{administration/members => university/people}/_list.html.erb (51%)
 create mode 100644 app/views/admin/university/people/_main_infos.html.erb
 create mode 100644 app/views/admin/university/people/administrator.html.erb
 create mode 100644 app/views/admin/university/people/author.html.erb
 create mode 100644 app/views/admin/university/people/edit.html.erb
 create mode 100644 app/views/admin/university/people/index.html.erb
 create mode 100644 app/views/admin/university/people/new.html.erb
 create mode 100644 app/views/admin/university/people/researcher.html.erb
 create mode 100644 app/views/admin/university/people/show.html.erb
 create mode 100644 app/views/admin/university/people/static.html.erb
 create mode 100644 app/views/admin/university/people/teacher.html.erb
 create mode 100644 config/locales/university/en.yml
 create mode 100644 config/locales/university/fr.yml
 create mode 100644 config/routes/admin/university.rb
 create mode 100644 db/migrate/20220105135913_rename_administration_members.rb

diff --git a/app/controllers/admin/administration/members_controller.rb b/app/controllers/admin/administration/members_controller.rb
deleted file mode 100644
index 70cb82433..000000000
--- a/app/controllers/admin/administration/members_controller.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-class Admin::Administration::MembersController < Admin::Administration::ApplicationController
-  load_and_authorize_resource class: Administration::Member,
-                              through: :current_university,
-                              through_association: :administration_members
-
-  def index
-    @members = @members.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 @member.save_and_sync
-      redirect_to admin_administration_member_path(@member), notice: t('admin.successfully_created_html', model: @member.to_s)
-    else
-      breadcrumb
-      render :new, status: :unprocessable_entity
-    end
-  end
-
-  def update
-    if @member.update_and_sync(member_params)
-      redirect_to admin_administration_member_path(@member), notice: t('admin.successfully_updated_html', model: @member.to_s)
-    else
-      breadcrumb
-      add_breadcrumb t('edit')
-      render :edit, status: :unprocessable_entity
-    end
-  end
-
-  def destroy
-    @member.destroy_and_sync
-    redirect_to admin_administration_members_url, notice: t('admin.successfully_destroyed_html', model: @member.to_s)
-  end
-
-  protected
-
-  def breadcrumb
-    super
-    add_breadcrumb  Administration::Member.model_name.human(count: 2),
-                    admin_administration_members_path
-    breadcrumb_for @member
-  end
-
-  def member_params
-    params.require(:administration_member)
-          .permit(:first_name, :last_name, :email, :phone, :biography, :slug, :user_id,
-          :is_author, :is_researcher, :is_teacher, :is_administrative)
-          .merge(university_id: current_university.id)
-  end
-end
diff --git a/app/controllers/admin/communication/website/authors_controller.rb b/app/controllers/admin/communication/website/authors_controller.rb
index bc2418e82..5f71ddf18 100644
--- a/app/controllers/admin/communication/website/authors_controller.rb
+++ b/app/controllers/admin/communication/website/authors_controller.rb
@@ -1,12 +1,12 @@
 class Admin::Communication::Website::AuthorsController < Admin::Communication::Website::ApplicationController
 
   def index
-    @authors = current_university.administration_members.authors.accessible_by(current_ability).ordered.page(params[:page])
+    @authors = current_university.people.authors.accessible_by(current_ability).ordered.page(params[:page])
     breadcrumb
   end
 
   def show
-    @author = current_university.administration_members.authors.accessible_by(current_ability).find(params[:id])
+    @author = current_university.people.authors.accessible_by(current_ability).find(params[:id])
     @posts = @author.communication_website_posts.ordered.page(params[:page])
     breadcrumb
   end
diff --git a/app/controllers/admin/education/teachers_controller.rb b/app/controllers/admin/education/teachers_controller.rb
index 34f774cd4..bf200fafe 100644
--- a/app/controllers/admin/education/teachers_controller.rb
+++ b/app/controllers/admin/education/teachers_controller.rb
@@ -2,7 +2,7 @@ class Admin::Education::TeachersController < Admin::Education::ApplicationContro
   before_action :get_teacher, except: :index
 
   def index
-    @teachers = current_university.administration_members.teachers.accessible_by(current_ability).ordered.page(params[:page])
+    @teachers = current_university.people.teachers.accessible_by(current_ability).ordered.page(params[:page])
     breadcrumb
   end
 
@@ -29,7 +29,7 @@ class Admin::Education::TeachersController < Admin::Education::ApplicationContro
   protected
 
   def get_teacher
-    @teacher = current_university.administration_members.teachers.accessible_by(current_ability).find(params[:id])
+    @teacher = current_university.people.teachers.accessible_by(current_ability).find(params[:id])
   end
 
   def breadcrumb
@@ -40,7 +40,7 @@ class Admin::Education::TeachersController < Admin::Education::ApplicationContro
   end
 
   def teacher_params
-    params.require(:administration_member)
+    params.require(:university_person)
           .permit(education_program_ids: [])
   end
 end
diff --git a/app/controllers/admin/research/researchers_controller.rb b/app/controllers/admin/research/researchers_controller.rb
index e6a11401c..c8f7efb73 100644
--- a/app/controllers/admin/research/researchers_controller.rb
+++ b/app/controllers/admin/research/researchers_controller.rb
@@ -1,12 +1,12 @@
 class Admin::Research::ResearchersController < Admin::Research::ApplicationController
 
   def index
-    @researchers = current_university.administration_members.researchers.accessible_by(current_ability).ordered.page(params[:page])
+    @researchers = current_university.people.researchers.accessible_by(current_ability).ordered.page(params[:page])
     breadcrumb
   end
 
   def show
-    @researcher = current_university.administration_members.authors.accessible_by(current_ability).find(params[:id])
+    @researcher = current_university.people.authors.accessible_by(current_ability).find(params[:id])
     @articles = @researcher.research_journal_articles.ordered.page(params[:page])
     breadcrumb
   end
diff --git a/app/controllers/admin/university/application_controller.rb b/app/controllers/admin/university/application_controller.rb
new file mode 100644
index 000000000..1da4eec6c
--- /dev/null
+++ b/app/controllers/admin/university/application_controller.rb
@@ -0,0 +1,6 @@
+class Admin::University::ApplicationController < Admin::ApplicationController
+  def breadcrumb
+    super
+    add_breadcrumb University.model_name.human
+  end
+end
diff --git a/app/controllers/admin/university/people_controller.rb b/app/controllers/admin/university/people_controller.rb
new file mode 100644
index 000000000..f838541bb
--- /dev/null
+++ b/app/controllers/admin/university/people_controller.rb
@@ -0,0 +1,63 @@
+class Admin::University::PeopleController < Admin::University::ApplicationController
+  load_and_authorize_resource class: University::Person,
+                              through: :current_university,
+                              through_association: :people
+
+  def index
+    @people = @people.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 @person.save_and_sync
+      redirect_to admin_university_person_path(@person), notice: t('admin.successfully_created_html', model: @person.to_s)
+    else
+      breadcrumb
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @person.update_and_sync(person_params)
+      redirect_to admin_university_person_path(@person), notice: t('admin.successfully_updated_html', model: @person.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('edit')
+      render :edit, status: :unprocessable_entity
+    end
+  end
+
+  def destroy
+    @person.destroy_and_sync
+    redirect_to admin_university_people_url, notice: t('admin.successfully_destroyed_html', model: @person.to_s)
+  end
+
+  protected
+
+  def breadcrumb
+    super
+    add_breadcrumb  University::Person.model_name.human(count: 2),
+                    admin_university_people_path
+    breadcrumb_for @person
+  end
+
+  def person_params
+    params.require(:university_person)
+          .permit(:first_name, :last_name, :email, :phone, :biography, :slug, :user_id,
+          :is_author, :is_researcher, :is_teacher, :is_administrative)
+          .merge(university_id: current_university.id)
+  end
+end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 2f1e93d76..63cb0f454 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -13,7 +13,7 @@ class Ability
   def visitor
     can :read, Administration::Qualiopi::Criterion
     can :read, Administration::Qualiopi::Indicator
-    can :read, Administration::Member
+    can :read, University::Person
     can :read, Communication::Website, university_id: @user.university_id
     can :read, Communication::Website::Page, university_id: @user.university_id
     can :read, Communication::Website::Post, university_id: @user.university_id
@@ -32,7 +32,7 @@ class Ability
   def admin
     can :read, Administration::Qualiopi::Criterion
     can :read, Administration::Qualiopi::Indicator
-    can :manage, Administration::Member
+    can :manage, University::Person
     can :read, Communication::Website, university_id: @user.university_id
     can :manage, Communication::Website::Page, university_id: @user.university_id
     can :manage, Communication::Website::Post, university_id: @user.university_id
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index 878449d81..900035620 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -46,6 +46,6 @@ class Communication::Website < ApplicationRecord
   end
 
   def git_dependencies_static
-    (pages + posts + categories + menus + members + [home] + [about]).compact
+    (pages + posts + categories + menus + people + [home] + [about]).compact
   end
 end
diff --git a/app/models/communication/website/imported/author.rb b/app/models/communication/website/imported/author.rb
index e820c7957..79689e427 100644
--- a/app/models/communication/website/imported/author.rb
+++ b/app/models/communication/website/imported/author.rb
@@ -22,7 +22,7 @@
 #
 # Foreign Keys
 #
-#  fk_rails_...  (author_id => administration_members.id)
+#  fk_rails_...  (author_id => university_people.id)
 #  fk_rails_...  (university_id => universities.id)
 #  fk_rails_...  (website_id => communication_website_imported_websites.id)
 #
@@ -32,7 +32,7 @@ class Communication::Website::Imported::Author < ApplicationRecord
   belongs_to :website,
              class_name: 'Communication::Website::Imported::Website'
   belongs_to :author,
-             class_name: 'Administration::Member',
+             class_name: 'University::Person',
              optional: true
 
   before_validation :sync
@@ -54,7 +54,7 @@ class Communication::Website::Imported::Author < ApplicationRecord
 
   def sync
     if author.nil?
-      self.author = Administration::Member.new university: university
+      self.author = University::Person.new university: university
       self.author.last_name = "Doe" # No title yet
       self.author.first_name = "John" # No title yet
       self.is_author = true
diff --git a/app/models/communication/website/imported/website.rb b/app/models/communication/website/imported/website.rb
index b5c6f3a19..b5dfa2525 100644
--- a/app/models/communication/website/imported/website.rb
+++ b/app/models/communication/website/imported/website.rb
@@ -60,16 +60,16 @@ class Communication::Website::Imported::Website < ApplicationRecord
 
   def sync_authors
     begin
-      skip_publish_callback(Administration::Member)
+      skip_publish_callback(University::Person)
       wordpress.authors.each do |data|
         author = authors.where(university: university, identifier: data['id']).first_or_initialize
         author.data = data
         author.save
       end
       # Batch update all changes (1 query only, good for github API limits)
-      website.publish_members!
+      website.publish_people!
     ensure
-      set_publish_callback(Administration::Member)
+      set_publish_callback(University::Person)
     end
   end
 
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index d6f4f48c6..36099f9fe 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -26,7 +26,7 @@
 #
 # Foreign Keys
 #
-#  fk_rails_...  (author_id => administration_members.id)
+#  fk_rails_...  (author_id => university_people.id)
 #  fk_rails_...  (communication_website_id => communication_websites.id)
 #  fk_rails_...  (university_id => universities.id)
 #
@@ -47,7 +47,7 @@ class Communication::Website::Post < ApplicationRecord
              class_name: 'Communication::Website',
              foreign_key: :communication_website_id
   belongs_to :author,
-             class_name: 'Administration::Member',
+             class_name: 'University::Person',
              optional: true
   has_and_belongs_to_many :categories,
                           class_name: 'Communication::Website::Category',
diff --git a/app/models/communication/website/with_abouts.rb b/app/models/communication/website/with_abouts.rb
index a352fb8fc..610853369 100644
--- a/app/models/communication/website/with_abouts.rb
+++ b/app/models/communication/website/with_abouts.rb
@@ -39,10 +39,10 @@ module Communication::Website::WithAbouts
     about_school? ? about.programs : Education::Program.none
   end
 
-  def members
-    @members ||= (
+  def people
+    @people ||= (
       posts.collect(&:author) +
-      programs.collect(&:members).flatten
+      programs.collect(&:teachers).flatten
       # TODO researchers via articles
     ).uniq.compact
   end
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index 2a1be1944..86061134a 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -71,7 +71,7 @@ class Education::Program < ApplicationRecord
                           foreign_key: 'education_program_id',
                           association_foreign_key: 'education_school_id'
   has_and_belongs_to_many :teachers,
-                          class_name: 'Administration::Member',
+                          class_name: 'University::Person',
                           join_table: 'education_programs_teachers',
                           foreign_key: 'education_program_id',
                           association_foreign_key: 'education_teacher_id'
diff --git a/app/models/education/program/member.rb b/app/models/education/program/member.rb
index c0c64f8ea..4f635eca4 100644
--- a/app/models/education/program/member.rb
+++ b/app/models/education/program/member.rb
@@ -16,10 +16,10 @@
 #
 # Foreign Keys
 #
-#  fk_rails_...  (member_id => administration_members.id)
+#  fk_rails_...  (member_id => university_people.id)
 #  fk_rails_...  (program_id => education_programs.id)
 #
 class Education::Program::Member < ApplicationRecord
   belongs_to :program, class_name: 'Education::Program', inverse_of: :members
-  belongs_to :member, class_name: 'Administration::Member'
+  belongs_to :member, class_name: 'University::Person'
 end
diff --git a/app/models/research/journal/article.rb b/app/models/research/journal/article.rb
index c3a6ca938..bf51e9631 100644
--- a/app/models/research/journal/article.rb
+++ b/app/models/research/journal/article.rb
@@ -42,7 +42,7 @@ class Research::Journal::Article < ApplicationRecord
   belongs_to :volume, foreign_key: :research_journal_volume_id, optional: true
   belongs_to :updated_by, class_name: 'User'
   has_and_belongs_to_many :researchers,
-                          class_name: 'Administration::Member',
+                          class_name: 'University::Person',
                           join_table: :research_journal_articles_researchers,
                           association_foreign_key: :researcher_id
   has_many :websites, -> { distinct }, through: :journal
diff --git a/app/models/university.rb b/app/models/university.rb
index 6d027182e..ee253140a 100644
--- a/app/models/university.rb
+++ b/app/models/university.rb
@@ -17,7 +17,7 @@
 #  updated_at        :datetime         not null
 #
 class University < ApplicationRecord
-  include WithAdministration
+  include WithPeople
   include WithCommunication
   include WithEducation
   include WithIdentifier
diff --git a/app/models/administration/member.rb b/app/models/university/person.rb
similarity index 94%
rename from app/models/administration/member.rb
rename to app/models/university/person.rb
index cf4201377..cd71ec8e7 100644
--- a/app/models/administration/member.rb
+++ b/app/models/university/person.rb
@@ -1,6 +1,6 @@
 # == Schema Information
 #
-# Table name: administration_members
+# Table name: university_people
 #
 #  id                :uuid             not null, primary key
 #  email             :string
@@ -19,15 +19,15 @@
 #
 # Indexes
 #
-#  index_administration_members_on_university_id  (university_id)
-#  index_administration_members_on_user_id        (user_id)
+#  index_university_people_on_university_id  (university_id)
+#  index_university_people_on_user_id        (user_id)
 #
 # Foreign Keys
 #
 #  fk_rails_...  (university_id => universities.id)
 #  fk_rails_...  (user_id => users.id)
 #
-class Administration::Member < ApplicationRecord
+class University::Person < ApplicationRecord
   include WithGit
   include WithSlug
 
diff --git a/app/models/university/with_administration.rb b/app/models/university/with_administration.rb
deleted file mode 100644
index 313e80472..000000000
--- a/app/models/university/with_administration.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module University::WithAdministration
-  extend ActiveSupport::Concern
-
-  included do
-    has_many :administration_members, class_name: 'Administration::Member', dependent: :destroy
-  end
-end
diff --git a/app/models/university/with_people.rb b/app/models/university/with_people.rb
new file mode 100644
index 000000000..0f992a60d
--- /dev/null
+++ b/app/models/university/with_people.rb
@@ -0,0 +1,7 @@
+module University::WithPeople
+  extend ActiveSupport::Concern
+
+  included do
+    has_many :people, class_name: 'University::Person', dependent: :destroy
+  end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 912755e7b..a33738c3c 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -60,7 +60,7 @@ class User < ApplicationRecord
 
   belongs_to :university
   belongs_to :language
-  has_one :member, class_name: 'Administration::Member', dependent: :nullify
+  has_one :person, class_name: 'University::Person', dependent: :nullify
 
   scope :ordered, -> { order(:last_name, :first_name) }
 
diff --git a/app/views/admin/administration/members/_main_infos.html.erb b/app/views/admin/administration/members/_main_infos.html.erb
deleted file mode 100644
index 67dfa3934..000000000
--- a/app/views/admin/administration/members/_main_infos.html.erb
+++ /dev/null
@@ -1,36 +0,0 @@
-<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">
-        <% unless member.email.blank? %>
-          <h3 class="h5"><%= Administration::Member.human_attribute_name('email') %></h3>
-          <p><%= link_to member.email, "mailto:#{member.email}", target: '_blank' %></p>
-        <% end %>
-        <% unless member.phone.blank? %>
-          <h3 class="h5"><%= Administration::Member.human_attribute_name('phone') %></h3>
-          <p><%= link_to member.phone, "tel:#{member.phone}", target: '_blank' %></p>
-        <% end %>
-        <h3 class="h5"><%= Administration::Member.human_attribute_name('biography') %></h3>
-        <%= member.biography %>
-      </div>
-    </div>
-  </div>
-  <div class="col-md-4">
-    <div class="card flex-fill w-100">
-      <div class="card-header">
-        <h2 class="card-title mb-0 h5"><%= t('metadata') %></h2>
-      </div>
-      <div class="card-body">
-        <h3 class="h5"><%= Administration::Member.human_attribute_name('slug') %></h3>
-        <p><%= member.slug %></p>
-        <% if member.user.present? %>
-          <h3 class="h5"><%= Administration::Member.human_attribute_name('user') %></h3>
-          <p><%= link_to_if can?(:read, member.user), member.user, admin_user_path(member.user) %></p>
-        <% end %>
-      </div>
-    </div>
-  </div>
-</div>
diff --git a/app/views/admin/administration/members/administrator.html.erb b/app/views/admin/administration/members/administrator.html.erb
deleted file mode 100644
index 4e281854b..000000000
--- a/app/views/admin/administration/members/administrator.html.erb
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: >
-  Responsabilités de <%= @member.to_s %>
-person: >
-  <%= @member.to_s %>
-slug: "<%= @member.slug %>"
----
diff --git a/app/views/admin/administration/members/author.html.erb b/app/views/admin/administration/members/author.html.erb
deleted file mode 100644
index 3dccaf0e0..000000000
--- a/app/views/admin/administration/members/author.html.erb
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: >
-  Actualités de <%= @member.to_s %>
-person: >
-  <%= @member.to_s %>
-slug: "<%= @member.slug %>"
----
diff --git a/app/views/admin/administration/members/edit.html.erb b/app/views/admin/administration/members/edit.html.erb
deleted file mode 100644
index 8a3aebfee..000000000
--- a/app/views/admin/administration/members/edit.html.erb
+++ /dev/null
@@ -1,3 +0,0 @@
-<% content_for :title, @member %>
-
-<%= render 'form', member: @member %>
diff --git a/app/views/admin/administration/members/index.html.erb b/app/views/admin/administration/members/index.html.erb
deleted file mode 100644
index 53ceb5e8e..000000000
--- a/app/views/admin/administration/members/index.html.erb
+++ /dev/null
@@ -1,8 +0,0 @@
-<% content_for :title, "#{Administration::Member.model_name.human(count: 2)} (#{@members.total_count})" %>
-
-<%= render 'admin/administration/members/list', members: @members %>
-<%= paginate @members, theme: 'bootstrap-5' %>
-
-<% content_for :action_bar_right do %>
-  <%= create_link Administration::Member %>
-<% end %>
diff --git a/app/views/admin/administration/members/new.html.erb b/app/views/admin/administration/members/new.html.erb
deleted file mode 100644
index 47b25fa3e..000000000
--- a/app/views/admin/administration/members/new.html.erb
+++ /dev/null
@@ -1,3 +0,0 @@
-<% content_for :title, Administration::Member.model_name.human %>
-
-<%= render 'form', member: @member %>
diff --git a/app/views/admin/administration/members/researcher.html.erb b/app/views/admin/administration/members/researcher.html.erb
deleted file mode 100644
index 823ad92ba..000000000
--- a/app/views/admin/administration/members/researcher.html.erb
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: >
-  Publications de <%= @member.to_s %>
-person: >
-  <%= @member.to_s %>
-slug: "<%= @member.slug %>"
----
diff --git a/app/views/admin/administration/members/show.html.erb b/app/views/admin/administration/members/show.html.erb
deleted file mode 100644
index 5e204e537..000000000
--- a/app/views/admin/administration/members/show.html.erb
+++ /dev/null
@@ -1,7 +0,0 @@
-<% content_for :title, @member %>
-
-<%= render 'main_infos', member: @member %>
-
-<% content_for :action_bar_right do %>
-  <%= edit_link @member %>
-<% end %>
diff --git a/app/views/admin/administration/members/static.html.erb b/app/views/admin/administration/members/static.html.erb
deleted file mode 100644
index 792802493..000000000
--- a/app/views/admin/administration/members/static.html.erb
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: >
-  <%= @member.to_s %>
-slug: "<%= @member.slug %>"
-first_name: "<%= @member.first_name %>"
-last_name: "<%= @member.last_name %>"
-phone: "<%= @member.phone %>"
-email: "<%= @member.email %>"
-roles:
-<% if @member.is_author %>
-  - author
-<% end %>
-<% if @member.is_teacher %>
-  - teacher
-<% end %>
-<% if @member.is_researcher %>
-  - researcher
-<% end %>
-<% if @member.is_administrative %>
-  - administrator
-<% end %>
----
-<%= prepare_for_github @member.biography, @member.university %>
diff --git a/app/views/admin/administration/members/teacher.html.erb b/app/views/admin/administration/members/teacher.html.erb
deleted file mode 100644
index 6a76fea4a..000000000
--- a/app/views/admin/administration/members/teacher.html.erb
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: >
-  Enseignements de <%= @member.to_s %>
-person: >
-  <%= @member.to_s %>
-slug: "<%= @member.slug %>"
----
diff --git a/app/views/admin/communication/website/authors/_list.html.erb b/app/views/admin/communication/website/authors/_list.html.erb
index 9eb1c1bdd..9914ed4f9 100644
--- a/app/views/admin/communication/website/authors/_list.html.erb
+++ b/app/views/admin/communication/website/authors/_list.html.erb
@@ -1,8 +1,8 @@
 <table class="<%= table_classes %>">
   <thead>
     <tr>
-      <th><%= Administration::Member.human_attribute_name('last_name') %></th>
-      <th><%= Administration::Member.human_attribute_name('first_name') %></th>
+      <th><%= University::Person.human_attribute_name('last_name') %></th>
+      <th><%= University::Person.human_attribute_name('first_name') %></th>
       <th><%= t('communication.number_of_posts') %></th>
     </tr>
   </thead>
diff --git a/app/views/admin/communication/website/authors/index.html.erb b/app/views/admin/communication/website/authors/index.html.erb
index 47e934231..40776b6c8 100644
--- a/app/views/admin/communication/website/authors/index.html.erb
+++ b/app/views/admin/communication/website/authors/index.html.erb
@@ -12,5 +12,5 @@
 <% end %>
 
 <% content_for :action_bar_right do %>
-  <%= link_to t('communication.manage_authors'), admin_administration_members_path, class: button_classes if can?(:read, Administration::Member) %>
+  <%= link_to t('communication.manage_authors'), admin_university_people_path, class: button_classes if can?(:read, University::Person) %>
 <% end %>
diff --git a/app/views/admin/communication/website/authors/show.html.erb b/app/views/admin/communication/website/authors/show.html.erb
index 212a629cc..d9d7e9b21 100644
--- a/app/views/admin/communication/website/authors/show.html.erb
+++ b/app/views/admin/communication/website/authors/show.html.erb
@@ -1,7 +1,7 @@
 <% content_for :title, @author %>
 
 <%= render 'admin/communication/websites/sidebar' do %>
-  <%= render 'admin/administration/members/main_infos', member: @author %>
+  <%= render 'admin/university/people/main_infos', person: @author %>
 
   <% if @posts.total_count > 0 %>
     <div class="card">
diff --git a/app/views/admin/communication/website/posts/_form.html.erb b/app/views/admin/communication/website/posts/_form.html.erb
index f575dced1..953383672 100644
--- a/app/views/admin/communication/website/posts/_form.html.erb
+++ b/app/views/admin/communication/website/posts/_form.html.erb
@@ -27,7 +27,7 @@
           <%= f.input :published %>
           <%= f.input :published_at, html5: true %>
           <%= f.input :pinned %>
-          <%= f.association :author, collection: current_university.administration_members.authors.ordered %>
+          <%= f.association :author, collection: current_university.people.authors.ordered %>
           <%= f.association :categories,
                             as: :check_boxes,
                             collection: collection_tree(@website.categories).map { |category| [
diff --git a/app/views/admin/communication/websites/import.html.erb b/app/views/admin/communication/websites/import.html.erb
index 71f9a23e8..16acd2448 100644
--- a/app/views/admin/communication/websites/import.html.erb
+++ b/app/views/admin/communication/websites/import.html.erb
@@ -111,7 +111,7 @@
   <table class="<%= table_classes %>">
     <thead>
       <tr>
-        <th><%= Administration::Member.human_attribute_name('name') %></th>
+        <th><%= University::Person.human_attribute_name('name') %></th>
         <th class="text-end" width="150">&nbsp;</th>
       </tr>
     </thead>
diff --git a/app/views/admin/education/programs/_form.html.erb b/app/views/admin/education/programs/_form.html.erb
index 93e2959b5..89a5b38f7 100644
--- a/app/views/admin/education/programs/_form.html.erb
+++ b/app/views/admin/education/programs/_form.html.erb
@@ -22,7 +22,7 @@
                             as: :check_boxes,
                             collection: current_university.education_schools.ordered %>
           <%= f.association :parent,
-                            collection: collection_tree(current_university.programs, program),
+                            collection: collection_tree(current_university.education_programs, program),
                             label_method: ->(p) { sanitize p[:label] },
                             value_method: ->(p) { p[:id] } %>
         </div>
@@ -69,7 +69,7 @@
         <div class="card-body">
           <%= f.association :teachers,
                             as: :check_boxes,
-                            collection: current_university.administration_members.teachers.ordered %>
+                            collection: current_university.people.teachers.ordered %>
         </div>
         <div class="card-body">
           <div id="js-program-members">
@@ -81,7 +81,7 @@
                 </div>
                 <div class="col-md-5">
                   <%
-                  base_members = current_university.administration_members
+                  base_members = current_university.people
                   list_of_members = base_members.administratives.or(base_members.teachers).ordered
                   %>
                   <%= member_form.association :member,
diff --git a/app/views/admin/education/teachers/_list.html.erb b/app/views/admin/education/teachers/_list.html.erb
index 9f59a100f..5a47a2f42 100644
--- a/app/views/admin/education/teachers/_list.html.erb
+++ b/app/views/admin/education/teachers/_list.html.erb
@@ -1,8 +1,8 @@
 <table class="<%= table_classes %>">
   <thead>
     <tr>
-      <th><%= Administration::Member.human_attribute_name('last_name') %></th>
-      <th><%= Administration::Member.human_attribute_name('first_name') %></th>
+      <th><%= University::Person.human_attribute_name('last_name') %></th>
+      <th><%= University::Person.human_attribute_name('first_name') %></th>
       <th></th>
     </tr>
   </thead>
diff --git a/app/views/admin/education/teachers/index.html.erb b/app/views/admin/education/teachers/index.html.erb
index 70d6d6ebc..44222c52b 100644
--- a/app/views/admin/education/teachers/index.html.erb
+++ b/app/views/admin/education/teachers/index.html.erb
@@ -7,5 +7,5 @@
 <% end %>
 
 <% content_for :action_bar_right do %>
-  <%= link_to t('education.manage_teachers'), admin_administration_members_path, class: button_classes if can?(:read, Administration::Member) %>
+  <%= link_to t('education.manage_teachers'), admin_university_people_path, class: button_classes if can?(:read, University::Person) %>
 <% end %>
diff --git a/app/views/admin/education/teachers/show.html.erb b/app/views/admin/education/teachers/show.html.erb
index c5fd6e562..2771c679d 100644
--- a/app/views/admin/education/teachers/show.html.erb
+++ b/app/views/admin/education/teachers/show.html.erb
@@ -1,6 +1,6 @@
 <% content_for :title, @teacher %>
 
-<%= render 'admin/administration/members/main_infos', member: @teacher %>
+<%= render 'admin/university/people/main_infos', person: @teacher %>
 
 
 <% if @programs.total_count > 0 %>
diff --git a/app/views/admin/research/journal/articles/_form.html.erb b/app/views/admin/research/journal/articles/_form.html.erb
index c2131ffce..60f8b1943 100644
--- a/app/views/admin/research/journal/articles/_form.html.erb
+++ b/app/views/admin/research/journal/articles/_form.html.erb
@@ -29,7 +29,7 @@
           <%= f.association :volume, collection: @journal.volumes, label: Research::Journal::Volume.model_name.human %>
           <%= f.input :published_at, html5: true %>
           <%= f.input :keywords, as: :text, input_html: { rows: 2 } %>
-          <%= f.association :researchers, collection: current_university.administration_members.researchers.ordered, as: :check_boxes %>
+          <%= f.association :researchers, collection: current_university.people.researchers.ordered, as: :check_boxes %>
         </div>
       </div>
     </div>
diff --git a/app/views/admin/research/researchers/index.html.erb b/app/views/admin/research/researchers/index.html.erb
index 9f11f2a30..9fa1cdad6 100644
--- a/app/views/admin/research/researchers/index.html.erb
+++ b/app/views/admin/research/researchers/index.html.erb
@@ -3,8 +3,8 @@
 <table class="table">
   <thead>
     <tr>
-      <th><%= Administration::Member.human_attribute_name('name') %></th>
-      <th><%= Administration::Member.human_attribute_name('first_name') %></th>
+      <th><%= University::Person.human_attribute_name('name') %></th>
+      <th><%= University::Person.human_attribute_name('first_name') %></th>
       <th><%= t('research.number_of_articles') %></th>
     </tr>
   </thead>
@@ -25,5 +25,5 @@
 
 
 <% content_for :action_bar_right do %>
-  <%= link_to t('research.manage_researchers'), admin_administration_members_path, class: button_classes if can?(:read, Administration::Member) %>
+  <%= link_to t('research.manage_researchers'), admin_university_people_path, class: button_classes if can?(:read, University::Person) %>
 <% end %>
diff --git a/app/views/admin/research/researchers/show.html.erb b/app/views/admin/research/researchers/show.html.erb
index 7c58ad5f8..b80329a3c 100644
--- a/app/views/admin/research/researchers/show.html.erb
+++ b/app/views/admin/research/researchers/show.html.erb
@@ -1,6 +1,6 @@
 <% content_for :title, @researcher %>
 
-<%= render 'admin/administration/members/main_infos', member: @researcher %>
+<%= render 'admin/university/people/main_infos', person: @researcher %>
 
 <% if @articles.total_count > 0 %>
   <div class="card">
diff --git a/app/views/admin/administration/members/_form.html.erb b/app/views/admin/university/people/_form.html.erb
similarity index 84%
rename from app/views/admin/administration/members/_form.html.erb
rename to app/views/admin/university/people/_form.html.erb
index 16d8ff2e4..9c725da98 100644
--- a/app/views/admin/administration/members/_form.html.erb
+++ b/app/views/admin/university/people/_form.html.erb
@@ -1,4 +1,4 @@
-<%= simple_form_for [:admin, member] do |f| %>
+<%= simple_form_for [:admin, person] do |f| %>
   <div class="row">
     <div class="col-md-8">
       <div class="card flex-fill w-100">
@@ -34,16 +34,16 @@
         <div class="card-body">
           <%= f.input :slug,
           as: :string,
-          input_html: member.persisted? ? {} : {
+          input_html: person.persisted? ? {} : {
             class: 'js-slug-input',
-            data: { source: '#administration_member_first_name, #administration_member_last_name' }
+            data: { source: '#university_person_first_name, #university_person_last_name' }
           } %>
           <%= f.association :user, collection: current_university.users.ordered %>
         </div>
       </div>
       <div class="card flex-fill w-100">
         <div class="card-header">
-          <h5 class="card-title mb-0"><%= Administration::Member.human_attribute_name('abilities') %></h5>
+          <h5 class="card-title mb-0"><%= University::Person.human_attribute_name('abilities') %></h5>
         </div>
         <div class="card-body">
           <%= f.input :is_author %>
diff --git a/app/views/admin/administration/members/_list.html.erb b/app/views/admin/university/people/_list.html.erb
similarity index 51%
rename from app/views/admin/administration/members/_list.html.erb
rename to app/views/admin/university/people/_list.html.erb
index 5d04d354d..d7e02ab29 100644
--- a/app/views/admin/administration/members/_list.html.erb
+++ b/app/views/admin/university/people/_list.html.erb
@@ -1,23 +1,23 @@
 <table class="<%= table_classes %>">
   <thead>
     <tr>
-      <th><%= Administration::Member.human_attribute_name('last_name') %></th>
-      <th><%= Administration::Member.human_attribute_name('first_name') %></th>
+      <th><%= University::Person.human_attribute_name('last_name') %></th>
+      <th><%= University::Person.human_attribute_name('first_name') %></th>
       <th></th>
     </tr>
   </thead>
   <tbody>
-    <% members.each do |member| %>
+    <% people.each do |person| %>
       <tr>
-        <td><%= link_to member.last_name, admin_administration_member_path(member) %></td>
-        <td><%= link_to member.first_name, admin_administration_member_path(member) %></td>
+        <td><%= link_to person.last_name, admin_university_person_path(person) %></td>
+        <td><%= link_to person.first_name, admin_university_person_path(person) %></td>
         <td class="text-end">
           <div class="btn-group" role="group">
             <%= link_to t('edit'),
-                      edit_admin_administration_member_path(member),
+                      edit_admin_university_person_path(person),
                       class: button_classes %>
             <%= link_to t('delete'),
-                      admin_administration_member_path(member),
+                      admin_university_person_path(person),
                       method: :delete,
                       data: { confirm: t('please_confirm') },
                       class: button_classes_danger %>
diff --git a/app/views/admin/university/people/_main_infos.html.erb b/app/views/admin/university/people/_main_infos.html.erb
new file mode 100644
index 000000000..9a5f7ebe4
--- /dev/null
+++ b/app/views/admin/university/people/_main_infos.html.erb
@@ -0,0 +1,36 @@
+<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">
+        <% unless person.email.blank? %>
+          <h3 class="h5"><%= University::Person.human_attribute_name('email') %></h3>
+          <p><%= link_to person.email, "mailto:#{person.email}", target: '_blank' %></p>
+        <% end %>
+        <% unless person.phone.blank? %>
+          <h3 class="h5"><%= University::Person.human_attribute_name('phone') %></h3>
+          <p><%= link_to person.phone, "tel:#{person.phone}", target: '_blank' %></p>
+        <% end %>
+        <h3 class="h5"><%= University::Person.human_attribute_name('biography') %></h3>
+        <%= person.biography %>
+      </div>
+    </div>
+  </div>
+  <div class="col-md-4">
+    <div class="card flex-fill w-100">
+      <div class="card-header">
+        <h2 class="card-title mb-0 h5"><%= t('metadata') %></h2>
+      </div>
+      <div class="card-body">
+        <h3 class="h5"><%= University::Person.human_attribute_name('slug') %></h3>
+        <p><%= person.slug %></p>
+        <% if person.user.present? %>
+          <h3 class="h5"><%= University::Person.human_attribute_name('user') %></h3>
+          <p><%= link_to_if can?(:read, person.user), person.user, admin_user_path(person.user) %></p>
+        <% end %>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/app/views/admin/university/people/administrator.html.erb b/app/views/admin/university/people/administrator.html.erb
new file mode 100644
index 000000000..7338333cf
--- /dev/null
+++ b/app/views/admin/university/people/administrator.html.erb
@@ -0,0 +1,7 @@
+---
+title: >
+  Responsabilités de <%= @person.to_s %>
+person: >
+  <%= @person.to_s %>
+slug: "<%= @person.slug %>"
+---
diff --git a/app/views/admin/university/people/author.html.erb b/app/views/admin/university/people/author.html.erb
new file mode 100644
index 000000000..e9875a833
--- /dev/null
+++ b/app/views/admin/university/people/author.html.erb
@@ -0,0 +1,7 @@
+---
+title: >
+  Actualités de <%= @person.to_s %>
+person: >
+  <%= @person.to_s %>
+slug: "<%= @person.slug %>"
+---
diff --git a/app/views/admin/university/people/edit.html.erb b/app/views/admin/university/people/edit.html.erb
new file mode 100644
index 000000000..d48b5d966
--- /dev/null
+++ b/app/views/admin/university/people/edit.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @person %>
+
+<%= render 'form', person: @person %>
diff --git a/app/views/admin/university/people/index.html.erb b/app/views/admin/university/people/index.html.erb
new file mode 100644
index 000000000..b95e8aa32
--- /dev/null
+++ b/app/views/admin/university/people/index.html.erb
@@ -0,0 +1,8 @@
+<% content_for :title, "#{University::Person.model_name.human(count: 2)} (#{@people.total_count})" %>
+
+<%= render 'admin/university/people/list', people: @people %>
+<%= paginate @people, theme: 'bootstrap-5' %>
+
+<% content_for :action_bar_right do %>
+  <%= create_link University::Person %>
+<% end %>
diff --git a/app/views/admin/university/people/new.html.erb b/app/views/admin/university/people/new.html.erb
new file mode 100644
index 000000000..5a24f1f3b
--- /dev/null
+++ b/app/views/admin/university/people/new.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, University::Person.model_name.human %>
+
+<%= render 'form', person: @person %>
diff --git a/app/views/admin/university/people/researcher.html.erb b/app/views/admin/university/people/researcher.html.erb
new file mode 100644
index 000000000..aac484f67
--- /dev/null
+++ b/app/views/admin/university/people/researcher.html.erb
@@ -0,0 +1,7 @@
+---
+title: >
+  Publications de <%= @person.to_s %>
+person: >
+  <%= @person.to_s %>
+slug: "<%= @person.slug %>"
+---
diff --git a/app/views/admin/university/people/show.html.erb b/app/views/admin/university/people/show.html.erb
new file mode 100644
index 000000000..4d3245b61
--- /dev/null
+++ b/app/views/admin/university/people/show.html.erb
@@ -0,0 +1,7 @@
+<% content_for :title, @person %>
+
+<%= render 'main_infos', person: @person %>
+
+<% content_for :action_bar_right do %>
+  <%= edit_link @person %>
+<% end %>
diff --git a/app/views/admin/university/people/static.html.erb b/app/views/admin/university/people/static.html.erb
new file mode 100644
index 000000000..0bbfffa7d
--- /dev/null
+++ b/app/views/admin/university/people/static.html.erb
@@ -0,0 +1,23 @@
+---
+title: >
+  <%= @person.to_s %>
+slug: "<%= @person.slug %>"
+first_name: "<%= @person.first_name %>"
+last_name: "<%= @person.last_name %>"
+phone: "<%= @person.phone %>"
+email: "<%= @person.email %>"
+roles:
+<% if @person.is_author %>
+  - author
+<% end %>
+<% if @person.is_teacher %>
+  - teacher
+<% end %>
+<% if @person.is_researcher %>
+  - researcher
+<% end %>
+<% if @person.is_administrative %>
+  - administrator
+<% end %>
+---
+<%= prepare_for_github @person.biography, @person.university %>
diff --git a/app/views/admin/university/people/teacher.html.erb b/app/views/admin/university/people/teacher.html.erb
new file mode 100644
index 000000000..c7ab2cf33
--- /dev/null
+++ b/app/views/admin/university/people/teacher.html.erb
@@ -0,0 +1,7 @@
+---
+title: >
+  Enseignements de <%= @person.to_s %>
+person: >
+  <%= @person.to_s %>
+slug: "<%= @person.slug %>"
+---
diff --git a/app/views/admin/users/show.html.erb b/app/views/admin/users/show.html.erb
index 58d61c2fa..746c076a5 100644
--- a/app/views/admin/users/show.html.erb
+++ b/app/views/admin/users/show.html.erb
@@ -23,10 +23,10 @@
           <td><%= User.human_attribute_name('language') %></td>
           <td class="text-end"><%= t("languages.#{@user.language.iso_code.to_s}") %></td>
         </tr>
-        <% if @user.member %>
+        <% if @user.person %>
           <tr>
-            <td><%= User.human_attribute_name('member') %></td>
-            <td class="text-end"><%= link_to @user.member, [:admin, @user.member] %></td>
+            <td><%= User.human_attribute_name('person') %></td>
+            <td class="text-end"><%= link_to @user.person, [:admin, @user.person] %></td>
           </tr>
         <% end %>
       </table>
diff --git a/config/admin_navigation.rb b/config/admin_navigation.rb
index 39ef3a21a..e753e4bdd 100644
--- a/config/admin_navigation.rb
+++ b/config/admin_navigation.rb
@@ -6,9 +6,14 @@ SimpleNavigation::Configuration.run do |navigation|
   navigation.items do |primary|
     primary.item :dashboard, t('dashboard'), admin_root_path, { icon: 'tachometer-alt', highlights_on: /admin$/ }
 
+    if can?(:read, User) || can?(:read, University::Person)
+      primary.item :university, University.model_name.human, nil, { kind: :header }
+      primary.item :university, University::Person.model_name.human(count: 2), admin_university_people_path, { icon: 'users-cog' }
+    end
+
     if can?(:read, Education::Program)
       primary.item :education, Education.model_name.human, nil, { kind: :header }
-      primary.item :education, t('education.teachers', count: 2), admin_education_teachers_path, { icon: 'user-graduate' } if can?(:read, Administration::Member)
+      primary.item :education, t('education.teachers', count: 2), admin_education_teachers_path, { icon: 'user-graduate' } if can?(:read, University::Person)
       primary.item :education, Education::School.model_name.human(count: 2), admin_education_schools_path, { icon: 'university' } if can?(:read, Education::School)
       primary.item :education_programs, Education::Program.model_name.human(count: 2), admin_education_programs_path, { icon: 'graduation-cap' } if can?(:read, Education::Program)
       primary.item :education, 'Ressources éducatives', nil, { icon: 'laptop' }
@@ -17,7 +22,7 @@ SimpleNavigation::Configuration.run do |navigation|
 
     if can?(:read, Research::Journal)
       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, Administration::Member)
+      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, 'Laboratoires', nil, { icon: 'flask' }
       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)
@@ -30,9 +35,8 @@ SimpleNavigation::Configuration.run do |navigation|
       primary.item :communication, 'Alumni', nil, { icon: 'users' }
     end
 
-    if can?(:read, User) || can?(:read, Administration::Qualiopi::Criterion)
+    if can?(:read, Administration::Qualiopi::Criterion)
       primary.item :administration, 'Administration', nil, { kind: :header }
-      primary.item :administration, Administration::Member.model_name.human(count: 2), admin_administration_members_path, { icon: 'users-cog' }
       primary.item :administration, 'Campus', nil, { icon: 'map-marker-alt' }
       primary.item :administration, 'Admissions', nil, { icon: 'door-open' }
       primary.item :administration, 'Statistiques', nil, { icon: 'cog' }
diff --git a/config/locales/administration/en.yml b/config/locales/administration/en.yml
index a5dd96be0..ee9d57f1e 100644
--- a/config/locales/administration/en.yml
+++ b/config/locales/administration/en.yml
@@ -10,27 +10,7 @@ en:
       administration/qualiopi/indicator:
         one: Indicator
         other: Indicators
-      administration/member:
-        one: Staff
-        other: Staff
     attributes:
-      administration/member:
-        abilities: Abilities
-        biography: Biography
-        communication_website_posts: Posts
-        education_programs: Programs
-        email: Email
-        first_name: First name
-        is_administrative: Administrative staff
-        is_author: Author
-        is_researcher: Researcher
-        is_teacher: Teacher
-        last_name: Last name
-        name: Name
-        phone: Phone
-        research_journal_articles: Articles
-        slug: Slug
-        user: User
       administration/qualiopi/criterion:
         number: Number
         name: Name
@@ -45,10 +25,3 @@ en:
         requirement: Requirement
         non_conformity: Non-conformity
         glossary: Glossary
-  simple_form:
-    hints:
-      administration_member:
-        is_administrative: "Is part of administrative staff for a school."
-        is_author: "Writes posts for websites."
-        is_researcher: "Writes articles for journals."
-        is_teacher: "Teaches in Schools."
diff --git a/config/locales/administration/fr.yml b/config/locales/administration/fr.yml
index 5c62bd090..e9d4fa0f9 100644
--- a/config/locales/administration/fr.yml
+++ b/config/locales/administration/fr.yml
@@ -10,27 +10,7 @@ fr:
       administration/qualiopi/indicator:
         one: Indicateur
         other: Indicateurs
-      administration/member:
-        one: Personnel
-        other: Personnel
     attributes:
-      administration/member:
-        abilities: Responsabilités
-        biography: Biographie
-        communication_website_posts: Actualités
-        education_programs: Formations
-        email: Email
-        first_name: Prénom
-        is_administrative: Personnel administratif
-        is_author: Auteur·rice
-        is_researcher: Chercheur·se
-        is_teacher: Enseignant·e
-        last_name: Nom de famille
-        name: Nom
-        phone: Téléphone
-        research_journal_articles: Articles
-        slug: Slug
-        user: Utilisateur
       administration/qualiopi/criterion:
         number: Numéro
         name: Nom
@@ -45,10 +25,3 @@ fr:
         requirement: Obligations spécifiques
         non_conformity: Non-conformité
         glossary: Glossaire
-  simple_form:
-    hints:
-      administration_member:
-        is_administrative: "Fait partie du personnel administratif d'une école."
-        is_author: "Écrit des articles pour les sites."
-        is_researcher: "Écrit des articles dans des revues scientifiques."
-        is_teacher: "Enseigne dans des formations."
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2809996a7..aea1857ea 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -4,25 +4,12 @@ en:
       language:
         iso_code: Iso code
         name: Name
-      university:
-        address: Address
-        city: City
-        country: Country
-        identifier: Identifier
-        logo: Logo
-        name: Name
-        private: Private
-        public: Public
-        public_or_private: Public/private
-        sms_sender_name: SMS sender name
-        url: 'URL'
-        zipcode: Zipcode
       user:
         email: Email
         first_name: First name
         language: Favourite language
         last_name: Last name
-        member: Member
+        person: Person
         mobile_phone: Mobile phone
         picture: Profile picture
         role: Role
@@ -36,9 +23,6 @@ en:
       language:
         one: Language
         other: Languages
-      university:
-        one: University
-        other: Universities
       user:
         one: User
         other: Users
@@ -122,8 +106,6 @@ en:
     error_notification:
       default_message: "Please review the problems below:"
     hints:
-      university:
-        sms_sender_name: "11 characters max."
       user:
         mobile_phone: "International format (+XX). By filling this field, you accept to receive your two-factor authentication codes via SMS."
   simple_form_password_with_hints:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 886a1e002..ebbd8d67b 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -4,25 +4,12 @@ fr:
       language:
         iso_code: Code Iso
         name: Nom
-      university:
-        address: Adresse
-        city: Ville
-        country: Pays
-        identifier: Identifiant
-        logo: Logo
-        name: Nom
-        private: Etablissement privé
-        public: Public
-        public_or_private: Public/privé
-        sms_sender_name: Nom de l'expéditeur SMS
-        url: 'URL'
-        zipcode: Code postal
       user:
         email: Email
         first_name: Prénom
         language: Langue préférée
         last_name: Nom
-        member: Personnel
+        person: Personne
         mobile_phone: Téléphone portable
         picture: Photo de profil
         role: Rôle
@@ -36,9 +23,6 @@ fr:
       language:
         one: Langue
         other: Langues
-      university:
-        one: Université
-        other: Universités
       user:
         one: Utilisateur·rice
         other: Utilisateur·rice·s
@@ -122,8 +106,6 @@ fr:
     error_notification:
       default_message: "Les erreurs ci-dessous empêchent la validation :"
     hints:
-      university:
-        sms_sender_name: "11 caractères maximum."
       user:
         mobile_phone: "Format international (+XX). En renseignant ce champ, vous acceptez de recevoir vos codes de double authentification par SMS."
   simple_form_password_with_hints:
diff --git a/config/locales/university/en.yml b/config/locales/university/en.yml
new file mode 100644
index 000000000..da4c0ba45
--- /dev/null
+++ b/config/locales/university/en.yml
@@ -0,0 +1,49 @@
+en:
+  activerecord:
+    attributes:
+      university:
+        address: Address
+        city: City
+        country: Country
+        identifier: Identifier
+        logo: Logo
+        name: Name
+        private: Private
+        public: Public
+        public_or_private: Public/private
+        sms_sender_name: SMS sender name
+        url: 'URL'
+        zipcode: Zipcode
+      university/person:
+        abilities: Abilities
+        biography: Biography
+        communication_website_posts: Posts
+        education_programs: Programs
+        email: Email
+        first_name: First name
+        is_administrative: Administrative staff
+        is_author: Author
+        is_researcher: Researcher
+        is_teacher: Teacher
+        last_name: Last name
+        name: Name
+        phone: Phone
+        research_journal_articles: Articles
+        slug: Slug
+        user: User
+    models:
+      university:
+        one: University
+        other: Universities
+      university/person:
+        one: Person
+        other: People
+  simple_form:
+    hints:
+      university:
+        sms_sender_name: "11 characters max."
+      university_person:
+        is_administrative: "Is part of administrative staff for a school."
+        is_author: "Writes posts for websites."
+        is_researcher: "Writes articles for journals."
+        is_teacher: "Teaches in Schools."
diff --git a/config/locales/university/fr.yml b/config/locales/university/fr.yml
new file mode 100644
index 000000000..415db01cd
--- /dev/null
+++ b/config/locales/university/fr.yml
@@ -0,0 +1,49 @@
+fr:
+  activerecord:
+    attributes:
+      university:
+        address: Adresse
+        city: Ville
+        country: Pays
+        identifier: Identifiant
+        logo: Logo
+        name: Nom
+        private: Etablissement privé
+        public: Public
+        public_or_private: Public/privé
+        sms_sender_name: Nom de l'expéditeur SMS
+        url: 'URL'
+        zipcode: Code postal
+      university/person:
+        abilities: Responsabilités
+        biography: Biographie
+        communication_website_posts: Actualités
+        education_programs: Formations
+        email: Email
+        first_name: Prénom
+        is_administrative: Personnel administratif
+        is_author: Auteur·rice
+        is_researcher: Chercheur·se
+        is_teacher: Enseignant·e
+        last_name: Nom de famille
+        name: Nom
+        phone: Téléphone
+        research_journal_articles: Articles
+        slug: Slug
+        user: Utilisateur
+    models:
+      university:
+        one: Université
+        other: Universités
+      university/person:
+        one: Personne
+        other: Personnes
+  simple_form:
+    hints:
+      university:
+        sms_sender_name: "11 caractères maximum."
+      university_person:
+        is_administrative: "Fait partie du personnel administratif d'une école."
+        is_author: "Écrit des articles pour les sites."
+        is_researcher: "Écrit des articles dans des revues scientifiques."
+        is_teacher: "Enseigne dans des formations."
diff --git a/config/routes.rb b/config/routes.rb
index 516bcd0b1..53f055ef2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -17,6 +17,7 @@ Rails.application.routes.draw do
     draw 'admin/communication'
     draw 'admin/education'
     draw 'admin/research'
+    draw 'admin/university'
     root to: 'dashboard#index'
   end
 
diff --git a/config/routes/admin/administration.rb b/config/routes/admin/administration.rb
index 50ef7b6cc..f5b69fe50 100644
--- a/config/routes/admin/administration.rb
+++ b/config/routes/admin/administration.rb
@@ -3,6 +3,4 @@ namespace :administration do
     resources :criterions, only: [:index, :show]
     resources :indicators, only: [:index, :show]
   end
-
-  resources :members
 end
diff --git a/config/routes/admin/university.rb b/config/routes/admin/university.rb
new file mode 100644
index 000000000..29714435a
--- /dev/null
+++ b/config/routes/admin/university.rb
@@ -0,0 +1,3 @@
+namespace :university do
+  resources :people
+end
diff --git a/db/migrate/20220105135913_rename_administration_members.rb b/db/migrate/20220105135913_rename_administration_members.rb
new file mode 100644
index 000000000..bc2af469c
--- /dev/null
+++ b/db/migrate/20220105135913_rename_administration_members.rb
@@ -0,0 +1,5 @@
+class RenameAdministrationMembers < ActiveRecord::Migration[6.1]
+  def change
+    rename_table :administration_members, :university_people
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ecbca4813..99307fe0b 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_03_174641) do
+ActiveRecord::Schema.define(version: 2022_01_05_135913) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -56,24 +56,6 @@ ActiveRecord::Schema.define(version: 2022_01_03_174641) do
     t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
   end
 
-  create_table "administration_members", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
-    t.uuid "university_id", null: false
-    t.uuid "user_id"
-    t.string "last_name"
-    t.string "first_name"
-    t.string "slug"
-    t.boolean "is_author"
-    t.boolean "is_researcher"
-    t.boolean "is_teacher"
-    t.boolean "is_administrative"
-    t.datetime "created_at", precision: 6, null: false
-    t.datetime "updated_at", precision: 6, null: false
-    t.string "phone"
-    t.string "email"
-    t.index ["university_id"], name: "index_administration_members_on_university_id"
-    t.index ["user_id"], name: "index_administration_members_on_user_id"
-  end
-
   create_table "administration_qualiopi_criterions", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.integer "number"
     t.text "name"
@@ -501,6 +483,24 @@ ActiveRecord::Schema.define(version: 2022_01_03_174641) do
     t.string "sms_sender_name"
   end
 
+  create_table "university_people", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.uuid "university_id", null: false
+    t.uuid "user_id"
+    t.string "last_name"
+    t.string "first_name"
+    t.string "slug"
+    t.boolean "is_author"
+    t.boolean "is_researcher"
+    t.boolean "is_teacher"
+    t.boolean "is_administrative"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.string "phone"
+    t.string "email"
+    t.index ["university_id"], name: "index_university_people_on_university_id"
+    t.index ["user_id"], name: "index_university_people_on_user_id"
+  end
+
   create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.uuid "university_id", null: false
     t.string "first_name"
@@ -546,8 +546,6 @@ ActiveRecord::Schema.define(version: 2022_01_03_174641) do
 
   add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
   add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
-  add_foreign_key "administration_members", "universities"
-  add_foreign_key "administration_members", "users"
   add_foreign_key "administration_qualiopi_indicators", "administration_qualiopi_criterions", column: "criterion_id"
   add_foreign_key "communication_website_categories", "communication_website_categories", column: "parent_id"
   add_foreign_key "communication_website_categories", "communication_websites"
@@ -556,9 +554,9 @@ ActiveRecord::Schema.define(version: 2022_01_03_174641) do
   add_foreign_key "communication_website_git_files", "communication_websites", column: "website_id"
   add_foreign_key "communication_website_homes", "communication_websites"
   add_foreign_key "communication_website_homes", "universities"
-  add_foreign_key "communication_website_imported_authors", "administration_members", column: "author_id"
   add_foreign_key "communication_website_imported_authors", "communication_website_imported_websites", column: "website_id"
   add_foreign_key "communication_website_imported_authors", "universities"
+  add_foreign_key "communication_website_imported_authors", "university_people", column: "author_id"
   add_foreign_key "communication_website_imported_categories", "communication_website_categories", column: "category_id"
   add_foreign_key "communication_website_imported_categories", "communication_website_imported_websites", column: "website_id"
   add_foreign_key "communication_website_imported_categories", "universities"
@@ -584,25 +582,27 @@ ActiveRecord::Schema.define(version: 2022_01_03_174641) do
   add_foreign_key "communication_website_pages", "communication_website_pages", column: "parent_id"
   add_foreign_key "communication_website_pages", "communication_websites"
   add_foreign_key "communication_website_pages", "universities"
-  add_foreign_key "communication_website_posts", "administration_members", column: "author_id"
   add_foreign_key "communication_website_posts", "communication_websites"
   add_foreign_key "communication_website_posts", "universities"
+  add_foreign_key "communication_website_posts", "university_people", column: "author_id"
   add_foreign_key "communication_websites", "universities"
-  add_foreign_key "education_program_members", "administration_members", column: "member_id"
   add_foreign_key "education_program_members", "education_programs", column: "program_id"
+  add_foreign_key "education_program_members", "university_people", column: "member_id"
   add_foreign_key "education_programs", "education_programs", column: "parent_id"
   add_foreign_key "education_programs", "universities"
-  add_foreign_key "education_programs_teachers", "administration_members", column: "education_teacher_id"
+  add_foreign_key "education_programs_teachers", "university_people", column: "education_teacher_id"
   add_foreign_key "education_schools", "universities"
   add_foreign_key "research_journal_articles", "research_journal_volumes"
   add_foreign_key "research_journal_articles", "research_journals"
   add_foreign_key "research_journal_articles", "universities"
   add_foreign_key "research_journal_articles", "users", column: "updated_by_id"
-  add_foreign_key "research_journal_articles_researchers", "administration_members", column: "researcher_id"
   add_foreign_key "research_journal_articles_researchers", "research_journal_articles", column: "article_id"
+  add_foreign_key "research_journal_articles_researchers", "university_people", column: "researcher_id"
   add_foreign_key "research_journal_volumes", "research_journals"
   add_foreign_key "research_journal_volumes", "universities"
   add_foreign_key "research_journals", "universities"
+  add_foreign_key "university_people", "universities"
+  add_foreign_key "university_people", "users"
   add_foreign_key "users", "languages"
   add_foreign_key "users", "universities"
 end
diff --git a/test/fixtures/education/program/members.yml b/test/fixtures/education/program/members.yml
index 1b1ab21f9..ddb1da3fb 100644
--- a/test/fixtures/education/program/members.yml
+++ b/test/fixtures/education/program/members.yml
@@ -16,7 +16,7 @@
 #
 # Foreign Keys
 #
-#  fk_rails_...  (member_id => administration_members.id)
+#  fk_rails_...  (member_id => university_people.id)
 #  fk_rails_...  (program_id => education_programs.id)
 #
 
diff --git a/test/models/education/program/member_test.rb b/test/models/education/program/member_test.rb
index 3e004507a..824cc97ed 100644
--- a/test/models/education/program/member_test.rb
+++ b/test/models/education/program/member_test.rb
@@ -16,7 +16,7 @@
 #
 # Foreign Keys
 #
-#  fk_rails_...  (member_id => administration_members.id)
+#  fk_rails_...  (member_id => university_people.id)
 #  fk_rails_...  (program_id => education_programs.id)
 #
 require "test_helper"
-- 
GitLab