diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index dd6653532182e805771d3ac942dc2b4172b18dc8..9e8543f8dc3390b8e217b835faa490ac3ddc906c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -42,3 +42,4 @@ include:
   - local: "/java-memoizers/.gitlab-ci.yml"
   - local: "/markov-chain/.gitlab-ci.yml"
   - local: "/names/.gitlab-ci.yml"
+  - local: "/employee-report-2/.gitlab-ci.yml"
diff --git a/employee-report-2/.gitlab-ci.yml b/employee-report-2/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d5bc9b437be0202d03fcc6af14ef202e7444aef2
--- /dev/null
+++ b/employee-report-2/.gitlab-ci.yml
@@ -0,0 +1,11 @@
+package-employee-report-2:
+  variables:
+    PROJECT_FOLDER: "employee-report-2"
+  extends: .java
+  only:
+    refs:
+      - master
+      - merge_requests
+    changes:
+      - ".gitlab-common-ci.yml"
+      - "employee-report-2/**/*"
diff --git a/employee-report-2/pom.xml b/employee-report-2/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aaf29090ac8c71f1e044de91f6c8136c90cdbe98
--- /dev/null
+++ b/employee-report-2/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <version>1.0.0</version>
+    <groupId>fr.ippon.kata</groupId>
+    <artifactId>java-parent</artifactId>
+    <relativePath>../java-parent</relativePath>
+  </parent>
+
+  <version>1.0.0-SNAPSHOT</version>
+  <artifactId>employee-report-2</artifactId>
+
+  <name>EmployeeReport2</name>
+
+  <developers>
+    <developer>
+      <email>kgrammont@ippon.fr</email>
+      <name>Ketil GRAMMONT</name>
+    </developer>
+    <developer>
+      <email>cdamon@ippon.fr</email>
+      <name>Colin DAMON</name>
+    </developer>
+  </developers>
+</project>
diff --git a/employee-report-2/readme.md b/employee-report-2/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..52685b5bf8ad4c40c03b036eb4d21ae0db44be33
--- /dev/null
+++ b/employee-report-2/readme.md
@@ -0,0 +1,9 @@
+# Employee report
+
+Résolution en TDD et en Java du kata [EmployeeReport](https://codingdojo.org/kata/Employee-Report/).
+
+-   **Auteurs** : Ketil GRAMMONT et Colin DAMON
+-   **Date** : 13/10/2021
+-   **Langage** : Java
+-   **Niveau** : Facile
+-   **Replay** : [Twitch](https://www.twitch.tv/videos/1175612810)
diff --git a/employee-report-2/src/main/java/fr/ippon/employee/Employee.java b/employee-report-2/src/main/java/fr/ippon/employee/Employee.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b79f5d8e5ab22828404ba0337cd3415ed1856d0
--- /dev/null
+++ b/employee-report-2/src/main/java/fr/ippon/employee/Employee.java
@@ -0,0 +1,39 @@
+package fr.ippon.employee;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public record Employee(String name, int age) {
+
+  private static Pattern NAME_PATTERN = Pattern
+      .compile("(\\p{L}+)(\\P{L}*)");
+
+  public Employee(String name, int age) {
+    this.name = format(name);
+    this.age = age;
+  }
+
+  private String format(String name) {
+    Matcher matcher = NAME_PATTERN.matcher(name);
+
+    StringBuilder result = new StringBuilder();
+    while (matcher.find()) {
+      result.append(capitalize(matcher.group(1)))
+          .append(matcher.group(2));
+    }
+
+    return result.toString();
+  }
+
+  private String capitalize(String word) {
+    return word.substring(0, 1)
+        .toUpperCase()
+        + word.substring(1, word.length())
+            .toLowerCase();
+  }
+
+  boolean isAdult() {
+    return age >= 18;
+  }
+
+}
diff --git a/employee-report-2/src/main/java/fr/ippon/employee/Employees.java b/employee-report-2/src/main/java/fr/ippon/employee/Employees.java
new file mode 100644
index 0000000000000000000000000000000000000000..31b7d581883f71da8e3fc47875261146635fd573
--- /dev/null
+++ b/employee-report-2/src/main/java/fr/ippon/employee/Employees.java
@@ -0,0 +1,27 @@
+package fr.ippon.employee;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+
+public class Employees {
+
+  private final List<Employee> employees;
+
+  public Employees(Employee... employees) {
+    this.employees = List.of(employees);
+  }
+
+  public Collection<Employee> get() {
+    return employees;
+  }
+
+  public Collection<String> sundayWorkers() {
+    return employees.stream()
+        .filter(Employee::isAdult)
+        .map(Employee::name)
+        .sorted(Comparator.reverseOrder())
+        .toList();
+  }
+
+}
diff --git a/employee-report-2/src/test/java/fr/ippon/employee/EmployeeReportTest.java b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeReportTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b696535393a0743cf6836161718634493c86288
--- /dev/null
+++ b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeReportTest.java
@@ -0,0 +1,37 @@
+package fr.ippon.employee;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+class EmployeeReportTest {
+
+  @Test
+  void shouldGetEmployees() {
+    Employees employees = new Employees(mike());
+
+    assertThat(employees.get()).containsExactly(mike());
+  }
+
+  @Test
+  void shouldGetUnmodifiableEmployees() {
+    assertThatThrownBy(() -> new Employees().get()
+        .clear()).isExactlyInstanceOf(
+            UnsupportedOperationException.class);
+  }
+
+  @Test
+  void shouldGetSundayWorkers() {
+    Employees employees = new Employees(
+        new Employee("Max", 17), mike(),
+        new Employee("jean charles", 18));
+
+    assertThat(employees.sundayWorkers())
+        .containsExactly("Mike", "Jean Charles");
+  }
+
+  private Employee mike() {
+    return new Employee("MIKE", 51);
+  }
+
+}
diff --git a/employee-report-2/src/test/java/fr/ippon/employee/EmployeeTest.java b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..793b991e9a8e0f32ba80102ed57d73ead47233da
--- /dev/null
+++ b/employee-report-2/src/test/java/fr/ippon/employee/EmployeeTest.java
@@ -0,0 +1,30 @@
+package fr.ippon.employee;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+class EmployeeTest {
+
+  @Test
+  void shouldCapitalizeSimpleName() {
+    Employee employee = new Employee("jeaN", 14);
+
+    assertThat(employee.name()).isEqualTo("Jean");
+  }
+
+  @Test
+  void shouldCapitalizeComposedName() {
+    Employee employee = new Employee("jean-charles", 14);
+
+    assertThat(employee.name()).isEqualTo("Jean-Charles");
+  }
+
+  @Test
+  void shouldCapitalizeComposedNameWithAccents() {
+    Employee employee = new Employee("jean jérémie", 14);
+
+    assertThat(employee.name()).isEqualTo("Jean Jérémie");
+  }
+
+}
diff --git a/readme.md b/readme.md
index fbf8314451f27fde268d227593d1ec7b45a6e4df..de0fbc4dc40837e9f72ddcba5b8f01055fd8727e 100644
--- a/readme.md
+++ b/readme.md
@@ -27,6 +27,7 @@ Un kata de code est un petit exercice pensé pour s'entrainer jusqu'à maitriser
 -   [Fizz Buzz](/fizz-buzz)
 -   [Leap years](/leap-years)
 -   [Employee report](/employee-report)
+-   [Employee report 2](/employee-report-2)
 
 ### Moyen