diff --git a/.gitignore b/.gitignore
index 5100048..b312012 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,6 @@
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
-
.idea/**/contentModel.xml
## Sensitive or high-churn files
@@ -31,4 +30,11 @@
# Others
.envrc
+# Eclipse
+
+.classpath
+.project
+.settings/
+
+# Maven
target/
diff --git a/complete-tutorial/.gitignore b/complete-tutorial/.gitignore
new file mode 100644
index 0000000..d9e5eda
--- /dev/null
+++ b/complete-tutorial/.gitignore
@@ -0,0 +1,4 @@
+# Intellij
+
+.idea
+
diff --git a/complete-tutorial/README.md b/complete-tutorial/README.md
index 46f0d32..4681997 100644
--- a/complete-tutorial/README.md
+++ b/complete-tutorial/README.md
@@ -1,5 +1,17 @@
# QuantumMaid - Creating a Complete Application
+(Author: [@lestephane](https://github.com/lestephane))
+
+Let us implement a backend in the style of todobackend.com!
+
+We’ll refer to this project as todomaid-api. PRs are welcome.
+
+Originally inspired from a [Tech Enthusiasts blog post](https://techenthusiasts.atlassian.net/wiki/spaces/TE/pages/71434262/Quantummaid+zero+to+lambda)
+
+## Step 1 - First failing test(s) ([step1/README.md](step1/README.md))
+
+---
+
This site is under construction. Contributions are greatly appreciated.
diff --git a/complete-tutorial/step1/README.md b/complete-tutorial/step1/README.md
new file mode 100644
index 0000000..a07a3ef
--- /dev/null
+++ b/complete-tutorial/step1/README.md
@@ -0,0 +1,147 @@
+# Step 1 - First failing test(s)
+
+## Initial pom.xml
+
+The `pom.xml` we'll start from is
+
+```xml
+
+ 4.0.0
+ todomaid
+ todomaid-api
+ 1.0.0
+
+
+ 11
+ true
+ ${java.version}
+ ${java.version}
+ 1.0.48
+
+
+
+
+
+ de.quantummaid.quantummaid
+ quantummaid-bom
+ ${quantummaid.version}
+ pom
+ import
+
+
+
+
+
+
+ de.quantummaid.quantummaid.packagings
+ quantummaid-essentials
+
+
+
+```
+
+- ⓵ QuantumMaid requires reflection metadata for method parameters (ie the compiler `-parameters` command-line argument). This enables it.
+
+- ⓶ In order to ensure that the various quantummaid libraries work together, we import their versions from the `quantummaid-bom` dependency, which tracks the latest good known versions.
+
+- ⓷ Grouping of dependencies that enables serving use case classes without having to hunt down artifact IDs.
+
+---
+
+## Initial main class
+
+We need a main class that will serve as the entrypoint for QuantumMaid.
+It must be located where maven expects production classes (src/main).
+
+```bash
+$ tree src/main
+src/main
+└── java
+ └── todomaid
+ └── api
+ └── Server.java
+```
+
+An initial version of the Server class will dump all requests to System.err:
+
+```java
+package todomaid.api;
+...
+public final class Server {
+ public static void main(String[] args) {
+ serverInstance(8080).run();
+ }
+
+ @NotNull
+ private static QuantumMaid serverInstance(int port) {
+ QuantumMaid quantumMaid = quantumMaid()
+ .withHttpMaid(anHttpMaid()
+ .get("/*", dumpRequest())
+ //.options("/*", dumpRequest()) ⓵
+ //.patch("/*", dumpRequest()) ⓶
+ .post("/*", dumpRequest())
+ .put("/*", dumpRequest())
+ .delete("/*", dumpRequest()).build())
+ .withLocalHostEndpointOnPort(port);
+ return quantumMaid;
+ }
+
+ private static HttpHandler dumpRequest() {
+ return (req, res) ->
+ System.err.printf("%s %s %n", req.method(), req.path());
+ }
+}
+```
+
+⓵ ⓶ [Additional support](https://github.com/quantummaid/httpmaid/issues/80) is needed to catch these request methods. An any() routing method will further reduce the method size.
+
+---
+
+## First start
+
+Starting the server is a rather involved maven command, and I never remember how to do it, so here it is:
+
+```shell
+(in terminal 1)
+$ mvn exec:java -Dexec.mainClass="todomaid.api.Server"
+...
+21:28:41.373 [todomaid.api.Server.main()] INFO de.quantummaid.quantummaid.QuantumMaid -
+ ____ _ __ __ _ _
+ / __ \ | | | \/ | (_) | |
+ | | | |_ _ __ _ _ __ | |_ _ _ _ __ ___ | \ / | __ _ _ __| |
+ | | | | | | |/ _` | '_ \| __| | | | '_ ` _ \| |\/| |/ _` | |/ _` |
+ | |__| | |_| | (_| | | | | |_| |_| | | | | | | | | | (_| | | (_| |
+ \___\_\\__,_|\__,_|_| |_|\__|\__,_|_| |_| |_|_| |_|\__,_|_|\__,_|
+
+21:28:41.374 [todomaid.api.Server.main()] INFO de.quantummaid.quantummaid.QuantumMaid - Startup took: 341ms (317ms initialization, 24ms endpoint startup)
+21:28:41.376 [todomaid.api.Server.main()] INFO de.quantummaid.quantummaid.QuantumMaid - Serving http://localhost:8080/
+21:28:41.376 [todomaid.api.Server.main()] INFO de.quantummaid.quantummaid.QuantumMaid - Ready.
+```
+
+Run a curl command from another terminal to verify that the server is receiving requests
+
+```shell
+(in terminal 2)
+$ curl localhost:8080
+```
+
+As expected, the server dumps the request to System.err
+
+```shell
+(in terminal 1)
+HttpRequestMethod(value=GET) Path(path=/)
+```
+
+Let's see the extent of the endpoints we need to support by running the todobackend test suite:
+
+```bash
+$ cd /tmp
+$ git clone https://github.com/TodoBackend/todo-backend-js-spec.git
+$ cd todo-backend-js-spec
+$ firefox index.html
+(enter http://localhost:8080)
+```
+
+The server output STDERR output is rather verbose with internal server errors caused by unmapped OPTIONS request. This is tracked under issue https://github.com/quantummaid/httpmaid/issues/81
+
+## To be continued...
diff --git a/complete-tutorial/step1/pom.xml b/complete-tutorial/step1/pom.xml
new file mode 100644
index 0000000..9085591
--- /dev/null
+++ b/complete-tutorial/step1/pom.xml
@@ -0,0 +1,37 @@
+
+
+ 4.0.0
+
+ todomaid
+ todomaid-api
+ 1.0.0
+
+
+ 11
+ true
+ ${java.version}
+ ${java.version}
+ 1.0.48
+
+
+
+
+
+ de.quantummaid.quantummaid
+ quantummaid-bom
+ ${quantummaid.version}
+ import
+ pom
+
+
+
+
+
+
+ de.quantummaid.quantummaid.packagings
+ quantummaid-essentials
+
+
+
diff --git a/complete-tutorial/step1/src/main/java/todomaid/api/Server.java b/complete-tutorial/step1/src/main/java/todomaid/api/Server.java
new file mode 100644
index 0000000..d29fadd
--- /dev/null
+++ b/complete-tutorial/step1/src/main/java/todomaid/api/Server.java
@@ -0,0 +1,33 @@
+package todomaid.api;
+
+import de.quantummaid.httpmaid.handler.http.HttpHandler;
+import de.quantummaid.quantummaid.QuantumMaid;
+import org.jetbrains.annotations.NotNull;
+
+import static de.quantummaid.httpmaid.HttpMaid.anHttpMaid;
+import static de.quantummaid.quantummaid.QuantumMaid.quantumMaid;
+
+public final class Server {
+ public static void main(String[] args) {
+ serverInstance(8080).run();
+ }
+
+ @NotNull
+ private static QuantumMaid serverInstance(int port) {
+ QuantumMaid quantumMaid = quantumMaid()
+ .withHttpMaid(anHttpMaid()
+ .get("/*", dumpRequest())
+ //.options("/*", dumpRequest())
+ //.patch("/*", dumpRequest())
+ .post("/*", dumpRequest())
+ .put("/*", dumpRequest())
+ .delete("/*", dumpRequest()).build())
+ .withLocalHostEndpointOnPort(port);
+ return quantumMaid;
+ }
+
+ private static HttpHandler dumpRequest() {
+ return (request, response) -> System.err.printf("%s %s %n", request.method(), request.path());
+ }
+}
+