You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2020/01/26 15:57:43 UTC

[isis] 08/14: ISIS-2062: updates to simpleapp about.adoc

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 7e8012ad736f560edb63f1bb9fff3125be8bc07a
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Jan 26 15:01:21 2020 +0000

    ISIS-2062: updates to simpleapp about.adoc
---
 .../images/simpleapp-webapp-before-launch.png      |  Bin 40147 -> 19629 bytes
 .../images/simpleapp-webapp-with-fixtures.png      |  Bin 32657 -> 0 bytes
 .../modules/simpleapp/images/simpleapp-webapp.png  |  Bin 32086 -> 30961 bytes
 .../images/using-simple-app/030-home-page.png      |  Bin 24943 -> 0 bytes
 .../040-run-fixture-script-menu.png                |  Bin 37569 -> 0 bytes
 .../050-run-fixture-script-prompt.png              |  Bin 34941 -> 0 bytes
 .../060-run-fixture-script-result.png              |  Bin 43088 -> 0 bytes
 .../images/using-simple-app/070-home-page.png      |  Bin 26848 -> 0 bytes
 .../using-simple-app/structure/structure.pptx      |  Bin 70518 -> 0 bytes
 .../structure/structure/Slide1.PNG                 |  Bin 43039 -> 0 bytes
 .../structure/structure/Slide2.PNG                 |  Bin 22610 -> 0 bytes
 .../simpleapp/images/using/010-root-page.png       |  Bin 0 -> 61914 bytes
 .../images/using/020-login-to-wicket-viewer.png    |  Bin 0 -> 20182 bytes
 .../simpleapp/images/using/030-home-page.png       |  Bin 0 -> 27296 bytes
 .../images/using/032-run-fixture-script-prompt.png |  Bin 0 -> 56350 bytes
 .../images/using/033-run-fixture-script-prompt.png |  Bin 0 -> 44931 bytes
 .../images/using/034-run-fixture-script-result.png |  Bin 0 -> 73824 bytes
 .../036-home-page-after-fixture-scriptpng.png      |  Bin 0 -> 38898 bytes
 .../images/using/040-create-object-from-menu.png   |  Bin 0 -> 42212 bytes
 .../using/050-create-object-from-menu-prompt.png   |  Bin 0 -> 46227 bytes
 .../simpleapp/images/using/060-created-object.png  |  Bin 0 -> 37716 bytes
 .../simpleapp/images/using/070-update-name.png     |  Bin 0 -> 36822 bytes
 .../images/using/075-publish-logging-1.png         |  Bin 0 -> 108407 bytes
 .../images/using/076-publish-logging-2.png         |  Bin 0 -> 55741 bytes
 .../simpleapp/images/using/080-edit-notes.png      |  Bin 0 -> 41764 bytes
 .../simpleapp/images/using/090-delete-object.png   |  Bin 0 -> 47073 bytes
 .../simpleapp/images/using/100-object-deleted.png  |  Bin 0 -> 41610 bytes
 .../images/using/200-swagger-ui-before-reload.png  |  Bin 0 -> 59936 bytes
 .../images/using/210-simpleapp-resources.png       |  Bin 0 -> 80626 bytes
 .../using/220-create-object-thru-rest-api.png      |  Bin 0 -> 27857 bytes
 .../230-create-object-thru-rest-api-response.png   |  Bin 0 -> 45720 bytes
 .../using/240-retrieve-object-using-rest-api.png   |  Bin 0 -> 37255 bytes
 ...250-retrieve-object-using-rest-api-response.png |  Bin 0 -> 50220 bytes
 starters/adoc/modules/simpleapp/nav.adoc           |    2 +-
 starters/adoc/modules/simpleapp/pages/about.adoc   | 1148 +++++++++++---------
 35 files changed, 626 insertions(+), 524 deletions(-)

diff --git a/starters/adoc/modules/simpleapp/images/simpleapp-webapp-before-launch.png b/starters/adoc/modules/simpleapp/images/simpleapp-webapp-before-launch.png
index de1ca7e..5b720bd 100644
Binary files a/starters/adoc/modules/simpleapp/images/simpleapp-webapp-before-launch.png and b/starters/adoc/modules/simpleapp/images/simpleapp-webapp-before-launch.png differ
diff --git a/starters/adoc/modules/simpleapp/images/simpleapp-webapp-with-fixtures.png b/starters/adoc/modules/simpleapp/images/simpleapp-webapp-with-fixtures.png
deleted file mode 100644
index 292698f..0000000
Binary files a/starters/adoc/modules/simpleapp/images/simpleapp-webapp-with-fixtures.png and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/simpleapp-webapp.png b/starters/adoc/modules/simpleapp/images/simpleapp-webapp.png
index 482531b..4f492a7 100644
Binary files a/starters/adoc/modules/simpleapp/images/simpleapp-webapp.png and b/starters/adoc/modules/simpleapp/images/simpleapp-webapp.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/030-home-page.png b/starters/adoc/modules/simpleapp/images/using-simple-app/030-home-page.png
deleted file mode 100644
index db90e27..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/030-home-page.png and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/040-run-fixture-script-menu.png b/starters/adoc/modules/simpleapp/images/using-simple-app/040-run-fixture-script-menu.png
deleted file mode 100644
index 3d55dab..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/040-run-fixture-script-menu.png and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/050-run-fixture-script-prompt.png b/starters/adoc/modules/simpleapp/images/using-simple-app/050-run-fixture-script-prompt.png
deleted file mode 100644
index fb8e703..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/050-run-fixture-script-prompt.png and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/060-run-fixture-script-result.png b/starters/adoc/modules/simpleapp/images/using-simple-app/060-run-fixture-script-result.png
deleted file mode 100644
index b79034f..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/060-run-fixture-script-result.png and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/070-home-page.png b/starters/adoc/modules/simpleapp/images/using-simple-app/070-home-page.png
deleted file mode 100644
index 047b5a0..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/070-home-page.png and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure.pptx b/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure.pptx
deleted file mode 100644
index a3323c2..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure.pptx and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure/Slide1.PNG b/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure/Slide1.PNG
deleted file mode 100644
index 169ab79..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure/Slide1.PNG and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure/Slide2.PNG b/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure/Slide2.PNG
deleted file mode 100644
index 9c44b93..0000000
Binary files a/starters/adoc/modules/simpleapp/images/using-simple-app/structure/structure/Slide2.PNG and /dev/null differ
diff --git a/starters/adoc/modules/simpleapp/images/using/010-root-page.png b/starters/adoc/modules/simpleapp/images/using/010-root-page.png
new file mode 100644
index 0000000..7557458
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/010-root-page.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/020-login-to-wicket-viewer.png b/starters/adoc/modules/simpleapp/images/using/020-login-to-wicket-viewer.png
new file mode 100644
index 0000000..3623000
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/020-login-to-wicket-viewer.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/030-home-page.png b/starters/adoc/modules/simpleapp/images/using/030-home-page.png
new file mode 100644
index 0000000..e48a0be
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/030-home-page.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/032-run-fixture-script-prompt.png b/starters/adoc/modules/simpleapp/images/using/032-run-fixture-script-prompt.png
new file mode 100644
index 0000000..f4616a4
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/032-run-fixture-script-prompt.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/033-run-fixture-script-prompt.png b/starters/adoc/modules/simpleapp/images/using/033-run-fixture-script-prompt.png
new file mode 100644
index 0000000..f375c51
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/033-run-fixture-script-prompt.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/034-run-fixture-script-result.png b/starters/adoc/modules/simpleapp/images/using/034-run-fixture-script-result.png
new file mode 100644
index 0000000..ed922d3
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/034-run-fixture-script-result.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/036-home-page-after-fixture-scriptpng.png b/starters/adoc/modules/simpleapp/images/using/036-home-page-after-fixture-scriptpng.png
new file mode 100644
index 0000000..27e5685
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/036-home-page-after-fixture-scriptpng.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/040-create-object-from-menu.png b/starters/adoc/modules/simpleapp/images/using/040-create-object-from-menu.png
new file mode 100644
index 0000000..533839a
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/040-create-object-from-menu.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/050-create-object-from-menu-prompt.png b/starters/adoc/modules/simpleapp/images/using/050-create-object-from-menu-prompt.png
new file mode 100644
index 0000000..76c257c
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/050-create-object-from-menu-prompt.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/060-created-object.png b/starters/adoc/modules/simpleapp/images/using/060-created-object.png
new file mode 100644
index 0000000..3dda726
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/060-created-object.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/070-update-name.png b/starters/adoc/modules/simpleapp/images/using/070-update-name.png
new file mode 100644
index 0000000..80a1a09
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/070-update-name.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/075-publish-logging-1.png b/starters/adoc/modules/simpleapp/images/using/075-publish-logging-1.png
new file mode 100644
index 0000000..dee1849
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/075-publish-logging-1.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/076-publish-logging-2.png b/starters/adoc/modules/simpleapp/images/using/076-publish-logging-2.png
new file mode 100644
index 0000000..9cb12ee
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/076-publish-logging-2.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/080-edit-notes.png b/starters/adoc/modules/simpleapp/images/using/080-edit-notes.png
new file mode 100644
index 0000000..4354ae0
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/080-edit-notes.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/090-delete-object.png b/starters/adoc/modules/simpleapp/images/using/090-delete-object.png
new file mode 100644
index 0000000..89baeea
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/090-delete-object.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/100-object-deleted.png b/starters/adoc/modules/simpleapp/images/using/100-object-deleted.png
new file mode 100644
index 0000000..3f51747
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/100-object-deleted.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/200-swagger-ui-before-reload.png b/starters/adoc/modules/simpleapp/images/using/200-swagger-ui-before-reload.png
new file mode 100644
index 0000000..9afbd86
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/200-swagger-ui-before-reload.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/210-simpleapp-resources.png b/starters/adoc/modules/simpleapp/images/using/210-simpleapp-resources.png
new file mode 100644
index 0000000..e41d365
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/210-simpleapp-resources.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/220-create-object-thru-rest-api.png b/starters/adoc/modules/simpleapp/images/using/220-create-object-thru-rest-api.png
new file mode 100644
index 0000000..180a79d
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/220-create-object-thru-rest-api.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/230-create-object-thru-rest-api-response.png b/starters/adoc/modules/simpleapp/images/using/230-create-object-thru-rest-api-response.png
new file mode 100644
index 0000000..f9c4720
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/230-create-object-thru-rest-api-response.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/240-retrieve-object-using-rest-api.png b/starters/adoc/modules/simpleapp/images/using/240-retrieve-object-using-rest-api.png
new file mode 100644
index 0000000..a4af1b5
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/240-retrieve-object-using-rest-api.png differ
diff --git a/starters/adoc/modules/simpleapp/images/using/250-retrieve-object-using-rest-api-response.png b/starters/adoc/modules/simpleapp/images/using/250-retrieve-object-using-rest-api-response.png
new file mode 100644
index 0000000..791d7a0
Binary files /dev/null and b/starters/adoc/modules/simpleapp/images/using/250-retrieve-object-using-rest-api-response.png differ
diff --git a/starters/adoc/modules/simpleapp/nav.adoc b/starters/adoc/modules/simpleapp/nav.adoc
index 026a8cd..f613038 100644
--- a/starters/adoc/modules/simpleapp/nav.adoc
+++ b/starters/adoc/modules/simpleapp/nav.adoc
@@ -1,2 +1,2 @@
-* xref:about.adoc[Simple App starter app]
+* xref:about.adoc[Simple App]
 
diff --git a/starters/adoc/modules/simpleapp/pages/about.adoc b/starters/adoc/modules/simpleapp/pages/about.adoc
index 5b83678..249248a 100644
--- a/starters/adoc/modules/simpleapp/pages/about.adoc
+++ b/starters/adoc/modules/simpleapp/pages/about.adoc
@@ -1,20 +1,12 @@
 = Simple App Starter App
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 
-NOTE: these notes are out-of-date and need to be reviewed.
+The quickest way to get started building an application "for real" is to use the `simpleapp` starter app.
 
-The quickest way to get started building an application "for real" is to run the `simpleapp` archetype.
-Like the link:https://github.com/apache/isis-app-helloworld[helloworld starter app], this too will generate a very simple one-class domain model (an entity called `SimpleObject` with a couple of properties).
+As with the xref:starters:helloworld:about.adoc[helloworld] startre app, this will download a very simple one-class domain model, namely the `SimpleObject` entity and a supporting `SimpleObjects` domain service.
 
-However, the generated application also provides more structure to assist you as your application grows.
+However, the app also provides more structure to assist you as your application grows, with multiple Maven modules, and examples of unit tests, integration tests and BDD (cucumber) specs.
 
-We'll talk more about the structure of the generated app xref:about.adoc#structure-of-the-app.adoc[below], but for now let's see how to generate the application.
-
-
-[TIP]
-====
-The (non-ASF) Incode Platform's link:https://platform.incode.org/quickstart/quickstart.html[quickstart archetype] builds upon the simpleapp archetype, but also adds in support for various Incode Platform modules such as security, auditing, commands and publishing.
-====
 
 
 == Prerequisites
@@ -32,12 +24,11 @@ This is implemented as a Maven plugin, so in the case of IntelliJ, it's easy eno
 It should be just as straightforward for NetBeans too.
 
 For Eclipse the maven integration story is a little less refined.
-All is not lost, however; DataNucleus also has an implementation of the enhancer as an Eclipse plugin, which usually works well enough.
-
+All is not lost, however; DataNucleus also has an implementation of the enhancer as an Eclipse plugin, which works well enough.
 
 
 
-== Generating the App
+== Downloading & Running
 
 Create a new directory, and `cd` into that directory.
 
@@ -45,730 +36,841 @@ To build the app from the latest stable release, then run the following command:
 
 include::script.adoc[]
 
-where:
-
-- `groupId` represents your own organization, and
-- `artifactId` is a unique identifier for this app within your organization.
-- `version` is the initial (snapshot) version of your app
-
-The archetype generation process will then run; it only takes a few seconds.
-
+This should only take a few seconds to download, compile and run.
+Then browse to link:http://localhost:8080[], and read on.
 
 
+== Using the App
 
-== Structure of the App
+When you start the app, you'll be presented with a welcome page from which you can access the webapp using either the generic UI provided by xref:vw:ROOT:about.adoc[Wicket viewer] or use Swagger to access the xref:vro:ROOT:about.adoc[Restful Objects viewer]:
 
-As mentioned above, the application generated by the simpleapp archetype is a multi-module project, structured so that you easily extend it as your application grows.
+image::using/010-root-page.png[width="600px",link="{imagesdir}/using/010-root-page.png"]
 
-The application consists of three modules, with a top-level module acting as an aggregator and also parent:
+Choose the generic Wicket UI, and navigate to the login page:
 
-image::using-simple-app/structure/structure/Slide1.PNG[width="800px",link="{imagesdir}/using-simple-app/structure/structure/Slide1.PNG"]
+image::using/020-login-to-wicket-viewer.png[width="600px",link="{imagesdir}/using/020-login-to-wicket-viewer.png"]
 
-The application separates domain object model holding the business logic (the `myapp-module-simple` Maven module containing `SimpleObject` entity and supporting domain classes) from the bootstrapping modules (`myapp-application` Maven module and the `myapp-webapp` module).
+The app itself is configured to run using xref:security:ROOT:about.adoc[shiro security], as configured in the `WEB-INF/shiro.ini` config file.
+You can login with:
 
-In a larger application there would likely be many more modules containing these domain object modules.
-For example, you might have a `myapp-module-customer` holding a `Customer` entity and related entities/services, a `myapp-module-product` holding a `Product` catalog, and a `myapp-module-order` to hold the ``Order``s placed by ``Customer``s:
+* username: _sven_
+* password: _pass_
 
-image::using-simple-app/structure/structure/Slide2.PNG[width="800px",link="{imagesdir}/using-simple-app/structure/structure/Slide2.PNG"]
+=== Wicket viewer
 
-We can use Maven dependency management to ensure that there are no cyclic dependencies (order "knows about" product but product does not know about orders) and ensure that the codebase remains decoupled.
-When Java9 modules are commonplace, we'll also be able to restrict visibility of classes between modules.
+Once you've logged in you'll see the default home page:
 
-[WARNING]
-====
-Note that while Maven dependencies are transitive (in the example the `myapp-application` needs only depend directly on `myapp-module-order`, the modules defined in the `AppManifest` are _not_ transitive: all modules must be listed.
-====
+image::using/030-home-page.png[width="600px",link="{imagesdir}/using/030-home-page.png"]
 
-Let's now review the contents of each of the generated modules.
+This is a view model annotated with xref:refguide:applib-ant:HomePage.adoc[@HomePage]:
 
+[source,java]
+.HomePageViewModel.java
+----
+@DomainObject(
+        nature = Nature.VIEW_MODEL,
+        objectType = "domainapp.HomePageViewModel"
+        )
+@HomePage
+public class HomePageViewModel {
 
-=== myapp (parent)
-
-The parent module is a fairly conventional, declaring its child modules (using `<dependencyManagement>` elements) and aggregating them (using `<module>` elements).
+    public TranslatableString title() {
+        return TranslatableString.tr("{num} objects", "num", getObjects().size());
+    }
 
-[NOTE]
-====
-One thing you'll discover when you review the generated classes is that they all reside under the `domainapp` package.
+    public List<SimpleObject> getObjects() {
+        return simpleObjects.listAll();
+    }
 
-While it's more conventional to use the inverse domain name for package (eg `com.mycompany.myapp`, that's only really appropriate for library code that will be released for reuse by multiple applications in different orgnisations (eg open source).
+    @Inject SimpleObjects simpleObjects;
+}
+----
 
-For internal application though this is less of a concern; indeed, avoiding the domain name means that if the company rebrands or is taken over then nothing needs be changed.
 
-Of course, you are always free to move the classes to a different package if you wish.
-====
+==== Fixtures
 
+When prototyping against an in-memory database, it's useful to have a mechanism to create some initial state.
+This can be done using fixture scripts, accessible from the menu:Prototyping[Run Fixture Script]:
 
+image::using/032-run-fixture-script-prompt.png[width="px",link="{imagesdir}/using/032-run-fixture-script-prompt.png"]
 
-=== myapp-application
+This brings up a dialog to select the fixture script:
 
-The production classes for `myapp-application` module (in `src/main/java`) are:
+image::using/033-run-fixture-script-prompt.png[width="px",link="{imagesdir}/using/033-run-fixture-script-prompt.png"]
 
-[source]
-----
-src/
-  main/
-    java/
-      domainapp/
-        application/
-          DomainAppApplicationModule.java
-          fixture/
-            DomainAppFixtureScriptsSpecificationProvider.java
-            scenarios/
-              DomainAppDemo.java
-          manifest/
-            DomainAppAppManifest.java
-            DomainAppAppManifestBypassSecurity.java
-            DomainAppAppManifestWithFixtures.java
-            DomainAppAppManifestWithFixturesBypassSecurity.java
-            isis-non-changing.properties
-            menubars.layout.xml
-          services
-            healthcheck
-              HealthCheckServiceImpl.java
-            homepage
-              HomePageService.java
-              HomePageViewModel.java
-              HomePageViewModel.layout.xml
-              HomePageViewModel.layout.png
-----
-
-==== Manifest
-
-The `DomainAppAppManifest` is the most important class here, typically being used to bootstrap the application.
-It is quite short:
+This surfaces this code:
 
 [source,java]
+.DomainAppDemo.java
 ----
-public class DomainAppAppManifest extends AppManifestAbstract2 {
-
-    public static final Builder BUILDER = Builder
-            .forModule(new DomainAppApplicationModule())
-            .withConfigurationPropertiesFile(
-                    DomainAppAppManifest.class, "isis-non-changing.properties")
-            .withAuthMechanism("shiro");
+public class DomainAppDemo extends FixtureScript {
 
-    public DomainAppAppManifest() {
-        super(BUILDER);
+    @Override
+    protected void execute(final ExecutionContext ec) {
+        ec.executeChild(this, new TeardownFixtureAbstract2() {
+            @Override
+            protected void execute(final ExecutionContext executionContext) {
+                deleteFrom(SimpleObject.class);
+            }
+        });
+        ec.executeChild(this, new SimpleObject_persona.PersistAll());
     }
 }
 ----
 
-Rather than implement `AppManifest` directly, `DomainAppAppManifest` uses the builder provided by the convenience `AppManifestAbstract2`), to define three things:
+When executed, all objects created by the fixture are listed:
 
-* a list of modules - there's just one, `DomainAppApplicationModule`
-* the location of a configuration file, `isis-non-changing.properties`, read in as a resource from the classpath
-* specifying an authentication/authorisation mechanism, in this case Apache Shiro integration.
+image::using/034-run-fixture-script-result.png[width="px",link="{imagesdir}/using/034-run-fixture-script-result.png"]
 
-The manifest uses the builder defined by `AppManifestAbstract2` and references a single top-level (Isis) module, namely `DomainAppApplicationModule`:
+Navigating back to the home page shows the newly created objects:
 
-[source,java]
-----
-public class DomainAppApplicationModule extends ModuleAbstract {
-    @Override
-    public Set<Module> getDependencies() {
-        return Sets.<Module>newHashSet(new SimpleModule());
-    }
-}
-----
+image::using/036-home-page-after-fixture-scriptpng.png[width="600px",link="{imagesdir}/using/036-home-page-after-fixture-scriptpng.png"]
 
-where `SimpleModule` in defined in the `mypp-module-simple` module (below).
 
-The primary purpose of the module class is to identify packages and subpackages that the framework should scan for entities and domain services.
-The transitive dependencies between modules are automatically resolved.
-The net effect is that all the domain services and entities in this module as well as those modules referenced are included into the app.
 
-Going back to the manifest, it also defines the `isis-non-changing.properties` configuration properties, loaded as a static resource from the classpath.
+==== Create an object
 
-You'll find that there's also a similar file called `isis.properties`, which resides at `WEB-INF/isis.properties`.
-This also provides configuration options (the framework simply combines them) but those in `WEB-INF/isis.properties` are restricted to settings that are likely to change from environment to environment, most notably JDBC URL connection strings.
-Separating these out makes it easy to reconfigure the application to run against different databases in different environments (dev, test, production etc).
+You can also of course create new objects:
 
-Finally, the app manifest identifies Apache Shiro for authentication and authorisation.
-Shiro in turn is configured using the `WEB-INF/shiro.ini` file.
+image::using/040-create-object-from-menu.png[width="600px",link="{imagesdir}/using/040-create-object-from-menu.png"]
 
-[TIP]
-====
-The security integration provided by Apache Isis and Shiro is quite sophisticated; to get started though you can just login using username: `sven`, password: `pass`.
-====
+To avoid obscuring the current page, this is configured to bring up a sidebar dialog:
 
-The `menubars.layout.xml` file also resides in the same package as the manifest; this defines the menubar structure.
+image::using/050-create-object-from-menu-prompt.png[width="600px",link="{imagesdir}/using/050-create-object-from-menu-prompt.png"]
 
-There are also several variations on the app manifest; these can be used to bootstrap the application with fixtures, or disabling security.
+Hitting OK returns the created object:
 
-==== Domain Services
+image::using/060-created-object.png[width="600px",link="{imagesdir}/using/060-created-object.png"]
 
-The `domainapp.application.services` package contains two SPI implementations.
-
-The `HomePageService` domain service simply has a single action annotated with `@HomePage`:
+The above functionality is implemented by this code:
 
 [source,java]
 ----
-@Action(semantics = SemanticsOf.SAFE)
-@HomePage
-public HomePageViewModel homePage() {
-    return factoryService.instantiate(HomePageViewModel.class);
+public static class CreateActionDomainEvent extends ActionDomainEvent {}
+@Action(semantics = SemanticsOf.NON_IDEMPOTENT, domainEvent = CreateActionDomainEvent.class)
+@ActionLayout(promptStyle = PromptStyle.DIALOG_SIDEBAR)
+public SimpleObject create(
+        @Name final String name) {
+    return repositoryService.persist(SimpleObject.ofName(name));
 }
 ----
 
-which returns the `HomePageViewModel` for use as the home page.
-The `HomePageViewModel` itself just renders a collection of ``SimpleObject``s in a list (`HomePageViewModel.layout.xml` defines the UI layout).
+TIP: Policies such as modal or sidebar can be specified per action, or globally in `application.yml` file.
 
-The other SPI implementation is the `HealthCheckServiceImpl` domain service, which is used to indicate if the application is running healthily.
-This is exposed as the `/restful/health` REST endpoint.
-The implementation itself simply runs a query on the `SimpleObjects` repository service, thus checking that the database is configured correctly and available.
+==== Invoke an action
 
+NOTE: The `CreatedActionDomainEvent` is published on an in-memory event bus; this allows subscribers to veto or to react to the action invocation.
 
-==== Fixtures
+The `SimpleObject` contains a couple of properties, and a single action to update that property.
 
-The final package in the application module is `domainapp.application.fixture`.
-The important class here is `DomainAppDemo`, a fixture script that can be used to setup the application with some dummy data.
-This is used in the app itself when running in prototype mode (against an in-memory database), and can also be used by integration tests.
+The `name` property is read-only, and can only be modified using the `updateName` action:
 
-There is in fact also a domain service defined here, namely `DomainAppFixtureScriptsSpecificationProvider`.
-This is just used to configure the run fixture script menu item shown on the "Prototyping" menu.
+image::using/070-update-name.png[width="600px",link="{imagesdir}/using/070-update-name.png"]
 
-The module also defines a number of BDD specs and integration tests, in `src/test/java`.
-The BDD specs (run using Cucumber) reside under `domain.application.bdd`:
+The above functionality is implemented by this code:
 
-[source]
+[source,java]
 ----
-src/
-  test/
-    java/
-      domainapp/
-        application/
-          bdd/
-            specglue/
-              BootstrappingGlue.java
-              CatalogOfFixturesGlue.java
-            specs/
-              RunIntegBddSpecs.java
-              SimpleObjectSpec_listAllAndCreate.feature
+public static class UpdateNameActionDomainEvent extends SimpleObject.ActionDomainEvent {}
+@Action(semantics = IDEMPOTENT,
+        publishing = Publishing.ENABLED,
+        associateWith = "name",
+        domainEvent = UpdateNameActionDomainEvent.class)
+public SimpleObject updateName(
+        @Name final String name) {
+    setName(name);
+    return this;
+}
+public String default0UpdateName() {
+    return getName();
+}
 ----
 
-Here the `BootstrappingGlue` glue class inherits from the framework's `HeadlessWithBootstrappingAbstract` class, and bootstraps using the `DomainAppApplicationModule` mentioned above.
+The `updateName` action is annotated with publishing enabled.
+This means that the action invocation is converted into XML and dispatched to all configured implementations of the xref:refguide:applib-svc:persistence-layer-spi/PublisherService.adoc[PublisherService] SPI.
 
-There is just one feature file: `SimpleObjectSpec_listAllAndCreate.feature`, which is pretty simple:
+The framework provides a default implementation that just logs the interaction:
 
-[source,feature]
-----
-@DomainAppDemo
-Feature: List and Create New Simple Objects
+image::using/075-publish-logging-1.png[width="600px",link="{imagesdir}/using/075-publish-logging-1.png"]
 
-  Scenario: Existing simple objects can be listed and new ones created
-    Given there are initially 10 simple objects
-    When  I create a new simple object
-    Then  there are 11 simple objects
-----
+In fact, it also logs the fact that the object itself was modified:
 
+image::using/076-publish-logging-2.png[width="600px",link="{imagesdir}/using/076-publish-logging-2.png"]
 
-The `@DomainAppDemo` annotation causes the `DomainAppDemo` fixture script to be run; this is the purpose of the `CatalogOfFixturesGlue` glue class.
 
-The specs themselves are run by the `RunIntegBddSpecs.java` class, which specifies which packages to search for "glue".
-This is just standard Cucumber bootstrapping.
 
-The integration tests meanwhile are in `domainapp.application.integtests`:
+==== Edit a property
 
-[source]
-----
-src/
-  test/
-    java/
-      domainapp/
-        application/
-          integtests/
-            DomainAppIntegTestAbstract.java
-            mml/
-              approved/
-              received/
-              MetaModelService_IntegTest.java
-            smoke/
-              Smoke_IntegTest.java
-----
+The `notes` property is editable, and can be edited in-place.
+For example:
 
-There are two different sets of tests.
+image::using/080-edit-notes.png[width="600px",link="{imagesdir}/using/080-edit-notes.png"]
 
-* The `Smoke_IntegTest` performs a number of high-level smoke tests, to check that the core functionality works correctly.
-+
-This test inherits `DomainAppIntegTestAbstract`, which in turn inherits from `IntegrationTestAbstract3` and uses the `DomainAppApplicationModule` previously discussed.
-+
-Moreover, the `Smoke_IntegTest` uses the same `DomainAppDemo` fixture script.
-The application and the smoke tests therefore run with the exact same state, making debugging easy.
 
-* The `MetaModelService_IntegTest` demonstrates how to use approval tests to verify that the metamodel is unchanged between releases of Apache Isis.
-+
-By default this test does nothing; it is activated by setting system properties ("lockdown.learn" or "lockdown.verify").
-When in "learn" mode, the test calls the `MetaModelService` to export an XML representation of the internal metamodel.
-These can then be moved from the `received` directory to the `approved` directory, as "known-to-good".
-+
-Then, if Apache Isis is updated, then the "verify" test can be called to check that the metamodel created by the new version of the framework is the same as the previous version.
+==== Actions requiring confirmations
 
-With regard to the naming of these various BDD specs and integration tests, they follow the naming convention required by the (non-ASF) link:http://github.com/danhaywood/java-mavenmixin-surefire["surefire" mavenmixin] that configures the maven surefire plugin.
+It's also possible to delete an object:
 
+image::using/090-delete-object.png[width="600px",link="{imagesdir}/using/090-delete-object.png"]
 
+The viewer displays a message confirming that the object has been deleted:
 
-=== myapp-module-simple
+image::using/100-object-deleted.png[width="600px",link="{imagesdir}/using/100-object-deleted.png"]
 
-This module is where the domain object model lives, that is the business logic of the application itself.
-This typically comprises entities, domain services, mixins and view models.
+The above functionality is implemented by this code:
 
+[source,java]
+----
+public static class DeleteActionDomainEvent extends SimpleObject.ActionDomainEvent {}
+@Action(semantics = NON_IDEMPOTENT_ARE_YOU_SURE, domainEvent = DeleteActionDomainEvent.class)
+public void delete() {
+    final String title = titleService.titleOf(this);
+    messageService.informUser(String.format("'%s' deleted", title));
+    repositoryService.removeAndFlush(this);
+}
+----
 
-[TIP]
-====
-As discussed above, larger applications will likely have multiple modules each containing their own slice of business logic.
+Note that this uses three services provided by the framework; these are injected into the domain object automatically.
 
-Initially though you should probably just use regular Java packages to separate out functionality; you can carve out separate modules later on once the responsibilities of each have settled down.
-====
 
+=== Swagger (Restful Objects)
 
-The classes for the simple module reside in the `domainapp.modules.simple` package.
-Under `src/main/java` we have:
+Using menu:Prototyping[Open Swagger UI] menu item (or just going back to the home page at link:http://localhost:8080[localhost:8080]) we can use link:https://swagger.io/[Swagger UI] as a front-end to the REST API provided by the Restful Objects viewer.
 
+image::using/200-swagger-ui-before-reload.png[width="600px",link="{imagesdir}/using/200-swagger-ui-before-reload.png"]
 
-//│
-//&boxv;
-//┌
-//&boxdr;
-//┐
-//&boxdl;
-//└
-//&boxur;
-//┘
-//&boxul;
-//├
-//&boxvr;
-//┤
-//&boxvl;
-//┬
-//&boxhd;
-//┴
-//&boxhu;
-//┼
-//&boxvh;
+The public API (where the calling client is assumed to be 3rd party) only exposes view models, not entities.
+If the API is private (or for prototyping), then resources corresponding to entities are also exposed:
 
-[source]
-----
-src/
-  main/
-    java/
-      domainapp/
-        application/
-          DomainAppApplicationModule.java
-          fixture/
-            DomainAppFixtureScriptsSpecificationProvider.java
-            scenarios/
-              DomainAppDemo.java
-          manifest/
-            DomainAppAppManifest.java
-            DomainAppAppManifestBypassSecurity.java
-            DomainAppAppManifestWithFixtures.java
-            DomainAppAppManifestWithFixturesBypassSecurity.java
-            isis-non-changing.properties
-            menubars.layout.xml
-          services
-            healthcheck
-              HealthCheckServiceImpl.java
-            homepage
-              HomePageService.java
-              HomePageViewModel.java
-              HomePageViewModel.layout.xml
-              HomePageViewModel.layout.png
-----
-
-The `SimpleModule` is the (single) module class referenced from the previously discussed `DomainAppApplicationModule`, meaning that all the entities, domain services and fixtures within it are included within the application.
-
-* `SimpleObject` is the (one-and-only) domain entity defined (with `SimpleObject.layout.xml` defines its layout in the UI).
-
-* `SimpleObjects` domain service's whos actions appear as menu items and which acts as a repository to create and find ``SimpleObject``s.
-
-The `SimpleModule` class also defines a teardown fixture, automatically called by integration tests.
+image::using/210-simpleapp-resources.png[width="600px",link="{imagesdir}/using/210-simpleapp-resources.png"]
 
-[source,java]
-----
-public class SimpleModule extends ModuleAbstract {
-    @Override
-    public FixtureScript getTeardownFixture() {
-        return new TeardownFixtureAbstract2() {
-            @Override
-            protected void execute(ExecutionContext ec) {
-                deleteFrom(SimpleObject.class);
-            }
-        };
-    }
-    ...
-}
-----
+For example, an object can be created using the resource that represents the `SimpleObjects#create` action:
 
-In the `fixture` subpackage is the `SimpleObject_persona` "persona" which uses the corresponding `SimpleObjectBuilder` builder script; further discussion on this pattern xref:fixtures:ROOT:about.adoc#persona-and-builders.adoc[here].
-These fixtures are also used by "local" integration tests, which reside under `src/test/java`.
+image::using/220-create-object-thru-rest-api.png[width="600px",link="{imagesdir}/using/220-create-object-thru-rest-api.png"]
 
-There are also unit tests and "glue" for the BDD specs:
+CAUTION: if invoking the action returns a 401 (unauthorised), then navigate to the REST API directly (link:http://localhost:8080/restful[] to authenticate the browser first]).
 
-[source]
-----
-src/
-  test/
-    java/
-      domainapp/
-        modules/
-          simple/
-            dom/
-              impl/
-                SimpleObject_Test.java
-                SimpleObjectRepository_Test.java
-            integtests/
-              SimpleModuleIntegTestAbstract.java
-                tests/
-                  SimpleObject_IntegTest.java
-                  SimpleObjectMenu_IntegTest.java
-              specglue/
-                SimpleObjectMenuGlue.java
-----
+The response indicates that the object was successfully created:
 
-The simpleapp application has both "local" integration tests (defined within the `myapp-module-simple` module) and also "global" integration tests (the "smoke" tests in `myapp-application` module).
-There's a role for both: local integration tests should fully exercise the module but may need to mock out collaborations between modules, while global integration tests exercise the whole application (but an over-reliance on these can cause test run times to bloat).
+image::using/230-create-object-thru-rest-api-response.png[width="600px",link="{imagesdir}/using/230-create-object-thru-rest-api-response.png"]
 
-With regard to the naming of these various BDD specs and integration tests, they follow the naming convention required by the (non-ASF) link:http://github.com/danhaywood/java-mavenmixin-surefire["surefire" mavenmixin] that configures the maven surefire plugin.
-Integration tests include the name "IntegTest", while unit tests contain merely "Test".
+The Swagger UI also provides a resource to retrieve any object:
 
-// FIXME: currently removed in v2, may reinstate
-//The module also defines its own manifest, `SimpleModuleManifest`.
-//This is used to run Isis' own xref:refguide:mvn:about.adoc[maven plugin] to xref:refguide:mvn:validate.adoc[validate] the domain object model (eg to detect orphaned supported methods).
+image::using/240-retrieve-object-using-rest-api.png[width="600px",link="{imagesdir}/using/240-retrieve-object-using-rest-api.png"]
 
+This results in a representation of the domain object (as per the requested `Response Content Type`, ie `ACCEPT` header):
 
+image::using/250-retrieve-object-using-rest-api-response.png[width="600px",link="{imagesdir}/using/250-retrieve-object-using-rest-api-response.png"]
 
-=== myapp-webapp
 
-Finally, in the `myapp-webapp` module we have the configuration to package and bootstrap the application as a webapp.
-Under `src/main/webapp` are various resources, used either to configure the webapp, or that are served up by the running webapp:
+The Swagger UI is provided as a convenience; the REST API is actually a complete hypermedia API (in other words you can follow the links to access all the behaviour exposed in the regular Wicket app).
+The REST API implemented by Apache Isis is specified in the link:http://www.restfulobjects.org[Restful Object spec].
 
-[source]
-----
-src/
-  main/
-    webapp/
-      src/
-        main/
-          webapp/
-            about/
-              index.html
-            css/
-              application.css
-            scripts/
-              application.js
-            swagger-ui/
-            WEB-INF/
-              isis.properties
-              logging.properties
-              shiro.ini
-              translations.po
-              web.xml
-----
-
-Most important of these is `WEB-INF/web.xml`, which bootstraps both the Wicket viewer and the Restful Objects viewer, along with Shiro security.
-This is done using a webapp context listener:
 
-[source,xml]
-.web.xml
-----
-<web-app ...>
-  ...
-  <listener>
-      <listener-class>org.apache.isis.core.webapp.IsisWebAppContextListener</listener-class>
-  </listener>
-  ...
-</web-app>
-----
 
-The `about/index.html` is the page shown at the root of the package, providing links to either the Wicket viewer or to the Swagger UI.
-In a production application this is usually replaced with a page that does an HTTP 302 redirect to the Wicket viewer.
+== Structure of the App
 
-In `css/application.css` you can use to customise CSS, typically to highlight certain fields or states.
-The pages generated by the Wicket viewer have plenty of CSS classes to target.
-You can also implement the `cssClass()` method in each domain object to provide additional CSS classes to target.
+The simpleapp starter app is a multi-module project, structured so that you easily extend it as your application grows.
 
-Similarly, in `scripts/application.js` you have the option to add arbitrary Javascript.
-JQuery is available by default.
+The application consists of three modules, with a top-level module acting as an aggregator, the `module-simple` module that contains the business logic, and `webapp` module that acts as a bootstrapper.
 
-In `swagger-ui` is a copy of the Swagger 2.x UI classes, preconfigured to run against the REST API exposed by the Restful Objects viewer.
-This can be useful for developing custom applications, and is accessible from the initial page (served up by `about/index.html`).
+[plantuml]
+.simpleapp module dependencies
+----
+[webapp] <<maven module>>
+[module-simple]  <<maven module>>
 
-Finally in `WEB-INF` we have the standard `web.xml` (already briefly discussed) along with several other files:
+[webapp] .-> [module-simple]
+----
 
-* `isis.properties` contains further configuration settings for Apache Isis itself.
-+
-(As already discussed), these are in addition to the configuration properties found in various configuration properties that live alongside and that are loaded by the `DomainAppAppManifest` class.
-Those in the WEB-INF/isis.properties file are those that are likely to change when running the application in different environments.
+Each Maven module contains exactly one link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html[@Configuration] class, residing at the package root for that Maven module.
+So, the `module-simple` maven
+The location of this class is used for classpath scanning.
 
-* `logging.properties` configures log4j.
-+
-The framework is configured to use slf4j running against log4j.
+In a larger application there would likely be many more modules containing these domain object modules.
+For example, you might have a `module-customer` holding a `Customer` entity and related entities/services, a `module-product` holding a `Product` catalog, and a `module-order` to hold the ``Order``s placed by ``Customer``s:
 
-* `shiro.ini` configures Apache Shiro, used for security (authentication and authorisation)
 
-* `web.xml` configures the Wicket viewer and Restful Objects viewer.
-It also sets up various filters for serving up static resources with caching HTTP headers.
+[plantuml]
+.Typical application dependencies
+----
+[webapp] <<maven module>>
+[module-order]  <<maven module>>
+[module-customer]  <<maven module>>
+[module-product]  <<maven module>>
 
-The webapp module's `pom.xml` also has several tricks up its sleeve:
+[webapp] .-> [module-order]
+[module-order] .-> [module-customer]
+[module-order] .-> [module-product]
+----
 
-* most fundamentally, it allows the application to be packaged up as a regular `.war` file for deployment to a servlet container such as Tomcat 8.x
+We can use Maven dependency management to ensure that there are no cyclic dependencies (order "knows about" product but product does not know about orders) and ensure that the codebase remains decoupled.
+When Java9 modules are commonplace, we'll also be able to restrict visibility of classes between modules.
 
-* it also uses the jetty-console mavenmixin to package the application as a standalone executable JAR (with an embedded jetty container).
-+
-The files in `src/main/jettyconsole` provide a splash image (if not run in headless mode).
+Let's now review the contents of each of the modules in the simpleapp starter app.
 
-* the docker mavenmixin packages up the application as a docker image.
-+
-This uses the Dockerfile residing in `docker/Dockerfile` (under `src/main/resources`).
 
-// FIXME: currently removed in v2, may reinstate
-//* also, the xref:refguide:mvn:about.adoc[Apache Isis Maven plugin] is also configured to generate a xref:refguide:mvn:swagger.adoc[swagger] spec file for the entire application, in the `xxx-webapp` module
+=== module-simple's src/main/java
 
-Under `src/main/resources` there is:
+Under `src/main/java` we have:
 
 [source]
 ----
-src/
-  main/
-    resources/
-      docker/
-        Dockerfile
+src/main/java/
+  domainapp/                            <!--1-->
+    modules/                            <!--2-->
+      simple/                           <!--2-->
+        dom/                            <!--3-->
+          sp/                           <!--4-->
+            SimpleObject.java
+            SimpleObject.layout.xml
+            SimpleObject.png
+            SimpleObjects.java
+        fixture/                        <!--5-->
+          SimpleObject_persona.java
+          SimpleObjectBuilder.java
+        types/                          <!--6-->
+          Name.java
+          Notes.java
+      SimpleModule.java                 <!--7-->
+  META-INF/
+    persistence.xml                     <!--8-->
+----
+<1> For simplicity, all the Java source files generated by the archetype are placed in a `domainapp` top-level package.
+Change as required.
+<2> Defines the 'simple' module.
+Apache Isis can be used for both microservice and monolithic architectures, but for the latter it encourages "modular monoliths" from the start.
+<3> The `dom` package holds the "domain object model" for this module.
+Modules may have other packages, common ones include ``types`` and ``fixture``s (as below), also ``api``s, ``contribution``s, ``spi``s
+<4> Holds classes for the `so` ("simple object") entity/aggregate, consisting of the entity definition itself (`SimpleObject`) and a corresponding repository (`SimpleObjects`).
+The associated `.layout.xml` and `.png` are optional but provide metadata/resources for rendering (Maven is configured to also treat `src/main/java` as a resource location).
+<5> The `fixture` package contains classes to set up the database to an initial state (as described xref:#fixtures[earlier].
+One of the classes is a `FixtureScript` (defines _how_ to set up the data) the other is a persona enum (defines _what_ data to set up).
+<6> The `types` package contains meta-annotations to describe the usage of common value types such as ``String``s.
+<7> `SimpleModule` is a Spring link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html[@Configuration] which allows the domain services and entities of the module to be located. +
+This is discussed in more detail below.
+<8> The `persistence.xml` file is required when using the JDO/DataNucleus object store (though it is basically boilerplate, an empty file).
+
+
+==== SimpleModule
+
+Every module within an Apache Isis application should have a module class.
+Its purpose is to define a package to scan from, and optionally to declare any transitive dependencies.
+In the case of `SimpleModule`, it consists of:
+
+[source,java]
+.SimpleModule.java
 ----
+package domainapp.modules.simple;
+// ... imports omitted ...
+@Configuration
+@Import({})                                             //<!--1-->
+@ComponentScan                                          //<!--2-->
+public class SimpleModule
+                implements ModuleWithFixtures {         //<!--3-->
 
-As you might expect, this is used to create a Docker image.
-The `Dockerfile` is very simple; the built webapp is deployed as the ROOT.war into Apache Tomcat:
+    @Override
+    public FixtureScript getTeardownFixture() {
+        return new TeardownFixtureAbstract2() {
+            @Override
+            protected void execute(ExecutionContext executionContext) {
+                deleteFrom(SimpleObject.class);
+            }
+        };
+    }
 
-[source,Dockerfile]
-.Dockerfile
-----
-FROM incodehq/tomcat
-RUN rm -rf ${DEPLOYMENT_DIR}/ROOT
-COPY ${docker-plugin.resource.include} ${DEPLOYMENT_DIR}/ROOT.war
-EXPOSE 8080
+    public static class PropertyDomainEvent<S,T>        //<!--4-->
+    extends org.apache.isis.applib.events.domain.PropertyDomainEvent<S,T> {}
+
+    public static class CollectionDomainEvent<S,T>
+    extends org.apache.isis.applib.events.domain.CollectionDomainEvent<S,T> {}
+
+    public static class ActionDomainEvent<S> extends
+    org.apache.isis.applib.events.domain.ActionDomainEvent<S> {}
+}
 ----
+<1> This module has no dependencies.
+If there were, these would be expressed in terms of module classes (each being a Spring `@Configuration`)
+<2> specifies this class' package as a root to scan for Spring link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Component.html[@Component]s.
+<3> Optionally, modules can implement the testing's `ModuleWithFixtures` interface.
+Through this, they can provide a fixture script which can be used to teardown all entities that are "owned" by the module.
+Since the module dependency graph is known, this allows all data to be removed, useful for prototyping and sometimes for integration tests.
+<4> The actions for the domain objects and domain services all emit domain events, ultimately inheriting from xref:refguide:applib-cm:classes/domainevent/ActionDomainEvent.adoc[ActionDomainEvent].
+By convention, this inheritance hierarchy includes classes defined at the module level.
+This then allows subscribes to subscribe to all actions emitted by anything within the module. +
+Events can also be emitted for xref:refguide:applib-cm:classes/domainevent/PropertyDomainEvent.adoc[properties] and xref:refguide:applib-cm:classes/domainevent/CollectionDomainEvent.adoc[collections].
+
+The scanning mechanism is leveraged by Apache Isis to pick up three types of classes:
 
+This will pick up the `SimpleObjects` repository because it is annotated with the framework's xref:refguide:applib-ant:DomainService.adoc[@DomainService] annotation; itself meta-annotated with `@Component`.
 
-Now you know your way around the code generated by the archetype, lets see how to build the app and run it.
+* all domain services
++
+These are classes that are annotated with the framework's xref:refguide:applib-ant:DomainService.adoc[@DomainService] annotation.
+Because `@DomainService` is meta-annotated as a `@Component`, these are found automatically and are managed by Spring (ie instantiated, injected etc).
++
+Depending on their nature, domain services are used to build up the menu, or are available to call programmatically, eg repositories, or sometimes both.
++
+In the simpleapp starter app, the only domain service  is `SimpleObjects`.
+This appears in the menu, and also acts as a repository for the `SimpleObject` entity.
+
+* all entities.
++
+These are entities that are annotated with `@javax.jdo.annotations.PersistenceCapable`.
+These are passed through to the JDO/DataNucleus object store, in order to create database mappings from the entities to relational tables
++
+In the simpleapp starter app, the only entity is `SimpleObject`.
 
+* all fixture scripts
++
+These are classes that extend from the testing applib's `FixtureScript` class, and are used to setup the database when running in prototype mode (against an in-memory database).
++
+As already discussed, the `fixture` package provides classes to create sample objects, while the `SimpleModule` provides a fixture script to tear down all data from the module.
 
 
-== Building the App
+=== module-simple's src/test/java
 
-Switch into the root directory of your newly generated app, and build your app:
+Under `src/test/java` we have:
 
-[source,bash]
+[source]
 ----
-cd myapp
-mvn clean install
+src/test/java/
+  domainapp/
+    modules/
+      simple/
+        dom/
+          so/                                   <!--1-->
+            SimpleObject_Test.java
+            SimpleObjects_Test.java
+        integtests/
+          tests/                                <!--2-->
+            SimpleObject_IntegTest.java
+            SimpleObjects_IntegTest.java
+          SimpleModuleIntegTestAbstract.java    <!--3-->
 ----
+<1> These are very simple unit tests of `SimpleObject` and `SimpleObjects` with the package structure the same as in `src/main/java`.
+They are written in JUnit 5, and use JMockito as the mocking library.
+<2> Integration tests for the module.
+These use the xref:refguide:applib-svc:application-layer-api/WrapperFactory.adoc[WrapperFactory] to simulate interactions through the UI.
+<3> The `SimpleModuleIntegTestAbstract` superclass bootstraps the module's integration tests.
+This is discussed in more detail below.
 
-where `myapp` is the `artifactId` entered above.
+NOTE: these integration tests are annotated with the Spring link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html[@Transactional], which means that Spring will automatically roll back the changes to the database; there's no need to delete data afterwards.
 
+IMPORTANT: the naming convention -- with `Test` and `IntegTest` suffixes -- is important, because the Maven surefire plugin is configured to run multiple times, one `<execution>` for each suffix.
 
 
-== Running the App
+==== SimpleModuleIntegTestAbstract
 
-The `simpleapp` archetype generates a single WAR file, configured to run both the xref:vw:ROOT:about.adoc[Wicket viewer] and the xref:vro:ROOT:about.adoc[Restful Objects viewer].
-The archetype also configures the DataNucleus/JDO Objectstore to use an in-memory HSQLDB connection.
+The `SimpleModuleIntegTestAbstract` is the superclass of all integration tests in the module, annotated with link:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/SpringBootTest.html[@SpringBootTest]:
 
-Once you've built the app, you can run the WAR in a variety of ways.
+[source,java]
+.SimpleModuleIntegTestAbstract.java
+----
+@SpringBootTest(
+        classes = SimpleModuleIntegTestAbstract.AppManifest.class   //<!--1-->
+)
+@TestPropertySource({                                               //<!--2-->
+        IsisPresets.H2InMemory_withUniqueSchema,                    //<!--3-->
+        IsisPresets.DataNucleusAutoCreate,                          //<!--4-->
+        IsisPresets.UseLog4j2Test,                                  //<!--5-->
+})
+public abstract class SimpleModuleIntegTestAbstract
+        extends IsisIntegrationTestAbstractWithFixtures {           //<!--6-->
+
+    @Configuration
+    @Import({
+        IsisModuleCoreRuntimeServices.class,                        //<!--7-->
+        IsisModuleSecurityBypass.class,
+        IsisModuleJdoDataNucleus5.class,
+        IsisModuleTestingFixturesApplib.class,                      //<!--8-->
+
+        SimpleModule.class
+    })
+    public static class AppManifest {
+    }
+}
+----
+<1> The `AppManifest` (defined as a nested static class below) lists the modules needed to bootstrap the integration test.
+<2> Spring allows additional properties to be defined through the link:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/context/TestPropertySource.html[@TestPropertySource] annotation
+<3> Runs the tests in memory using H2.
+A unique schema allows tests to potentially be run in parallel
+<4> Ensures that JDO/DataNucleus is configured to create the database schema first.
+This may be required because the application might otherwise be configured to use the xref:userguide:flyway:about.adoc[Flyway integration].
+<5> Sets up logging to use the configuration defined in the `log4j2-test.xml` file
+<6> Tests typically inherit from `IsisIntegrationTestAbstract`, which provides some convenience methods to inherit from.
+In this case, the test inherits from the `IsisIntegrationTestAbstractWithFixtures` subclass which also adds in support for running fixtures.
+<7> Specifies the modules that make up Apache Isis framework itself.
+These include core, security set to the bypass implementation (effecively is ignored) and JDO/DataNucleus for persistence.
+Note that there no viewers are bootstrapped because the tests are run through Spring's integration testing framework, rather than (say) as Selenium tests.
+<8> Brings in support for running fixtures.
 
+TIP: You can learn more about testing in the xref:testing:ROOT:about.adoc[Testing Guide].
 
-=== Using mvn Jetty plugin
 
-First, you could run the WAR in a Maven-hosted Jetty instance, though you need to `cd` into the `webapp` module:
 
-[source,bash]
-----
-mvn -pl webapp jetty:run
-----
 
+=== webapp's src/main/java
 
-You can also provide a system property to change the port:
+Under `src/main/java` we have:
 
-[source,bash]
-----
-mvn -pl webapp jetty:run -D jetty.port=9090
+[source]
 ----
+src/main/java/
+  domainapp/
+    webapp/
+      application/
+        fixture/
+          scenarios/                                            <!--1-->
+            DomainAppDemo.java                                  <!--2-->
+            DomainAppFixtureScriptsSpecificationProvider.java   <!--3-->
+        services/
+          health/
+            HealthCheckServiceImpl.java                         <!--4-->
+          homepage/
+            HomePageViewModel.java                              <!--5-->
+            HomePageViewModel.layout.xml
+            HomePageViewModel.png
+         ApplicationModule.java                                 <!--6-->
+      AppManifest.java                                          <!--7-->
+      SimpleApp.java                                            <!--8-->
+----
+<1> Defines scenarios (fixtures) for setting up the system into a known state.
+Used for prototyping and also integration testing.
+<2> The `DomainAppDemo` is the fixture that was run xref:#fixtures[earlier on].
+<3> The `DomainAppFixtureScriptsSpecificationProvider` is used to configure the run fixture script menu item shown on the "Prototyping" menu.
++
+NOTE: Fixture scenarios also need to be link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Import.html[@Import]ed, typically in the top-level `AppManifest`.
 
+<4> An implementation of the xref:refguide:applib-svc:application-layer-spi/HealthCheckService.adoc[HealtCheckService].
+This integrates with Spring Boot's link:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/actuate/health/HealthIndicator.html[HealthIndicator] SPI, surfaced through the link:https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html[Spring Boot Actuator].
+<5> Annotated with xref:refguide:applib-ant:HomePage.adoc[@HomePage] and so is shown automatically as the home page.
+<6> Defines the services in the webapp module, along with dependencies onto the other modules in the application. +
+Discussed in more detail below.
+<7> `AppManifest` is the top-level Spring link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html[@Configuration] that specifies the components of Apache Isis to use, along with the modules making up the application itself (ie `ApplicationModule`, which depends in turn on `SimpleModule`). +
+This is discussed in more detail below
+<8> `SimpleApp` is the link:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/SpringBootApplication.html[@SpringBootApplication] used to bootstrap the app.
+It's pretty much boilerplate - the important piece is that it references `AppManifest`. +
+It's discussed in more detail below
 
-=== Using a regular servlet container
 
-You can also take the built WAR file and deploy it into a standalone servlet container such as [Tomcat](http://tomcat.apache.org).
-The default configuration does not require any configuration of the servlet container; just drop the WAR file into the `webapps` directory.
 
+==== ApplicationModule
 
+The `ApplicationModule` defines the services in the webapp module, along with dependencies onto the other modules in the application.
+It's very simple though:
 
-=== Using Docker
+[source,java]
+.ApplicationModule.java
+----
+package domainapp.webapp.application;
+// ... imports omitted ...
+@Configuration
+@Import(SimpleModule.class)             // <!--1-->
+@ComponentScan                          // <!--2-->
+public class ApplicationModule {
+}
+----
+<1> This module depends on the `SimpleModule` module.
+<2> specifies this class' package as a root to scan for Spring link:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Component.html[@Component]s.
 
-It's also possible to package up the application as a docker image to run as a container.
 
-* To package up the application as a docker image (specifying the docker image name as a system property): +
-+
-[source,bash]
-----
-mvn install -Dmavenmixin-docker -Ddocker-plugin.imageName=mycompany/myapp
-----
-+
-Alternatively, define the `${docker-plugin.imageName}` in the `webapp` module and use simply: +
-+
-[source,bash]
-----
-mvn install -Dmavenmixin-docker
-----
-+
-The packaged image can be viewed using `docker images`.
+==== AppManifest
 
-* To run a docker image previously packaged: +
-+
-[source,bash]
-----
-docker container run -d -p 8080:8080 mycompany/myapp
-----
-+
-This can then be accessed at link:http://localhost:8080[localhost:8080].
-+
-See link:https://github.com/danhaywood/java-mavenmixin-docker#how-to-consume[mavenmixin-docker] for further details on how to run docker images.
+The "app manifest" (the name has been retained from Apache Isis v1.x) is the top-level Spring `@Configuration`.
+It looks like this:
 
-* To upload the application as a docker image to link:https://hub.docker.com[docker hub] (or some other docker registry): +
-+
-[source,bash]
-----
-mvn -pl webapp deploy -Dmavenmixin-docker
+[source,java]
+.AppManifest.java
 ----
-+
-This assumes that the `${docker-plugin.imageName}` property has been defined, _and_ also that docker registry credentials have been specified in `~/.m2/settings.xml`.
-Once more, see link:https://github.com/danhaywood/java-mavenmixin-docker#how-to-configure[mavenmixin-docker] for further details.
+@Configuration
+@Import({
+        IsisModuleCoreRuntimeServices.class,                    //<!--1-->
+        IsisModuleSecurityShiro.class,                          //<!--2-->
+        IsisModuleJdoDataNucleus5.class,                        //<!--3-->
+        IsisModuleViewerRestfulObjectsJaxrsResteasy4.class,     //<!--4-->
+        IsisModuleViewerWicketViewer.class,                     //<!--5-->
 
+        IsisModuleTestingH2ConsoleUi.class,                     //<!--6-->
+        IsisModuleTestingFixturesApplib.class,                  //<!--7-->
 
+        IsisModuleExtFlywayImpl.class,                          //<!--8-->
 
-=== From within the IDE
+        ApplicationModule.class,                                //<!--9-->
 
-Most of the time, though, you'll probably want to run the app from within your IDE.
-The mechanics of doing this will vary by IDE; see the xref:toc:devguide:ide.adoc[Developers' Guide] for details of setting up Eclipse or IntelliJ IDEA.
-Basically, though, it amounts to running `org.apache.isis.WebServer`, and ensuring that the xref:toc:devguide:hints-and-tips/datanucleus-enhancer.adoc[DataNucleus enhancer] has properly processed all domain entities.
+        DomainAppDemo.class                                     //<!--10-->
+})
+@PropertySource(IsisPresets.NoTranslations)                     //<!--11-->
+@PropertySource(IsisPresets.DebugDiscovery),
+public class AppManifest {
+}
+----
+<1> Mandatory - specifies the core of the Apache Isis framework
+<2> Enables the Shiro security mechanism.
+There are several implementations, precisely one must be selected
+<3> Enables JDO/DataNucleus for persistence.
+Optional (though if omitted then only xref:userguide:fun:building-blocks/types-of-domain-objects.adoc[view models] may be used, with hand-rolled persistence).
+<4> Enables the xref:vro:ROOT:about.adoc[Restful Objects viewer] (ie REST API).
+<5> Enables the xref:vw:ROOT:about.adoc[Wicket viewer]
+<6> Enables the H2 Console (menu from the "Prototyping" menu), applicable only if running against h2 in-memory database.
+<7> Brings in support to run xref:testing:fixtures:about.adoc[fixtures] within the application, eg for prototyping.
+<8> Enables the xref:userguide:flyway:about.adoc[Flyway] integration.
+<9> References the application's module(s), in this case just the one, `ApplicationModule`. +
+This is discussed below.
+<10> Makes the fixture scenario classes available for discovery.
+<11> Normally configuration properties are picked up from Spring Boot's `application.properties` or `application.yaml` files, but additional properties can be overridden directly.
+These two both use the `IsisPresets` convenience class, to disable i18n support and for additional debugging log statements.
 
-Here's what the setup looks like in IntelliJ IDEA:
 
-image::simpleapp-webapp.png[width="600px",link="{imagesdir}/simpleapp-webapp.png"]
+==== SimpleApp
 
-with the maven goal to run the DataNucleus enhancer (discussed in more detail xref:toc:devguide:hints-and-tips/datanucleus-enhancer.adoc[here]) before launch defined as:
+The application is bootstrapped using `SimpleApp`, a regular `@SpringBootApplication`.
+It is mostly boilerplate:
 
-image::simpleapp-webapp-before-launch.png[width="600px",link="{imagesdir}/simpleapp-webapp-before-launch.png"]
+[source,java]
+----
+@SpringBootApplication
+@Import({
+    AppManifest.class,                                          //<!--1-->
+})
+public class SimpleApp
+            extends SpringBootServletInitializer {
+
+    public static void main(String[] args) {
+        IsisPresets.prototyping();                              //<!--2-->
+        SpringApplication.run(
+                new Class[] { SimpleApp.class }, args);
+    }
+}
+----
+<1> references the `AppManifest` mentioned earlier
+<2> specifies prototyping mode.
+This enables actions marked for prototyping to become available, useful during the early stages of development.
++
+TIP: As an alternative to making this call, you can also just run with a system property `-DPROTOTYPING=true`
 
 
+=== webapp's src/main/resources
 
-== Running with Fixtures
+Under `src/main/resources` we have:
 
-It is also possible to start the application with a pre-defined set of data; useful for demos or manual exploratory testing.
-This is done by specifying a xref:fixtures:ROOT:about.adoc[fixture script] on the command line.
+[source]
+----
+src/main/resources
+  config/
+    application.properties              <!--1-->
+    application-SQLSERVER.properties    <!--2-->
+  db/
+    migration/
+      SQLSERVER/
+        Vyyyy.mm.dd.hh.ss__xxx.sql      <!--3-->
+  static/                               <!--4-->
+  templates/                            <!--5-->
+  application.yml                       <!--6-->
+  banner.txt                            <!--7-->
+  log4j2-spring.xml                     <!--8-->
+  menubars.layout.xml                   <!--9-->
+  shiro.ini                             <!--10-->
+----
+<1> By convention, we use `config/application.properties` to hold configuration properties that change between environments (dev, test, prod).
+Typically this just holds JDBC connection strings, etc.
+<2> Enabled if run using the `SQLSERVER` profile (eg using `-Dspring.profiles.active=SQLSERVER`). Configures to use a SQL Server database, and enables Flyway to set up the database schema
+<3> Flyway migration scripts. +
+This leverages a feature in Spring Boot's Flyway integration which allows different variants of scripts for different vendors to be stored, in a `+db.migration.{vendor}+` package.
+<4> The `static` package (a link:https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-spring-mvc-static-content[Spring convention]) provides access for static resources that are accessible from the webapp
+<5> The `templates` package holds a fallback error page, which is the link:https://www.baeldung.com/spring-thymeleaf-template-directory#change-default[default location] for pages rendered using Spring Boot's integration with Thymeleaf.
+<6> By convention, we use `application.yml` to hold configuration properties that do _not_ change between environments.
+<7> The `banner.txt` is shown when bootstrapping.
+<8> The `log4j2-spring.xml` configures log4j2 (the logging system used by Apache Isis)
+<9> The `menubars.layout.xml` arranges the actions of the domain services into menus.
+<10> The `shiro.ini` file configures Shiro security integration (see the `IsisModuleSecurityShiro` module imported in the `AppManifest`, above).
++
+[TIP]
+====
+The xref:security:shiro:about.adoc[Shiro security] integration is much more flexible than simple file-based authentication.
+====
 
-If you are running the app from an IDE, then you can specify the fixture script using the `--fixture` flag.  The archetype provides the `domainapp.fixture.scenarios.RecreateSimpleObjects` fixture script, for example:
+To call out some of the files under `static`:
 
-image::simpleapp-webapp-with-fixtures.png[width="600px",link="{imagesdir}/simpleapp-webapp-with-fixtures.png"]
+* The `index.html` is the page shown at the root of the package, providing links to either the Wicket viewer or to the Swagger UI.
+In a production application this is usually replaced with a page that does an HTTP 302 redirect to the Wicket viewer.
 
-Alternatively, you can run with a different xref:refguide:applib-cm:classes/AppManifest-bootstrapping.adoc[`AppManifest`] using the `--appManifest` (or `-m`) flag.
-The archetype provides
-`domainapp.app.DomainAppAppManifestWithFixtures` which specifies the aforementioned `RecreateSimpleObjects` fixture.
+* In `css/application.css` you can use to customise CSS, typically to highlight certain fields or states.
+The pages generated by the Wicket viewer have plenty of CSS classes to target.
+You can also implement the `cssClass()` method in each domain object to provide additional CSS classes to target.
+
+* Similarly, in `scripts/application.js` you have the option to add arbitrary Javascript.
+JQuery is available by default.
 
+=== No src/main/webapp
 
+Note that there is no `src/main/webapp/` or `WEB-INF/web.xml` - the servlets and filters are configured by Apache Isis automatically.
 
-== Using the App
 
-The generated application is almost identical similar to that generated by link:https://github.com/apache/isis-app-helloworld[helloworld starter app]; a description of how to use it can be found link:https://github.com/apache/isis-app-helloworld#using-the-app[here].
+=== webapp's src/test/java
 
-One additional feature that the simpleapp contains over the helloworld app is a home page.
-This shows all domain objects (as installed by fixture scripts, described link:https://github.com/apache/isis-app-simpleapp#running-with-fixtures[above]).
+Under `src/test/java` we have different sets of tests.
+We'll inspect each in turn.
 
-image::using-simple-app/030-home-page.png[width="600px",link="{imagesdir}/using-simple-app/030-home-page.png"]
+IMPORTANT: the naming convention -- with `Test`, `IntegTest` and `IntegBddSpecs` suffixes -- is important, because the Maven surefire plugin is configured to run multiple times, one `<execution>` for each suffix.
 
-It's also possible to run fixture scripts from the app itself:
+==== BDD Specs
 
-image::using-simple-app/040-run-fixture-script-menu.png[width="600px",link="{imagesdir}/using-simple-app/040-run-fixture-script-menu.png"]
+The simplapp starter app includes support for xref:testing:specsupport:about.adoc[BDD (Cucumber)] specifications.
+These reside under `domain.webapp.bdd`:
 
-Some fixture scripts may allow their default behaviour to be tweaked ((eg specify how many objects to create):
+[source]
+----
+src/test/java
+  domainapp/
+    webapp/
+      bdd/
+        glue/
+          SimpleObjectsStepDef.java                     <!--1-->
+        specs/
+          SimpleObjectSpec_listAllAndCreate.feature     <!--2-->
+        RunIntegBddSpecs.java                           <!--3-->
+----
+<1> defines the step definitions (or "glue") which describes how to interact with the application. +
+This class inherits from `ApplicationIntegTestAbstract`, the base class for integration tests, described in the xref:about.adoc#integration-tests[next section].
+<2> the feature file, discussed below.
+<3> boilerplate used to run the BDD Cucumber tests using JUni5 4.x.
 
-image::using-simple-app/050-run-fixture-script-prompt.png[width="600px",link="{imagesdir}/using-simple-app/050-run-fixture-script-prompt.png"]
+There is just one feature file: `SimpleObjectSpec_listAllAndCreate.feature`, which is pretty simple:
 
-The table summarises the resultant fixtures that were run:
+[source,feature]
+----
+Feature: List and Create New Simple Objects
 
-image::using-simple-app/060-run-fixture-script-result.png[width="600px",link="{imagesdir}/using-simple-app/060-run-fixture-script-result.png"]
+  Scenario: Existing simple objects can be listed and new ones created
+    Given there are initially 3 simple objects
+    When  I create a new simple object
+    Then  there are 4 simple objects
+----
 
-Navigating back to the home page shows the newly created objects:
+The set up of the 3 initial objects is part of the step definitions.
 
-image::using-simple-app/070-home-page.png[width="600px",link="{imagesdir}/using-simple-app/070-home-page.png"]
 
+==== Integration Tests
 
+The integration tests are in `domainapp.application.integtests`:
 
-== Using GitLab CI and DockerHub
+[source]
+----
+src/
+  test/
+    java/
+      domainapp/
+        webapp/
+          integtests/
+            metamodel/
+              lockdown/
+                approved/
+                  ...
+                current/
+                  ...
+                LockDownMetaModel_IntegTest.java    <!--1-->
+              ValidateDomainModel_IntegTest.java    <!--2-->
+            smoke/
+              Smoke_IntegTest.java                  <!--3-->
+            ApplicationIntegTestAbstract.java       <!--4-->
+----
+<1> Uses approval tests to verify that the metamodel is unchanged between releases of Apache Isis. +
+Discussed in more detail below.
+<2> Bootstraps the app and runs the metamodel validators to check that there are not metamodel errors. +
+This can also be done simply when running the application, but performing the checks through integration tests enables "fail-fast" checking, as part of CI, for example.
+<3> Performs a number of high-level smoke tests, to check that the core functionality works correctly.
+<4> Base class used to bootstrap all integration tests for this module.
+It is very similar to the base class used to bootstrap the integration tests for the simple module xref:about.adoc#SimpleModuleIntegTestAbstract[], but referencing `ApplicationModule` rather than `SimpleModule`.
 
-The archetype provides configuration files to allow you to build and package the application using link:https://gitlab.com/[GitLab] (for continuous integration pipelines) and link:https://hub.docker.com/[Docker Hub] (as a registry of Docker images).
+The purpose of the metamodel lockdown tests is to capture regressions in Apache Isis itself whenever it is updated.
 
-To use, you'll need an account on both GitLab and DockerHub.
+Normally the metamodel of the application will evolve all of the time, so the metamodel lockdown tests are disabled by default and only enabled with `-Dmetamodel.lockdown`.
+If you want to capture the current metamodel, then enable and they will likely fail.
+The new export of the metamodel will be in `current` and can simply be approved (by copying over to the `approved` directory.
 
-=== DockerHub
+However, if you are upgrading Apache Isis then you may want to check that the metamodel being built by the next version of Apache Isis is the same as previous.
+In this case, update Apache Isis (by updating the `<version> of the parent pom) and run the lockdown tests to check for differences.
 
-Simply create Docker repository "myapp" in DockerHub.
 
 
-=== Source code
+==== Unit Tests
 
-In the `.gitlab-ci.yml` file, update the name of the Docker repository on DockerHub:
+The integration tests are in `domainapp.application.unittests`:
 
-[source,yml]
+[source]
 ----
-variables:
-  ...
-  DOCKER_REGISTRY_REPOSITORY: "myapp"
+src/test/java
+  domainapp/
+    webapp/
+       unittests/
+         mavendeps/
+           lockdown/
+             approved/
+               ...
+             current/
+               ...
+             LockDownMavenDeps_Test.java                <!--1-->
+       util/
+         CurrentVsApprovedApprovalTextWriter.java       <!--2-->
 ----
+<1> lock down test to check the transitive set of dependencies used by the application
+<2> utility class used by the lock down tests (unit tests and integ tests).
 
-=== GitLab
+The maven dependency lock down tests are disabled by default, only enabled using `-Dmavendeps.lockdown`.
+The `pom.xml` is configured to run the Maven `dependency:tree` and `dependency:list` goals, capturing the current dependencies.
+These are compared to the approved versions.
 
-Create a git repository "myapp" in GitLab.
+Any time the Apache Isis version is updated, run these tests using `-Dmavendeps.lockdown` to capture and approve the new versions.
 
-Using Settings > CI/CD, specify the following _Secret Variables_:
+TIP: The Maven dependency lock down tests are useful to capture any accidental changes to the dependency tree, so consider enabling them all of the time.
 
-* `DOCKER_REGISTRY_USERNAME` - corresponds to user account name on DockerHub
-* `DOCKER_REGISTRY_PASSWORD` - corresponding password
-* `DOCKER_REGISTRY_EMAIL` - associated email for the user account
+=== Root module's pom.xml
 
-Finally, push a copy of the generated application to this repository using the instructions provided by GitLab.
+In the parent module we of course have the `pom.xml`.
+This inherits from `isis-app-starter-parent`:
 
-This will kick off a pipeline that will build the image and push to DockerHub.
+[source,xml]
+.pom.xml
+----
+<parent>
+    <groupId>org.apache.isis.app</groupId>
+    <artifactId>isis-app-starter-parent</artifactId>
+    <version>XXX</version>
+</parent>
+----
 
-image::dockerhub-tags.png[width="600px",link="{imagesdir}/dockerhub-tags.png"]
+\... which builds upon Spring Boot's own `org.springframework.boot:spring-boot-starter-parent`.
+This means:
 
-The tag name is based on a combination of the date, the branch and the git shaId.
+* the set of third party dependencies declared have been validated as compatible by Spring Boot team
+* build plugins are declared and configured appropriately
+* imports to the Apache Isis dependencies are declared via `<dependencyManagement>`
 
 
-=== Running the Image
 
-You can run the image in a new container using:
+== Running from within the IDE
 
-[source,bash]
-----
-docker run -p 8080:8080 -d XXX/YYY:ZZZ
-----
+Most of the time you'll probably want to run the app from within your IDE.
+The mechanics of doing this will vary by IDE; see the xref:toc:devguide:ide.adoc[Developers' Guide] for details of setting up Eclipse or IntelliJ IDEA.
+Basically, though, it amounts to running the `main()` method in the `SimpleApp`, but also (and this bit is important) ensuring that the xref:toc:devguide:hints-and-tips/datanucleus-enhancer.adoc[DataNucleus enhancer] has properly processed all domain entities.
 
-where
+Here's what the setup looks like in IntelliJ IDEA:
 
-* `XXX` is your DockerHub account name (`DOCKER_REGISTRY_USERNAME` secret variable in GitLab CI)
-* `YYY` is the name of the DockerHub registry (`DOCKER_REGISTRY_REPOSITORY` in the `.gitlab-ci.yml` file)
-* `ZZZ` is the tag of the image to run
+image::simpleapp-webapp.png[width="600px",link="{imagesdir}/simpleapp-webapp.png"]
 
+which uses an IntelliJ feature to run a different run configuration to run DataNucleus enhancer (discussed in more detail xref:toc:devguide:hints-and-tips/datanucleus-enhancer.adoc[here]) beforehand:
 
-For example, using the screenshot above, that image could be run using:
+image::simpleapp-webapp-before-launch.png[width="600px",link="{imagesdir}/simpleapp-webapp-before-launch.png"]
 
-[source,bash]
-----
-docker run -p 8080:8080 -d danhaywood/simpleapp:20180315.0935.master.4521215
-----
 
 
-== Modifying the App
+== Experimenting with the App
 
-Once you are familiar with the generated app, you'll want to start modifying it.
-There is plenty of guidance on this site; start with this guide (fundamentals) and then look at the other guides linked to from the top-level menu or from the main xref:toc:ROOT:about.adoc[table of contents].
+Once you are familiar with the app, try modifying it.
+There is plenty more guidance on this site; start with the xref:userguide:fun:about.adoc[User Guide Fundamentals] and then look at the other guides linked to from the top-level menu or from the main xref:toc:ROOT:about.adoc[table of contents].
 
 If you use IntelliJ IDEA or Eclipse, do also install the xref:toc:devguide:about.adoc#live-templates[live templates (for IntelliJ)] / xref:toc:devguide:about.adoc#editor-templates[editor templates (for Eclipse)]; these will help you follow the Apache Isis naming conventions.
 
+If you run into issues, please don't hesitate to ask for help on the users mailing list or the Slack channel, as per the xref:toc:ROOT:landing-page/support.adoc[support page].
+