diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.md b/.github/ISSUE_TEMPLATE/1_Bug_report.md
deleted file mode 100644
index 3a3e9fd4de1db2988c87fc7e1395ed435288ccc4..0000000000000000000000000000000000000000
--- a/.github/ISSUE_TEMPLATE/1_Bug_report.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-name: 🐛 Bug Report
-about: ⚠️ See below for security reports
-labels: Bug
-
----
-
-**Version(s) affected**: x.y.z
-
-**Description**
-<!-- A clear and concise description of the problem. -->
-
-**How to reproduce**
-<!-- Code and/or config needed to reproduce the problem. If it's a complex bug,
-     create a "bug reproducer" as explained in: -->
-
-**Possible Solution**
-<!--- Optional: only if you have suggestions on a fix/reason for the bug -->
-
-**Additional context**
-<!-- Optional: any other context about the problem: log messages, screenshots, etc. -->
diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.yaml b/.github/ISSUE_TEMPLATE/1_Bug_report.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..841cfdc01291a0ce2c7febbf5d53745c5ccb6ec7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/1_Bug_report.yaml
@@ -0,0 +1,43 @@
+name: 🐛 Bug Report
+description: ⚠️ NEVER report security issues, email security AT spomky-labs.com instead
+labels: Bug
+
+body:
+ - type: input
+   id: affected-versions
+   attributes:
+    label: Version(s) affected
+    placeholder: x.y.z
+   validations:
+    required: true
+ - type: textarea
+   id: description
+   attributes:
+    label: Description
+    description: A clear and concise description of the problem
+   validations:
+    required: true
+ - type: textarea
+   id: how-to-reproduce
+   attributes:
+    label: How to reproduce
+    description: |
+     ⚠️  This is the most important part of the report ⚠️
+     Without a way to easily reproduce your issue, there is little chance we will be able to help you and work on a fix.
+     Please, take the time to show us some code and/or config that is needed for others to reproduce the problem easily.
+     Most of the time, creating a "bug reproducer" is the best way to help us and increases the chances someone
+     will have a look at it.
+   validations:
+    required: true
+ - type: textarea
+   id: possible-solution
+   attributes:
+    label: Possible Solution
+    description: |
+     Optional: only if you have suggestions on a fix/reason for the bug
+     Don't hesitate to create a pull request with your solution, it helps get faster feedback.
+ - type: textarea
+   id: additional-context
+   attributes:
+    label: Additional Context
+    description: "Optional: any other context about the problem: log messages, screenshots, etc."
diff --git a/.github/ISSUE_TEMPLATE/2_Feature_request.md b/.github/ISSUE_TEMPLATE/2_Feature_request.md
deleted file mode 100644
index 8ffd9746dfbf5789e756309c107eb881a8aa6a52..0000000000000000000000000000000000000000
--- a/.github/ISSUE_TEMPLATE/2_Feature_request.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-name: 🚀 Feature Request
-about: Ideas for new features and improvements
-
----
-
-**Description**
-<!-- A clear and concise description of the new feature. -->
-
-**Example**
-<!-- A simple example of the new feature in action (include PHP code, YAML config, etc.)
-     If the new feature changes an existing feature, include a simple before/after comparison. -->
diff --git a/.github/ISSUE_TEMPLATE/2_Feature_request.yaml b/.github/ISSUE_TEMPLATE/2_Feature_request.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bd300eb1e82b265ed3b47052863d05504e029a75
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/2_Feature_request.yaml
@@ -0,0 +1,17 @@
+name: 🚀 Feature Request
+description: RFC and ideas for new features and improvements
+body:
+    - type: textarea
+      id: description
+      attributes:
+          label: Description
+          description: A clear and concise description of the new feature
+      validations:
+          required: true
+    - type: textarea
+      id: example
+      attributes:
+          label: Example
+          description: |
+              A simple example of the new feature in action (include PHP code, YAML config, etc.)
+              If the new feature changes an existing feature, include a simple before/after comparison.
diff --git a/.github/ISSUE_TEMPLATE/3_Documentation.yaml b/.github/ISSUE_TEMPLATE/3_Documentation.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7a3dc1785d3ccbfe76cb1f3dc596ce18fb39e8d1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/3_Documentation.yaml
@@ -0,0 +1,10 @@
+name: 📖 Documentation Issue
+description: To report typo or obsolete section in the documentation
+body:
+    - type: textarea
+      id: description
+      attributes:
+          label: Description
+          description: A clear and concise description of the error you found in the documentation
+      validations:
+          required: true
diff --git a/.github/ISSUE_TEMPLATE/3_Documentation_issue.md b/.github/ISSUE_TEMPLATE/3_Documentation_issue.md
deleted file mode 100644
index 26cd199c1df604f880c14ea1f58e7ca0e5bea21f..0000000000000000000000000000000000000000
--- a/.github/ISSUE_TEMPLATE/3_Documentation_issue.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-name: 📖 Documentation Issue
-about: To report typo or obsolete section in the documentation
-
----
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index dde06cf341221f7468a2cd6e426d292df2d61398..11812417c42426de5865c54614713516f84fadfb 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,5 @@
 blank_issues_enabled: false
 contact_links:
-  - name: Support Question
-    url: https://spomky-labs.com/contact/
-    about: We use GitHub issues only to discuss about bugs and new features. For this kind of questions about using the library, please use Stackoverflow (or similar) or send a quote request at https://spomky-labs.com/contact/
+    - name: Support Question
+      url: https://spomky-labs.com/contact/
+      about: We use GitHub issues only to discuss about bugs and new features. For this kind of questions about using the library, please use Stackoverflow (or similar) or send a quote request at https://spomky-labs.com/contact/
diff --git a/Makefile b/Makefile
index e96bc55c1ef080a10890c5464edf77574bd03665..bf8a8afb248251607cd53af3d666667e5e10655e 100644
--- a/Makefile
+++ b/Makefile
@@ -22,13 +22,7 @@ all: vendor ## Run all tests
 	vendor/bin/phpunit --color
 
 tu: vendor ## Run only unit tests
-	vendor/bin/phpunit --color tests/Unit
-
-ti: vendor ## Run only integration tests
-	vendor/bin/phpunit --color tests/Integration
-
-tf: vendor ## Run only functional tests
-	vendor/bin/phpunit --color tests/Functional
+	vendor/bin/phpunit --color tests
 
 st: vendor ## Run static analyse
 	vendor/bin/phpstan analyse
@@ -49,20 +43,9 @@ rector: vendor ## Check all files using Rector
 #        Others        #
 ########################
 
-twig-lint: vendor ## All Twig template checks
-	bin/console lint:twig templates/
-
 mu: vendor ## Mutation tests
 	vendor/bin/infection -s --threads=$(nproc) --min-msi=70 --min-covered-msi=50 --test-framework-options="--exclude-group=Performance"
 
-db: vendor ## Create the database (should only be used in local env
-	bin/console doctrine:database:drop --env=test --force
-	bin/console doctrine:database:create --env=test
-	bin/console doctrine:schema:create --env=test
-
-clean: vendor ## Cleanup the var folder
-	rm -rf var
-
 cc: vendor ## Show test coverage rates (HTML)
 	vendor/bin/phpunit --coverage-html ./build
 
diff --git a/README.md b/README.md
index f4eb3c6dbdcbd6f5f293974dbe9b0226d5fc5c10..88956b99285c7f3f1bce190fac0023f342e05a51 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ TOTP / HOTP library in PHP
 [![Latest Unstable Version](https://poser.pugx.org/spomky-labs/otphp/v/unstable.png)](https://packagist.org/packages/spomky-labs/otphp)
 [![License](https://poser.pugx.org/spomky-labs/otphp/license.png)](https://packagist.org/packages/spomky-labs/otphp)
 
-A php library for generating one-time passwords according to [RFC 4226](http://tools.ietf.org/html/rfc4226) (HOTP Algorithm) and [RFC 6238](http://tools.ietf.org/html/rfc6238) (TOTP Algorithm)
+A php library for generating one-time passwords according to [RFC 4226](https://datatracker.ietf.org/doc/html/rfc4226) (HOTP Algorithm) and [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238) (TOTP Algorithm)
 
 This library is compatible with Google Authenticator apps available for Android and iPhone.
 It is also compatible with other applications such as [FreeOTP](https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp) for example.
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 116a7f440b1ceefacc23e1d8a234e43780aa5f15..d4bd675ced25b45caddb42640b5d2e4ce31fae43 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,18 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" backupStaticAttributes="false" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" bootstrap="vendor/autoload.php" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
   <coverage>
     <include>
-      <directory suffix=".php">./</directory>
+      <directory suffix=".php">./src</directory>
     </include>
-    <exclude>
-      <directory>./tests</directory>
-      <directory>./doc</directory>
-      <directory>./vendor</directory>
-    </exclude>
   </coverage>
   <testsuites>
     <testsuite name="OTP Test Suite">
-      <directory suffix="Test.php">./tests</directory>
+      <directory>./tests</directory>
     </testsuite>
   </testsuites>
   <listeners>
diff --git a/rector.php b/rector.php
index 1f7b45d747641fcd7c57709e1bb5f081b5105148..a90482a36f5f658cec165ed442a08461af15469e 100644
--- a/rector.php
+++ b/rector.php
@@ -6,31 +6,35 @@ use Rector\Config\RectorConfig;
 use Rector\Core\ValueObject\PhpVersion;
 use Rector\Doctrine\Set\DoctrineSetList;
 use Rector\Php74\Rector\Property\TypedPropertyRector;
+use Rector\PHPUnit\Set\PHPUnitLevelSetList;
 use Rector\PHPUnit\Set\PHPUnitSetList;
 use Rector\Set\ValueObject\LevelSetList;
 use Rector\Set\ValueObject\SetList;
 use Rector\Symfony\Set\SymfonyLevelSetList;
 use Rector\Symfony\Set\SymfonySetList;
 
-return static function (RectorConfig $rectorConfig): void {
-    $rectorConfig->import(SetList::DEAD_CODE);
-    $rectorConfig->import(LevelSetList::UP_TO_PHP_81);
-    $rectorConfig->import(SymfonyLevelSetList::UP_TO_SYMFONY_60);
-    $rectorConfig->import(SymfonySetList::SYMFONY_CODE_QUALITY);
-    $rectorConfig->import(SymfonySetList::SYMFONY_52_VALIDATOR_ATTRIBUTES);
-    $rectorConfig->import(SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION);
-    $rectorConfig->import(SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES);
-    $rectorConfig->import(DoctrineSetList::DOCTRINE_CODE_QUALITY);
-    $rectorConfig->import(DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES);
-    $rectorConfig->import(PHPUnitSetList::PHPUNIT_EXCEPTION);
-    $rectorConfig->import(PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD);
-    $rectorConfig->import(PHPUnitSetList::PHPUNIT_91);
-    $rectorConfig->import(PHPUnitSetList::PHPUNIT_YIELD_DATA_PROVIDER);
-    $rectorConfig->paths([__DIR__ . '/src']);
-    $rectorConfig->phpVersion(PhpVersion::PHP_81);
-    $rectorConfig->importNames();
-    $rectorConfig->importShortClasses();
+return static function (RectorConfig $config): void {
+    $config->sets([
+        SetList::DEAD_CODE,
+        LevelSetList::UP_TO_PHP_81,
+        SymfonyLevelSetList::UP_TO_SYMFONY_54,
+        SymfonySetList::SYMFONY_CODE_QUALITY,
+        SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION,
+        SymfonySetList::SYMFONY_STRICT,
+        DoctrineSetList::DOCTRINE_CODE_QUALITY,
+        DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
+        PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD,
+        PHPUnitLevelSetList::UP_TO_PHPUNIT_100,
+        PHPUnitSetList::PHPUNIT_CODE_QUALITY,
+        PHPUnitSetList::PHPUNIT_EXCEPTION,
+        PHPUnitSetList::REMOVE_MOCKS,
+        PHPUnitSetList::PHPUNIT_YIELD_DATA_PROVIDER,
+    ]);
+    $config->services()->set(TypedPropertyRector::class);
+    $config->parallel();
+    $config->paths([__DIR__ . '/src']);
+    $config->phpVersion(PhpVersion::PHP_81);
+    $config->importNames();
+    $config->importShortClasses();
 
-    $services = $rectorConfig->services();
-    $services->set(TypedPropertyRector::class);
 };
diff --git a/src/Factory.php b/src/Factory.php
index 1260c71643c9698fc771c2acc7fc1a6794087934..b904c399249f53d08da5d3cbbf7f02e18b34b7e3 100644
--- a/src/Factory.php
+++ b/src/Factory.php
@@ -11,6 +11,8 @@ use Throwable;
 
 /**
  * This class is used to load OTP object from a provisioning Uri.
+ *
+ * @see \OTPHP\Test\FactoryTest
  */
 final class Factory implements FactoryInterface
 {
diff --git a/src/HOTP.php b/src/HOTP.php
index 9c278c212ddf03c9e43c79f731d2aa84a57c3dc6..b07da78f8e34d97e6fe20ff8cb3013680a0af4db 100644
--- a/src/HOTP.php
+++ b/src/HOTP.php
@@ -6,6 +6,9 @@ namespace OTPHP;
 
 use Assert\Assertion;
 
+/**
+ * @see \OTPHP\Test\HOTPTest
+ */
 final class HOTP extends OTP implements HOTPInterface
 {
     protected function __construct(null|string $secret, int $counter, string $digest, int $digits)
diff --git a/src/TOTP.php b/src/TOTP.php
index 18b48a8bae5669c5644ee81f76ad305f76aaaa08..881a1afefb1dde62ea61bafb3b10f71957b9b766 100644
--- a/src/TOTP.php
+++ b/src/TOTP.php
@@ -6,6 +6,9 @@ namespace OTPHP;
 
 use Assert\Assertion;
 
+/**
+ * @see \OTPHP\Test\TOTPTest
+ */
 final class TOTP extends OTP implements TOTPInterface
 {
     protected function __construct(null|string $secret, int $period, string $digest, int $digits, int $epoch = 0)