You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/04/22 13:23:23 UTC

[isis] 01/01: ISIS-2622: CommandLog: split impl into JDO and JPA variants

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

ahuber pushed a commit to branch 2622_cmdLog.split
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f86a1fad48db0b01e7559b973d41c6c545bd8311
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Apr 22 11:55:53 2021 +0200

    ISIS-2622: CommandLog: split impl into JDO and JPA variants
---
 .../src/main/java/demoapp/dom/DemoModule.java      |   4 +-
 .../domain/_commands/ExposePersistedCommands.java  |   6 +-
 .../ExposePersistedCommands_commands.java          |   9 +-
 extensions/core/command-log/jdo/pom.xml            |  23 +---
 .../jdo/src/main/java/META-INF/persistence.xml     |   2 +-
 .../{impl => jdo}/CommandSubscriberForJdo.java     |   6 +-
 .../IsisModuleExtCommandLogJdo.java}               |  45 ++------
 .../{impl/jdo => jdo/entities}/CommandJdo.java     |  33 +++---
 .../entities}/CommandJdo.layout.fallback.xml       |   0
 .../{impl/jdo => jdo/entities}/CommandJdo.png      | Bin
 .../jdo => jdo/entities}/CommandJdoRepository.java |  88 +++++----------
 .../entities}/CommandJdo_childCommands.java        |  13 +--
 .../entities}/CommandJdo_openResultObject.java     |   6 +-
 .../entities}/CommandJdo_openTargetObject.java     |  12 +--
 .../jdo => jdo/entities}/CommandJdo_retry.java     |  13 +--
 .../entities}/CommandJdo_siblingCommands.java      |  12 +--
 .../mixins/HasInteractionId_command.java           |  10 +-
 .../mixins/HasUsername_recentCommandsByUser.java   |  10 +-
 .../mixins/Object_recentCommands.java              |  10 +-
 .../commandlog/{impl => jdo}/mixins/T_recent.java  |  10 +-
 .../{impl => jdo}/ui/CommandServiceMenu.java       |  14 +--
 extensions/core/command-log/{jdo => model}/pom.xml |  16 +--
 .../model/IsisModuleExtCommandLogModel.java        |  47 ++++++++
 .../commandlog/model/command/CommandModel.java     |  59 +++++++++++
 .../model/command/CommandModelRepository.java      | 118 +++++++++++++++++++++
 .../commandlog/model/command}/ReplayState.java     |   2 +-
 .../commandlog/model}/util/BigDecimalUtils.java    |   2 +-
 .../commandlog/model}/util/StringUtils.java        |   2 +-
 .../model}/util/StringUtils_trimmed_Test.java      |   4 +-
 extensions/core/command-log/pom.xml                |   1 +
 extensions/core/command-replay/primary/pom.xml     |   2 +-
 .../primary/IsisModuleExtCommandReplayPrimary.java |   4 +-
 .../primary/restapi/CommandRetrievalService.java   |  12 +--
 .../primary/spiimpl/CaptureResultOfCommand.java    |  19 ++--
 .../primary/ui/CommandReplayOnPrimaryService.java  |  12 +--
 extensions/core/command-replay/secondary/pom.xml   |   2 +-
 .../IsisModuleExtCommandReplaySecondary.java       |   4 +-
 .../secondary/analyser/CommandReplayAnalyser.java  |   4 +-
 .../analyser/CommandReplayAnalyserException.java   |   8 +-
 .../analyser/CommandReplayAnalyserResult.java      |   8 +-
 .../analysis/CommandReplayAnalysisService.java     |  13 ++-
 .../secondary/fetch/CommandFetcher.java            |   6 +-
 .../jobcallables/ReplicateAndRunCommands.java      |  36 ++++---
 .../secondary/mixins/CommandJdo_replayQueue.java   |  15 ++-
 ...dJdo_exclude.java => CommandModel_exclude.java} |  22 ++--
 .../ui/CommandReplayOnSecondaryService.java        |  14 ++-
 extensions/pom.xml                                 |  12 +++
 47 files changed, 454 insertions(+), 316 deletions(-)

diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModule.java b/examples/demo/domain/src/main/java/demoapp/dom/DemoModule.java
index bd14130..b2b6333 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModule.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/DemoModule.java
@@ -27,7 +27,7 @@ import org.springframework.context.annotation.PropertySources;
 
 import org.apache.isis.core.config.presets.IsisPresets;
 import org.apache.isis.core.runtimeservices.IsisModuleCoreRuntimeServices;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
 import org.apache.isis.extensions.secman.api.SecmanConfiguration;
 import org.apache.isis.extensions.secman.api.permission.PermissionsEvaluationService;
 import org.apache.isis.extensions.secman.api.permission.PermissionsEvaluationServiceAllowBeatsVeto;
@@ -42,7 +42,7 @@ import org.apache.isis.testing.fixtures.applib.IsisModuleTestingFixturesApplib;
 
     IsisModuleTestingFixturesApplib.class,
 
-    IsisModuleExtCommandLogImpl.class,
+    IsisModuleExtCommandLogJdo.class,
 
 })
 @PropertySources({
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands.java
index 9513cc8..40dce51 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands.java
@@ -26,7 +26,7 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.tablecol.TableColumnOrderForCollectionTypeAbstract;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 
 /**
  * Marker interface for mixins to contribute to.
@@ -36,9 +36,9 @@ public interface ExposePersistedCommands {
 
     @Service
     @Order(OrderPrecedence.EARLY)
-    public static class TableColumnOrderDefault extends TableColumnOrderForCollectionTypeAbstract<CommandJdo> {
+    public static class TableColumnOrderDefault extends TableColumnOrderForCollectionTypeAbstract<CommandModel> {
 
-        public TableColumnOrderDefault() { super(CommandJdo.class); }
+        public TableColumnOrderDefault() { super(CommandModel.class); }
 
         @Override
         protected List<String> orderParented(Object parent, String collectionId, List<String> propertyIds) {
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands_commands.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands_commands.java
index 2714b8c..d857ee6 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands_commands.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/_commands/ExposePersistedCommands_commands.java
@@ -18,18 +18,16 @@
  */
 package demoapp.dom.domain._commands;
 
-import java.util.LinkedList;
 import java.util.List;
 
 import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 
 import lombok.RequiredArgsConstructor;
-import lombok.val;
 
 //tag::class[]
 @Collection
@@ -41,8 +39,7 @@ public class ExposePersistedCommands_commands {
     private final ExposePersistedCommands exposePersistedCommands;
 
     //tag::class[]
-    public List<CommandJdo> coll() {
-        val list = new LinkedList<CommandJdo>();
+    public List<? extends CommandModel> coll() {
         return commandJdoRepository.findCompleted();
     }
 
diff --git a/extensions/core/command-log/jdo/pom.xml b/extensions/core/command-log/jdo/pom.xml
index 40afeae..bad42a9 100644
--- a/extensions/core/command-log/jdo/pom.xml
+++ b/extensions/core/command-log/jdo/pom.xml
@@ -46,25 +46,10 @@
 
     <dependencies>
 
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-applib</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core-config</artifactId>
-        </dependency>
-
-        <dependency>
-	    	<groupId>org.apache.isis.testing</groupId>
-        	<artifactId>isis-testing-fixtures-applib</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core-runtimeservices</artifactId>
-        </dependency>
+	    <dependency>
+	        <groupId>org.apache.isis.extensions</groupId>
+	        <artifactId>isis-extensions-command-log-model</artifactId>
+	    </dependency>
 
         <!-- PERSISTENCE -->
 
diff --git a/extensions/core/command-log/jdo/src/main/java/META-INF/persistence.xml b/extensions/core/command-log/jdo/src/main/java/META-INF/persistence.xml
index 26b8ff5..7719606 100644
--- a/extensions/core/command-log/jdo/src/main/java/META-INF/persistence.xml
+++ b/extensions/core/command-log/jdo/src/main/java/META-INF/persistence.xml
@@ -14,6 +14,6 @@
     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
 
     <persistence-unit name="org-apache-isis-extensions-commandlog">
-        <class>org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo</class>
+        <class>org.apache.isis.extensions.commandlog.jdo.entities.CommandModel</class>
     </persistence-unit>
 </persistence>
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/CommandSubscriberForJdo.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/CommandSubscriberForJdo.java
similarity index 93%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/CommandSubscriberForJdo.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/CommandSubscriberForJdo.java
index 0adf534..d54741f 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/CommandSubscriberForJdo.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/CommandSubscriberForJdo.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl;
+package org.apache.isis.extensions.commandlog.jdo;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -29,8 +29,8 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 import org.apache.isis.applib.util.JaxbUtil;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/IsisModuleExtCommandLogImpl.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/IsisModuleExtCommandLogJdo.java
similarity index 52%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/IsisModuleExtCommandLogImpl.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/IsisModuleExtCommandLogJdo.java
index 1353de3..d6fdb7a 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/IsisModuleExtCommandLogImpl.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/IsisModuleExtCommandLogJdo.java
@@ -16,17 +16,18 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl;
+package org.apache.isis.extensions.commandlog.jdo;
 
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
-import org.apache.isis.extensions.commandlog.impl.ui.CommandServiceMenu;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.ui.CommandServiceMenu;
+import org.apache.isis.extensions.commandlog.model.IsisModuleExtCommandLogModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript;
-import org.apache.isis.testing.fixtures.applib.modules.ModuleWithFixtures;
 import org.apache.isis.testing.fixtures.applib.teardown.jdo.TeardownFixtureJdoAbstract;
 
 /**
@@ -43,36 +44,10 @@ import org.apache.isis.testing.fixtures.applib.teardown.jdo.TeardownFixtureJdoAb
 })
 @ComponentScan(
         basePackageClasses= {
-                IsisModuleExtCommandLogImpl.class
+                IsisModuleExtCommandLogJdo.class
         })
-public class IsisModuleExtCommandLogImpl implements ModuleWithFixtures {
-
-    public abstract static class TitleUiEvent<S>
-            extends org.apache.isis.applib.events.ui.TitleUiEvent<S> { }
-
-    public abstract static class IconUiEvent<S>
-            extends org.apache.isis.applib.events.ui.IconUiEvent<S> { }
-
-    public abstract static class CssClassUiEvent<S>
-            extends org.apache.isis.applib.events.ui.CssClassUiEvent<S> { }
-
-    public abstract static class LayoutUiEvent<S>
-            extends org.apache.isis.applib.events.ui.LayoutUiEvent<S> { }
-
-    public abstract static class ActionDomainEvent<S>
-            extends org.apache.isis.applib.events.domain.ActionDomainEvent<S> { }
-
-    public abstract static class CollectionDomainEvent<S,T>
-            extends org.apache.isis.applib.events.domain.CollectionDomainEvent<S,T> { }
-
-    public abstract static class PropertyDomainEvent<S,T>
-            extends org.apache.isis.applib.events.domain.PropertyDomainEvent<S,T> { }
-
-    @Override
-    public FixtureScript getTeardownFixture() {
-        // can't delete from CommandJdo, is searched for during teardown (IsisSession#close)
-        return FixtureScript.NOOP;
-    }
+public class IsisModuleExtCommandLogJdo 
+implements IsisModuleExtCommandLogModel {
 
     /**
      * For tests that need to delete the command table first.
@@ -82,7 +57,7 @@ public class IsisModuleExtCommandLogImpl implements ModuleWithFixtures {
         return new TeardownFixtureJdoAbstract() {
             @Override
             protected void execute(final ExecutionContext executionContext) {
-                deleteFrom(CommandJdo.class);
+                deleteFrom(CommandModel.class);
             }
         };
     }
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java
similarity index 94%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java
index af99de4..b2690d2 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.jdo.entities;
 
 import java.math.BigDecimal;
 import java.sql.Timestamp;
@@ -47,7 +47,6 @@ import org.apache.isis.applib.mixins.system.DomainChangeRecord;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.command.CommandOutcomeHandler;
-import org.apache.isis.applib.services.commanddto.HasCommandDto;
 import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
 import org.apache.isis.applib.services.tablecol.TableColumnOrderForCollectionTypeAbstract;
 import org.apache.isis.applib.types.MemberIdentifierType;
@@ -56,9 +55,10 @@ import org.apache.isis.applib.util.TitleBuffer;
 import org.apache.isis.commons.functional.Result;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandlog.impl.util.BigDecimalUtils;
-import org.apache.isis.extensions.commandlog.impl.util.StringUtils;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.ReplayState;
+import org.apache.isis.extensions.commandlog.model.util.BigDecimalUtils;
+import org.apache.isis.extensions.commandlog.model.util.StringUtils;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 import org.apache.isis.schema.cmd.v2.MapDto;
 
@@ -247,24 +247,19 @@ import lombok.val;
 )
 @DomainObjectLayout(
         named = "Command",
-        titleUiEvent = CommandJdo.TitleUiEvent.class,
-        iconUiEvent = CommandJdo.IconUiEvent.class,
-        cssClassUiEvent = CommandJdo.CssClassUiEvent.class,
-        layoutUiEvent = CommandJdo.LayoutUiEvent.class
+        titleUiEvent = CommandModel.TitleUiEvent.class,
+        iconUiEvent = CommandModel.IconUiEvent.class,
+        cssClassUiEvent = CommandModel.CssClassUiEvent.class,
+        layoutUiEvent = CommandModel.LayoutUiEvent.class
 )
 //@Log4j2
 @NoArgsConstructor
 public class CommandJdo
-        implements DomainChangeRecord, Comparable<CommandJdo>, HasCommandDto {
+implements
+    CommandModel,
+    DomainChangeRecord, 
+    Comparable<CommandJdo> {
 
-    public static class TitleUiEvent extends IsisModuleExtCommandLogImpl.TitleUiEvent<CommandJdo> { }
-    public static class IconUiEvent extends IsisModuleExtCommandLogImpl.IconUiEvent<CommandJdo> { }
-    public static class CssClassUiEvent extends IsisModuleExtCommandLogImpl.CssClassUiEvent<CommandJdo> { }
-    public static class LayoutUiEvent extends IsisModuleExtCommandLogImpl.LayoutUiEvent<CommandJdo> { }
-
-    public static abstract class PropertyDomainEvent<T> extends IsisModuleExtCommandLogImpl.PropertyDomainEvent<CommandJdo, T> { }
-    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtCommandLogImpl.CollectionDomainEvent<CommandJdo, T> { }
-    public static abstract class ActionDomainEvent extends IsisModuleExtCommandLogImpl.ActionDomainEvent<CommandJdo> { }
 
     /**
      * Intended for use on primary system.
@@ -344,7 +339,7 @@ public class CommandJdo
             if(!Objects.equals(ev.getTitle(), "Command Jdo") || ev.getTranslatableTitle() != null) {
                 return;
             }
-            ev.setTitle(title(ev.getSource()));
+            ev.setTitle(title((CommandJdo)ev.getSource()));
         }
 
         private static String title(CommandJdo source) {
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.layout.fallback.xml b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.layout.fallback.xml
similarity index 100%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.layout.fallback.xml
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.layout.fallback.xml
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.png b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.png
similarity index 100%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.png
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo.png
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdoRepository.java
similarity index 81%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdoRepository.java
index b3e906e..1de0913 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdoRepository.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.jdo.entities;
 
 import java.sql.Timestamp;
 import java.time.Instant;
@@ -46,6 +46,9 @@ import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.iactn.InteractionContext;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModelRepository;
+import org.apache.isis.extensions.commandlog.model.command.ReplayState;
 import org.apache.isis.persistence.jdo.applib.services.JdoSupportService;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 import org.apache.isis.schema.cmd.v2.CommandsDto;
@@ -66,12 +69,14 @@ import lombok.val;
 @Qualifier("Jdo")
 @RequiredArgsConstructor
 //@Log4j2
-public class CommandJdoRepository {
+public class CommandJdoRepository
+implements CommandModelRepository<CommandJdo> {
 
     @Inject final Provider<InteractionContext> interactionContextProvider;
     @Inject final Provider<RepositoryService> repositoryServiceProvider;
     @Inject final JdoSupportService jdoSupport;
 
+    @Override
     public List<CommandJdo> findByFromAndTo(
             final @Nullable LocalDate from,
             final @Nullable LocalDate to) {
@@ -99,32 +104,33 @@ public class CommandJdoRepository {
         return repositoryService().allMatches(query);
     }
 
-
+    @Override
     public Optional<CommandJdo> findByInteractionId(final UUID interactionId) {
         return repositoryService().firstMatch(
                 Query.named(CommandJdo.class, "findByInteractionIdStr")
                     .withParameter("interactionIdStr", interactionId.toString()));
     }
 
-    public List<CommandJdo> findByParent(final CommandJdo parent) {
+    @Override
+    public List<CommandJdo> findByParent(final CommandModel parent) {
         return repositoryService().allMatches(
                 Query.named(CommandJdo.class, "findByParent")
                     .withParameter("parent", parent));
     }
 
-
+    @Override
     public List<CommandJdo> findCurrent() {
         return repositoryService().allMatches(
                 Query.named(CommandJdo.class, "findCurrent"));
     }
 
-
+    @Override
     public List<CommandJdo> findCompleted() {
         return repositoryService().allMatches(
                 Query.named(CommandJdo.class, "findCompleted"));
     }
 
-
+    @Override
     public List<CommandJdo> findByTargetAndFromAndTo(
             final Bookmark target,
             final @Nullable LocalDate from,
@@ -169,51 +175,21 @@ public class CommandJdoRepository {
                 : null;
     }
 
-
+    @Override
     public List<CommandJdo> findRecentByUsername(final String username) {
         return repositoryService().allMatches(
                 Query.named(CommandJdo.class, "findRecentByUsername")
                     .withParameter("username", username));
     }
 
-
+    @Override
     public List<CommandJdo> findRecentByTarget(final Bookmark target) {
         return repositoryService().allMatches(
                 Query.named(CommandJdo.class, "findRecentByTarget")
                     .withParameter("target", target));
     }
 
-
-    /**
-     * Intended to support the replay of commands on a secondary instance of
-     * the application.
-     *
-     * This finder returns all (completed) {@link CommandJdo}s started after
-     * the command with the specified interactionId.  The number of commands
-     * returned can be limited so that they can be applied in batches.
-     *
-     * If the provided interactionId is null, then only a single
-     * {@link CommandJdo command} is returned.  This is intended to support
-     * the case when the secondary does not yet have any
-     * {@link CommandJdo command}s replicated.  In practice this is unlikely;
-     * typically we expect that the secondary will be set up to run against a
-     * copy of the primary instance's DB (restored from a backup), in which
-     * case there will already be a {@link CommandJdo command} representing the
-     * current high water mark on the secondary system.
-     *
-     * If the interactionid is not null but the corresponding
-     * {@link CommandJdo command} is not found, then <tt>null</tt> is returned.
-     * In the replay scenario the caller will probably interpret this as an
-     * error because it means that the high water mark on the secondary is
-     * inaccurate, referring to a non-existent {@link CommandJdo command} on
-     * the primary.
-     *
-     * @param interactionId - the identifier of the {@link CommandJdo command} being
-     *                   the replay hwm (using {@link #findMostRecentReplayed()} on the
-     *                   secondary), or null if no HWM was found there.
-     * @param batchSize - to restrict the number returned (so that replay
-     *                   commands can be batched).
-     */
+    @Override
     public List<CommandJdo> findSince(final UUID interactionId, final Integer batchSize) {
         if(interactionId == null) {
             return findFirst();
@@ -265,51 +241,32 @@ public class CommandJdoRepository {
     }
 
 
-    /**
-     * The most recent replayed command previously replicated from primary to
-     * secondary.
-     *
-     * <p>
-     * This should always exist except for the very first times
-     * (after restored the prod DB to secondary).
-     * </p>
-     */
+    @Override
     public Optional<CommandJdo> findMostRecentReplayed() {
 
         return repositoryService().firstMatch(
                 Query.named(CommandJdo.class, "findMostRecentReplayed"));
     }
 
-    /**
-     * The most recent completed command, as queried on the
-     * secondary.
-     *
-     * <p>
-     *     After a restart following the production database being restored
-     *     from primary to secondary, would correspond to the last command
-     *     run on primary before the production database was restored to the
-     *     secondary.
-     * </p>
-     */
+    @Override
     public Optional<CommandJdo> findMostRecentCompleted() {
         return repositoryService().firstMatch(
                 Query.named(CommandJdo.class, "findMostRecentCompleted"));
     }
 
-
+    @Override
     public List<CommandJdo> findNotYetReplayed() {
         return repositoryService().allMatches(
                 Query.named(CommandJdo.class, "findNotYetReplayed"));
     }
 
-
-
+    @Override
     public List<CommandJdo> findReplayedOnSecondary() {
         return repositoryService().allMatches(
                 Query.named(CommandJdo.class, "findReplayableMostRecentStarted"));
     }
 
-
+    @Override
     public List<CommandJdo> saveForReplay(final CommandsDto commandsDto) {
         List<CommandDto> commandDto = commandsDto.getCommandDto();
         List<CommandJdo> commands = new ArrayList<>();
@@ -320,6 +277,7 @@ public class CommandJdoRepository {
     }
 
     @Programmatic
+    @Override
     public CommandJdo saveForReplay(final CommandDto dto) {
 
         if(dto.getMember().getInteractionType() == InteractionType.ACTION_INVOCATION) {
@@ -349,10 +307,12 @@ public class CommandJdoRepository {
         return commandJdo;
     }
 
+    @Override
     public void persist(final CommandJdo commandJdo) {
         repositoryService().persist(commandJdo);
     }
 
+    @Override
     public void truncateLog() {
         repositoryService().removeAll(CommandJdo.class);
     }
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_childCommands.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_childCommands.java
similarity index 78%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_childCommands.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_childCommands.java
index aa5b8f4..0f13f5a 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_childCommands.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_childCommands.java
@@ -16,13 +16,16 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.jdo.entities;
 
 import java.util.List;
 
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+
+import lombok.RequiredArgsConstructor;
 
 
 @Collection(
@@ -32,15 +35,13 @@ import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
     defaultView = "table",
     sequence = "100.100"
 )
+@RequiredArgsConstructor
 public class CommandJdo_childCommands {
 
     public static class CollectionDomainEvent
-            extends IsisModuleExtCommandLogImpl.CollectionDomainEvent<CommandJdo_childCommands, CommandJdo> { }
+            extends IsisModuleExtCommandLogJdo.CollectionDomainEvent<CommandJdo_childCommands, CommandModel> { }
 
     private final CommandJdo commandJdo;
-    public CommandJdo_childCommands(final CommandJdo commandJdo) {
-        this.commandJdo = commandJdo;
-    }
 
     public List<CommandJdo> coll() {
         return commandJdoRepository.findByParent(commandJdo);
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_openResultObject.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_openResultObject.java
similarity index 89%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_openResultObject.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_openResultObject.java
index 7c829cc..41db097 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_openResultObject.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_openResultObject.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.jdo.entities;
 
 import javax.inject.Inject;
 
@@ -25,7 +25,7 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.message.MessageService;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
 
 import lombok.val;
 
@@ -38,7 +38,7 @@ import lombok.val;
 public class CommandJdo_openResultObject {
 
     public static class ActionDomainEvent
-            extends IsisModuleExtCommandLogImpl.ActionDomainEvent<CommandJdo_openResultObject> { }
+            extends IsisModuleExtCommandLogJdo.ActionDomainEvent<CommandJdo_openResultObject> { }
 
     private final CommandJdo commandJdo;
     public CommandJdo_openResultObject(CommandJdo commandJdo) {
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_openTargetObject.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_openTargetObject.java
similarity index 85%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_openTargetObject.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_openTargetObject.java
index 440cf56..adc6c63 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_openTargetObject.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_openTargetObject.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.jdo.entities;
 
 import javax.inject.Inject;
 
@@ -25,8 +25,9 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.message.MessageService;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 
 @Action(
@@ -35,15 +36,14 @@ import lombok.val;
     associateWith = "target"
 )
 @ActionLayout(named = "Open", sequence="1")
+@RequiredArgsConstructor
 public class CommandJdo_openTargetObject {
 
     public static class ActionDomainEvent
-            extends IsisModuleExtCommandLogImpl.ActionDomainEvent<CommandJdo_openTargetObject> { }
+            extends IsisModuleExtCommandLogJdo.ActionDomainEvent<CommandJdo_openTargetObject> { }
 
     private final CommandJdo commandJdo;
-    public CommandJdo_openTargetObject(CommandJdo commandJdo) {
-        this.commandJdo = commandJdo;
-    }
+
 
     public Object act() {
         val targetBookmark = bookmarkService.lookup(commandJdo.getTarget()).orElse(null);
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_retry.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_retry.java
similarity index 88%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_retry.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_retry.java
index fe4b70a..4bd2451 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_retry.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_retry.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.jdo.entities;
 
 import javax.inject.Inject;
 
@@ -30,7 +30,10 @@ import org.apache.isis.applib.services.metamodel.MetaModelService;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.core.interaction.session.InteractionFactory;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+import org.apache.isis.extensions.commandlog.model.command.ReplayState;
+
+import lombok.RequiredArgsConstructor;
 
 @Action(
     semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE,
@@ -39,14 +42,12 @@ import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
     associateWith = "executeIn"
 )
 @ActionLayout(sequence = "1")
+@RequiredArgsConstructor
 public class CommandJdo_retry {
 
     private final CommandJdo commandJdo;
-    public CommandJdo_retry(CommandJdo commandJdo) {
-        this.commandJdo = commandJdo;
-    }
 
-    public static class ActionDomainEvent extends IsisModuleExtCommandLogImpl.ActionDomainEvent<CommandJdo_retry> { }
+    public static class ActionDomainEvent extends IsisModuleExtCommandLogJdo.ActionDomainEvent<CommandJdo_retry> { }
     
     public CommandJdo act() {
 
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_siblingCommands.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_siblingCommands.java
similarity index 82%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_siblingCommands.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_siblingCommands.java
index d9b1a90..f64c797 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo_siblingCommands.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/entities/CommandJdo_siblingCommands.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.jdo.entities;
 
 import java.util.Collections;
 import java.util.List;
@@ -25,7 +25,9 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+
+import lombok.RequiredArgsConstructor;
 
 @Collection(
     domainEvent = CommandJdo_siblingCommands.CollectionDomainEvent.class
@@ -34,15 +36,13 @@ import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
     defaultView = "table",
     sequence = "100.110"
 )
+@RequiredArgsConstructor
 public class CommandJdo_siblingCommands {
 
     public static class CollectionDomainEvent
-            extends IsisModuleExtCommandLogImpl.CollectionDomainEvent<CommandJdo_siblingCommands, CommandJdo> { }
+            extends IsisModuleExtCommandLogJdo.CollectionDomainEvent<CommandJdo_siblingCommands, CommandJdo> { }
 
     private final CommandJdo commandJdo;
-    public CommandJdo_siblingCommands(final CommandJdo commandJdo) {
-        this.commandJdo = commandJdo;
-    }
 
     public List<CommandJdo> coll() {
         final CommandJdo parentJdo = commandJdo.getParent();
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasInteractionId_command.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/HasInteractionId_command.java
similarity index 87%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasInteractionId_command.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/HasInteractionId_command.java
index c045310..55d80ec 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasInteractionId_command.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/HasInteractionId_command.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.mixins;
+package org.apache.isis.extensions.commandlog.jdo.mixins;
 
 import java.util.UUID;
 
@@ -27,9 +27,9 @@ import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
 
 import lombok.RequiredArgsConstructor;
 
@@ -51,7 +51,7 @@ import lombok.RequiredArgsConstructor;
 public class HasInteractionId_command {
 
     public static class ActionDomainEvent
-            extends IsisModuleExtCommandLogImpl.ActionDomainEvent<HasInteractionId_command> { }
+            extends IsisModuleExtCommandLogJdo.ActionDomainEvent<HasInteractionId_command> { }
 
     private final HasInteractionId hasInteractionId;
 
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUsername_recentCommandsByUser.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/HasUsername_recentCommandsByUser.java
similarity index 82%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUsername_recentCommandsByUser.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/HasUsername_recentCommandsByUser.java
index 6065e21..2067ab5 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/HasUsername_recentCommandsByUser.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/HasUsername_recentCommandsByUser.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.mixins;
+package org.apache.isis.extensions.commandlog.jdo.mixins;
 
 import java.util.Collections;
 import java.util.List;
@@ -26,9 +26,9 @@ import javax.inject.Inject;
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
 import org.apache.isis.applib.mixins.security.HasUsername;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
 
 
 /**
@@ -44,7 +44,7 @@ import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
 public class HasUsername_recentCommandsByUser {
 
     public static class CollectionDomainEvent
-            extends IsisModuleExtCommandLogImpl.CollectionDomainEvent<HasUsername_recentCommandsByUser, CommandJdo> { }
+            extends IsisModuleExtCommandLogJdo.CollectionDomainEvent<HasUsername_recentCommandsByUser, CommandJdo> { }
 
     private final HasUsername hasUsername;
     public HasUsername_recentCommandsByUser(final HasUsername hasUsername) {
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/Object_recentCommands.java
similarity index 88%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/Object_recentCommands.java
index 9e0f564..810eeb5 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/Object_recentCommands.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/Object_recentCommands.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.mixins;
+package org.apache.isis.extensions.commandlog.jdo.mixins;
 
 import java.util.Collections;
 import java.util.List;
@@ -31,9 +31,9 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.mixins.layout.LayoutMixinConstants;
 import org.apache.isis.applib.mixins.system.HasInteractionId;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
 
 /**
  * This mixin contributes a <tt>recentCommands</tt> action to any domain object
@@ -57,7 +57,7 @@ import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
 public class Object_recentCommands {
 
     public static class ActionDomainEvent
-            extends IsisModuleExtCommandLogImpl.ActionDomainEvent<Object_recentCommands> { }
+            extends IsisModuleExtCommandLogJdo.ActionDomainEvent<Object_recentCommands> { }
 
     private final Object domainObject;
     public Object_recentCommands(final Object domainObject) {
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/T_recent.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/T_recent.java
similarity index 84%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/T_recent.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/T_recent.java
index ac24af5..4fe2d81 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/mixins/T_recent.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/mixins/T_recent.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.mixins;
+package org.apache.isis.extensions.commandlog.jdo.mixins;
 
 import java.util.Collections;
 import java.util.List;
@@ -27,9 +27,9 @@ import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
 
 @Collection(
     domainEvent = T_recent.CollectionDomainEvent.class
@@ -40,7 +40,7 @@ import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
 public abstract class T_recent<T> {
 
     public static class CollectionDomainEvent
-            extends IsisModuleExtCommandLogImpl.CollectionDomainEvent<T_recent, CommandJdo> { }
+            extends IsisModuleExtCommandLogJdo.CollectionDomainEvent<T_recent, CommandJdo> { }
 
     private final T domainObject;
     public T_recent(final T domainObject) {
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/ui/CommandServiceMenu.java b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/ui/CommandServiceMenu.java
similarity index 89%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/ui/CommandServiceMenu.java
rename to extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/ui/CommandServiceMenu.java
index 957e6eb..bab99ad 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/ui/CommandServiceMenu.java
+++ b/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/jdo/ui/CommandServiceMenu.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.ui;
+package org.apache.isis.extensions.commandlog.jdo.ui;
 
 import java.time.LocalDate;
 import java.time.ZoneId;
@@ -43,9 +43,9 @@ import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.RestrictTo;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.clock.ClockService;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.jdo.IsisModuleExtCommandLogJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdo;
+import org.apache.isis.extensions.commandlog.jdo.entities.CommandJdoRepository;
 
 import lombok.RequiredArgsConstructor;
 
@@ -68,11 +68,11 @@ import lombok.RequiredArgsConstructor;
 public class CommandServiceMenu {
 
     public static abstract class PropertyDomainEvent<T>
-            extends IsisModuleExtCommandLogImpl.PropertyDomainEvent<CommandServiceMenu, T> { }
+            extends IsisModuleExtCommandLogJdo.PropertyDomainEvent<CommandServiceMenu, T> { }
     public static abstract class CollectionDomainEvent<T>
-            extends IsisModuleExtCommandLogImpl.CollectionDomainEvent<CommandServiceMenu, T> { }
+            extends IsisModuleExtCommandLogJdo.CollectionDomainEvent<CommandServiceMenu, T> { }
     public static abstract class ActionDomainEvent
-            extends IsisModuleExtCommandLogImpl.ActionDomainEvent<CommandServiceMenu> {
+            extends IsisModuleExtCommandLogJdo.ActionDomainEvent<CommandServiceMenu> {
     }
 
     final CommandJdoRepository commandServiceRepository;
diff --git a/extensions/core/command-log/jdo/pom.xml b/extensions/core/command-log/model/pom.xml
similarity index 88%
copy from extensions/core/command-log/jdo/pom.xml
copy to extensions/core/command-log/model/pom.xml
index 40afeae..b177e40 100644
--- a/extensions/core/command-log/jdo/pom.xml
+++ b/extensions/core/command-log/model/pom.xml
@@ -19,12 +19,12 @@
         <version>2.0.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>isis-extensions-command-log-jdo</artifactId>
-    <name>Apache Isis Ext - Command Log Implementation (JDO)</name>
+    <artifactId>isis-extensions-command-log-model</artifactId>
+    <name>Apache Isis Ext - Command Log Model</name>
 
     <properties>
-        <jar-plugin.automaticModuleName>org.apache.isis.extensions.commandlog.jdo</jar-plugin.automaticModuleName>
-        <git-plugin.propertiesDir>org/apache/isis/extensions/commandlog/jdo</git-plugin.propertiesDir>
+        <jar-plugin.automaticModuleName>org.apache.isis.extensions.commandlog.model</jar-plugin.automaticModuleName>
+        <git-plugin.propertiesDir>org/apache/isis/extensions/commandlog/model</git-plugin.propertiesDir>
     </properties>
 
     <build>
@@ -66,14 +66,6 @@
             <artifactId>isis-core-runtimeservices</artifactId>
         </dependency>
 
-        <!-- PERSISTENCE -->
-
-		<dependency>
-            <groupId>org.apache.isis.mavendeps</groupId>
-			<artifactId>isis-mavendeps-jdo</artifactId>
-			<type>pom</type>
-        </dependency>
-
         <!-- Testing -->
 
         <dependency>
diff --git a/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/IsisModuleExtCommandLogModel.java b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/IsisModuleExtCommandLogModel.java
new file mode 100644
index 0000000..b75b1a8
--- /dev/null
+++ b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/IsisModuleExtCommandLogModel.java
@@ -0,0 +1,47 @@
+/*
+ *  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 agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.extensions.commandlog.model;
+
+import org.apache.isis.testing.fixtures.applib.modules.ModuleWithFixtures;
+
+public interface IsisModuleExtCommandLogModel 
+extends ModuleWithFixtures {
+
+    public abstract static class TitleUiEvent<S>
+        extends org.apache.isis.applib.events.ui.TitleUiEvent<S> { }
+
+    public abstract static class IconUiEvent<S>
+        extends org.apache.isis.applib.events.ui.IconUiEvent<S> { }
+    
+    public abstract static class CssClassUiEvent<S>
+        extends org.apache.isis.applib.events.ui.CssClassUiEvent<S> { }
+    
+    public abstract static class LayoutUiEvent<S>
+        extends org.apache.isis.applib.events.ui.LayoutUiEvent<S> { }
+    
+    public abstract static class ActionDomainEvent<S>
+        extends org.apache.isis.applib.events.domain.ActionDomainEvent<S> { }
+    
+    public abstract static class CollectionDomainEvent<S,T>
+        extends org.apache.isis.applib.events.domain.CollectionDomainEvent<S,T> { }
+    
+    public abstract static class PropertyDomainEvent<S,T>
+        extends org.apache.isis.applib.events.domain.PropertyDomainEvent<S,T> { }
+    
+}
diff --git a/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/CommandModel.java b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/CommandModel.java
new file mode 100644
index 0000000..33e610c
--- /dev/null
+++ b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/CommandModel.java
@@ -0,0 +1,59 @@
+/*
+ *  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 agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.extensions.commandlog.model.command;
+
+import java.sql.Timestamp;
+import java.util.UUID;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.command.CommandOutcomeHandler;
+import org.apache.isis.applib.services.commanddto.HasCommandDto;
+import org.apache.isis.extensions.commandlog.model.IsisModuleExtCommandLogModel;
+
+public interface CommandModel extends HasCommandDto {
+    
+    public static class TitleUiEvent extends IsisModuleExtCommandLogModel.TitleUiEvent<CommandModel> { }
+    public static class IconUiEvent extends IsisModuleExtCommandLogModel.IconUiEvent<CommandModel> { }
+    public static class CssClassUiEvent extends IsisModuleExtCommandLogModel.CssClassUiEvent<CommandModel> { }
+    public static class LayoutUiEvent extends IsisModuleExtCommandLogModel.LayoutUiEvent<CommandModel> { }
+
+    public static abstract class PropertyDomainEvent<T> extends IsisModuleExtCommandLogModel.PropertyDomainEvent<CommandModel, T> { }
+    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtCommandLogModel.CollectionDomainEvent<CommandModel, T> { }
+    public static abstract class ActionDomainEvent extends IsisModuleExtCommandLogModel.ActionDomainEvent<CommandModel> { }
+
+    
+    Bookmark getResult();
+    
+    String getException();
+
+    Timestamp getStartedAt();
+
+    Timestamp getCompletedAt();
+
+    void saveAnalysis(String analysis);
+
+    UUID getInteractionId();
+    
+    ReplayState getReplayState();
+
+    CommandOutcomeHandler outcomeHandler();
+
+    void setReplayState(ReplayState excluded);
+
+}
diff --git a/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/CommandModelRepository.java b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/CommandModelRepository.java
new file mode 100644
index 0000000..3929e4e
--- /dev/null
+++ b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/CommandModelRepository.java
@@ -0,0 +1,118 @@
+/*
+ *  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 agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.extensions.commandlog.model.command;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.schema.cmd.v2.CommandDto;
+import org.apache.isis.schema.cmd.v2.CommandsDto;
+
+public interface CommandModelRepository<C extends CommandModel> {
+
+    Optional<C> findByInteractionId(UUID interactionId);
+
+    List<C> findByParent(CommandModel parent);
+
+    List<C> findByFromAndTo(LocalDate from, LocalDate to);
+
+    List<C> findCurrent();
+
+    List<C> findCompleted();
+
+    List<C> findByTargetAndFromAndTo(Bookmark target, LocalDate from, LocalDate to);
+
+    List<C> findRecentByUsername(String username);
+
+    List<C> findRecentByTarget(Bookmark target);
+    
+    /**
+     * Intended to support the replay of commands on a secondary instance of
+     * the application.
+     *
+     * This finder returns all (completed) {@link CommandModel}s started after
+     * the command with the specified interactionId.  The number of commands
+     * returned can be limited so that they can be applied in batches.
+     *
+     * If the provided interactionId is null, then only a single
+     * {@link CommandModel command} is returned.  This is intended to support
+     * the case when the secondary does not yet have any
+     * {@link CommandModel command}s replicated.  In practice this is unlikely;
+     * typically we expect that the secondary will be set up to run against a
+     * copy of the primary instance's DB (restored from a backup), in which
+     * case there will already be a {@link CommandModel command} representing the
+     * current high water mark on the secondary system.
+     *
+     * If the interactionId is not null but the corresponding
+     * {@link CommandModel command} is not found, then <tt>null</tt> is returned.
+     * In the replay scenario the caller will probably interpret this as an
+     * error because it means that the high water mark on the secondary is
+     * inaccurate, referring to a non-existent {@link CommandModel command} on
+     * the primary.
+     *
+     * @param interactionId - the identifier of the {@link CommandModel command} being
+     *                   the replay hwm (using {@link #findMostRecentReplayed()} on the
+     *                   secondary), or null if no HWM was found there.
+     * @param batchSize - to restrict the number returned (so that replay
+     *                   commands can be batched).
+     */
+    List<C> findSince(UUID interactionId, Integer batchSize);
+
+    /**
+     * The most recent replayed command previously replicated from primary to
+     * secondary.
+     *
+     * <p>
+     * This should always exist except for the very first times
+     * (after restored the prod DB to secondary).
+     * </p>
+     */
+    Optional<C> findMostRecentReplayed();
+
+    /**
+     * The most recent completed command, as queried on the
+     * secondary.
+     *
+     * <p>
+     *     After a restart following the production database being restored
+     *     from primary to secondary, would correspond to the last command
+     *     run on primary before the production database was restored to the
+     *     secondary.
+     * </p>
+     */
+    Optional<C> findMostRecentCompleted();
+
+    List<C> findNotYetReplayed();
+
+    List<C> findReplayedOnSecondary();
+
+    C saveForReplay(CommandDto dto);
+    
+    List<C> saveForReplay(CommandsDto commandsDto);
+
+    void persist(C commandJdo);
+
+    void truncateLog();
+
+    
+    
+}
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/ReplayState.java b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/ReplayState.java
similarity index 95%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/ReplayState.java
rename to extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/ReplayState.java
index e4ebdb6..75d99e6 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/ReplayState.java
+++ b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/command/ReplayState.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.jdo;
+package org.apache.isis.extensions.commandlog.model.command;
 
 public enum ReplayState {
     /**
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/util/BigDecimalUtils.java b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/util/BigDecimalUtils.java
similarity index 96%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/util/BigDecimalUtils.java
rename to extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/util/BigDecimalUtils.java
index a4b9e58..7d27553 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/util/BigDecimalUtils.java
+++ b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/util/BigDecimalUtils.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.util;
+package org.apache.isis.extensions.commandlog.model.util;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
diff --git a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/util/StringUtils.java b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/util/StringUtils.java
similarity index 95%
rename from extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/util/StringUtils.java
rename to extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/util/StringUtils.java
index 5ee0d20..9e613c6 100644
--- a/extensions/core/command-log/jdo/src/main/java/org/apache/isis/extensions/commandlog/impl/util/StringUtils.java
+++ b/extensions/core/command-log/model/src/main/java/org/apache/isis/extensions/commandlog/model/util/StringUtils.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.util;
+package org.apache.isis.extensions.commandlog.model.util;
 
 import lombok.experimental.UtilityClass;
 
diff --git a/extensions/core/command-log/jdo/src/test/java/org/apache/isis/extensions/commandlog/impl/util/StringUtils_trimmed_Test.java b/extensions/core/command-log/model/src/test/java/org/apache/isis/extensions/commandlog/model/util/StringUtils_trimmed_Test.java
similarity index 91%
rename from extensions/core/command-log/jdo/src/test/java/org/apache/isis/extensions/commandlog/impl/util/StringUtils_trimmed_Test.java
rename to extensions/core/command-log/model/src/test/java/org/apache/isis/extensions/commandlog/model/util/StringUtils_trimmed_Test.java
index 524c305..2c2d6b3 100644
--- a/extensions/core/command-log/jdo/src/test/java/org/apache/isis/extensions/commandlog/impl/util/StringUtils_trimmed_Test.java
+++ b/extensions/core/command-log/model/src/test/java/org/apache/isis/extensions/commandlog/model/util/StringUtils_trimmed_Test.java
@@ -16,11 +16,13 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.commandlog.impl.util;
+package org.apache.isis.extensions.commandlog.model.util;
 
 import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import org.apache.isis.extensions.commandlog.model.util.StringUtils;
+
 public class StringUtils_trimmed_Test {
 
     @Test
diff --git a/extensions/core/command-log/pom.xml b/extensions/core/command-log/pom.xml
index 7f87aee..932a38a 100644
--- a/extensions/core/command-log/pom.xml
+++ b/extensions/core/command-log/pom.xml
@@ -40,6 +40,7 @@
 	</dependencyManagement>
 
 	<modules>
+		<module>model</module>
 		<module>jdo</module>
 		<module>jpa</module>
 	</modules>
diff --git a/extensions/core/command-replay/primary/pom.xml b/extensions/core/command-replay/primary/pom.xml
index b83a439..4b00bba 100644
--- a/extensions/core/command-replay/primary/pom.xml
+++ b/extensions/core/command-replay/primary/pom.xml
@@ -66,7 +66,7 @@
 
         <dependency>
             <groupId>org.apache.isis.extensions</groupId>
-            <artifactId>isis-extensions-command-log-jdo</artifactId>
+            <artifactId>isis-extensions-command-log-model</artifactId>
         </dependency>
 
     </dependencies>
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/IsisModuleExtCommandReplayPrimary.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/IsisModuleExtCommandReplayPrimary.java
index 8864f2b..f249f0e 100644
--- a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/IsisModuleExtCommandReplayPrimary.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/IsisModuleExtCommandReplayPrimary.java
@@ -22,7 +22,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
 
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.model.IsisModuleExtCommandLogModel;
 import org.apache.isis.extensions.commandreplay.primary.config.PrimaryConfig;
 import org.apache.isis.extensions.commandreplay.primary.mixins.Object_openOnSecondary;
 import org.apache.isis.extensions.commandreplay.primary.restapi.CommandRetrievalService;
@@ -35,7 +35,7 @@ import org.apache.isis.extensions.commandreplay.primary.ui.CommandReplayOnPrimar
 @Configuration
 @Import({
         // @Configuration's
-        IsisModuleExtCommandLogImpl.class,
+        IsisModuleExtCommandLogModel.class,
 
         // @Service's
         CommandRetrievalService.class,
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/restapi/CommandRetrievalService.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/restapi/CommandRetrievalService.java
index 5a17174..1b8ead9 100644
--- a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/restapi/CommandRetrievalService.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/restapi/CommandRetrievalService.java
@@ -34,8 +34,8 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.exceptions.RecoverableException;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModelRepository;
 import org.apache.isis.extensions.commandreplay.primary.IsisModuleExtCommandReplayPrimary;
 
 import lombok.Getter;
@@ -75,7 +75,7 @@ public class CommandRetrievalService {
      * @throws NotFoundException - if the command with specified transaction cannot be found.
      */
     @Action(domainEvent = FindCommandsOnPrimaryFromDomainEvent.class, semantics = SemanticsOf.SAFE)
-    public List<CommandJdo> findCommandsOnPrimaryFrom(
+    public List<? extends CommandModel> findCommandsOnPrimaryFrom(
             @Nullable
             @ParameterLayout(named="Interaction Id")
             final UUID interactionId,
@@ -83,7 +83,7 @@ public class CommandRetrievalService {
             @ParameterLayout(named="Batch size")
             final Integer batchSize)
             throws NotFoundException {
-        final List<CommandJdo> commands = commandServiceRepository.findSince(interactionId, batchSize);
+        final List<? extends CommandModel> commands = commandModelRepository.findSince(interactionId, batchSize);
         if(commands == null) {
             throw new NotFoundException(interactionId);
         }
@@ -93,8 +93,6 @@ public class CommandRetrievalService {
         return 25;
     }
 
-
-
-    @Inject CommandJdoRepository commandServiceRepository;
+    @Inject CommandModelRepository<? extends CommandModel> commandModelRepository;
 }
 
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/spiimpl/CaptureResultOfCommand.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/spiimpl/CaptureResultOfCommand.java
index 8d4136d..c926ea7 100644
--- a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/spiimpl/CaptureResultOfCommand.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/spiimpl/CaptureResultOfCommand.java
@@ -20,7 +20,6 @@ package org.apache.isis.extensions.commandreplay.primary.spiimpl;
 
 import javax.inject.Named;
 
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
@@ -31,10 +30,8 @@ import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
 import org.apache.isis.applib.services.commanddto.processor.spi.CommandDtoProcessorService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 import org.apache.isis.schema.cmd.v2.CommandDto;
-import org.apache.isis.schema.common.v2.PeriodDto;
 
 import lombok.val;
 
@@ -55,16 +52,16 @@ public class CaptureResultOfCommand implements CommandDtoProcessorService {
     @Override
     public CommandDto process(final Object domainObject, CommandDto commandDto) {
 
-        if (!(domainObject instanceof CommandJdo)) {
+        if (!(domainObject instanceof CommandModel)) {
             return commandDto;
         }
 
-        val commandJdo = (CommandJdo) domainObject;
+        val commandModel = (CommandModel) domainObject;
         if(commandDto == null) {
-            commandDto = commandJdo.getCommandDto();
+            commandDto = commandModel.getCommandDto();
         }
 
-        final Bookmark result = commandJdo.getResult();
+        final Bookmark result = commandModel.getResult();
         CommandDtoUtils.setUserData(commandDto, UserDataKeys.RESULT, result);
 
         // knowing whether there was an exception is on the primary is
@@ -72,11 +69,11 @@ public class CaptureResultOfCommand implements CommandDtoProcessorService {
         // secondary if an exception occurs there also
         CommandDtoUtils.setUserData(commandDto,
                 UserDataKeys.EXCEPTION,
-                commandJdo.getException());
+                commandModel.getException());
 
         val timings = CommandDtoUtils.timingsFor(commandDto);
-        timings.setStartedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(commandJdo.getStartedAt()));
-        timings.setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(commandJdo.getCompletedAt()));
+        timings.setStartedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(commandModel.getStartedAt()));
+        timings.setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(commandModel.getCompletedAt()));
 
         return commandDto;
     }
diff --git a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
index ca1c916..cfdfee9 100644
--- a/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
+++ b/extensions/core/command-replay/primary/src/main/java/org/apache/isis/extensions/commandreplay/primary/ui/CommandReplayOnPrimaryService.java
@@ -40,8 +40,8 @@ import org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceFo
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.applib.value.Clob;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModelRepository;
 import org.apache.isis.extensions.commandreplay.primary.IsisModuleExtCommandReplayPrimary;
 import org.apache.isis.extensions.commandreplay.primary.restapi.CommandRetrievalService;
 import org.apache.isis.schema.cmd.v2.CommandDto;
@@ -67,7 +67,7 @@ import lombok.RequiredArgsConstructor;
 //@Log4j2
 public class CommandReplayOnPrimaryService {
 
-    @Inject final CommandJdoRepository commandServiceRepository;
+    @Inject final CommandModelRepository<? extends CommandModel> commandModelRepository;
     @Inject final JaxbService jaxbService;
     @Inject final MessageService messageService;
     @Inject final ContentMappingServiceForCommandsDto contentMappingServiceForCommandsDto;
@@ -98,7 +98,7 @@ public class CommandReplayOnPrimaryService {
      */
     @Action(domainEvent = FindCommandsDomainEvent.class, semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa = "fa-search", sequence="40")
-    public List<CommandJdo> findCommands(
+    public List<? extends CommandModel> findCommands(
             @Nullable
             @ParameterLayout(named="Interaction Id")
             final UUID interactionId,
@@ -131,7 +131,7 @@ public class CommandReplayOnPrimaryService {
             @Nullable
             final Integer batchSize,
             final String filenamePrefix) {
-        final List<CommandJdo> commands = commandServiceRepository.findSince(interactionId, batchSize);
+        final List<? extends CommandModel> commands = commandModelRepository.findSince(interactionId, batchSize);
         if(commands == null) {
             messageService.informUser("No commands found");
         }
@@ -168,7 +168,7 @@ public class CommandReplayOnPrimaryService {
             final UUID interactionId,
             final String filenamePrefix) {
 
-        return commandServiceRepository.findByInteractionId(interactionId)
+        return commandModelRepository.findByInteractionId(interactionId)
                 .map(commandJdo -> {
 
                     final CommandDto commandDto = commandJdo.getCommandDto();
diff --git a/extensions/core/command-replay/secondary/pom.xml b/extensions/core/command-replay/secondary/pom.xml
index 963d3d2..5385399 100644
--- a/extensions/core/command-replay/secondary/pom.xml
+++ b/extensions/core/command-replay/secondary/pom.xml
@@ -67,7 +67,7 @@
 
         <dependency>
             <groupId>org.apache.isis.extensions</groupId>
-            <artifactId>isis-extensions-command-log-jdo</artifactId>
+            <artifactId>isis-extensions-command-log-model</artifactId>
         </dependency>
 
         <dependency>
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/IsisModuleExtCommandReplaySecondary.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/IsisModuleExtCommandReplaySecondary.java
index cf016ca..634dd8f 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/IsisModuleExtCommandReplaySecondary.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/IsisModuleExtCommandReplaySecondary.java
@@ -38,7 +38,7 @@ import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
 import org.springframework.scheduling.quartz.SpringBeanJobFactory;
 
 import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
+import org.apache.isis.extensions.commandlog.model.IsisModuleExtCommandLogModel;
 import org.apache.isis.extensions.commandreplay.secondary.analyser.CommandReplayAnalyserException;
 import org.apache.isis.extensions.commandreplay.secondary.analyser.CommandReplayAnalyserResult;
 import org.apache.isis.extensions.commandreplay.secondary.analysis.CommandReplayAnalysisService;
@@ -60,7 +60,7 @@ import lombok.val;
 @Configuration
 @Import({
         // @Configuration's
-        IsisModuleExtCommandLogImpl.class,
+        IsisModuleExtCommandLogModel.class,
         IsisModuleExtQuartzImpl.class,
 
         // @Service's
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyser.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyser.java
index 1255b2f..4264739 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyser.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyser.java
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.extensions.commandreplay.secondary.analyser;
 
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 
 /**
  * @since 2.0 {@index}
@@ -30,6 +30,6 @@ public interface CommandReplayAnalyser {
      * @param commandJdo
      * @return - if not <code>null</code>, indicates the reason that there was an issue replaying the command.
      */
-    String analyzeReplay(final CommandJdo commandJdo);
+    String analyzeReplay(final CommandModel commandJdo);
 
 }
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserException.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserException.java
index cd3aaa1..0741859 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserException.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserException.java
@@ -31,7 +31,7 @@ import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 import org.apache.isis.schema.common.v2.InteractionType;
 
 import lombok.RequiredArgsConstructor;
@@ -55,12 +55,12 @@ public class CommandReplayAnalyserException implements CommandReplayAnalyser {
     }
 
     @Override
-    public String analyzeReplay(final CommandJdo commandJdo) {
+    public String analyzeReplay(final CommandModel commandModel) {
         if(!enabled) {
             return null;
         }
 
-        val dto = commandJdo.getCommandDto();
+        val dto = commandModel.getCommandDto();
         if(dto.getMember().getInteractionType() == InteractionType.PROPERTY_EDIT) {
             return null;
         }
@@ -70,7 +70,7 @@ public class CommandReplayAnalyserException implements CommandReplayAnalyser {
             return null;
         }
 
-        val replayedException = commandJdo.getException();
+        val replayedException = commandModel.getException();
 
         val primaryExceptionTrimmed = trimmed(primaryException);
         val replayedExceptionTrimmed = trimmed(replayedException);
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserResult.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserResult.java
index 4a0d206..97f0863 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserResult.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analyser/CommandReplayAnalyserResult.java
@@ -30,7 +30,7 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.commanddto.conmap.UserDataKeys;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
 import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 import org.apache.isis.schema.common.v2.InteractionType;
 
 import lombok.RequiredArgsConstructor;
@@ -54,12 +54,12 @@ public class CommandReplayAnalyserResult implements CommandReplayAnalyser {
     }
 
     @Override
-    public String analyzeReplay(final CommandJdo commandJdo) {
+    public String analyzeReplay(final CommandModel commandModel) {
         if(!enabled) {
             return null;
         }
 
-        val dto = commandJdo.getCommandDto();
+        val dto = commandModel.getCommandDto();
         if(dto.getMember().getInteractionType() == InteractionType.PROPERTY_EDIT) {
             return null;
         }
@@ -68,7 +68,7 @@ public class CommandReplayAnalyserResult implements CommandReplayAnalyser {
         // ... either the same result when replayed
         val primaryResultStr = CommandDtoUtils.getUserData(dto, UserDataKeys.RESULT);
 
-        val secondaryResult = commandJdo.getResult();
+        val secondaryResult = commandModel.getResult();
         val secondaryResultStr =
                 secondaryResult != null ? secondaryResult.toString() : null;
         return Objects.equals(primaryResultStr, secondaryResultStr)
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analysis/CommandReplayAnalysisService.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analysis/CommandReplayAnalysisService.java
index 9f1494e..4af9cc0 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analysis/CommandReplayAnalysisService.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/analysis/CommandReplayAnalysisService.java
@@ -26,9 +26,8 @@ import javax.inject.Named;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
-import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 import org.apache.isis.extensions.commandreplay.secondary.analyser.CommandReplayAnalyser;
 
 import lombok.extern.log4j.Log4j2;
@@ -45,15 +44,15 @@ public class CommandReplayAnalysisService {
     /**
      * if hit an issue with the command having been replayed, then mark this
      * as in error.
-     * This will effectively block the running of any further commands until the adminstrator fixes the issue.
+     * This will effectively block the running of any further commands until the administrator fixes the issue.
      */
-    public void analyse(final CommandJdo commandJdo) {
-        final String analysis = analyseReplay(commandJdo);
+    public void analyse(final CommandModel commandModel) {
+        final String analysis = analyseReplay(commandModel);
 
-        commandJdo.saveAnalysis(analysis);
+        commandModel.saveAnalysis(analysis);
     }
 
-    private String analyseReplay(final CommandJdo commandJdo) {
+    private String analyseReplay(final CommandModel commandJdo) {
 
         for (final CommandReplayAnalyser analyser : analysers) {
             try {
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
index c2bb972..8322b3f 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/fetch/CommandFetcher.java
@@ -35,7 +35,7 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.jaxb.JaxbService.Simple;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
 import org.apache.isis.extensions.commandreplay.secondary.SecondaryStatus;
 import org.apache.isis.extensions.commandreplay.secondary.StatusException;
 import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
@@ -68,7 +68,7 @@ public class CommandFetcher {
      * @throws StatusException
      */
     public List<CommandDto> fetchCommand(
-            @Nullable final CommandJdo previousHwmIfAny)
+            @Nullable final CommandModel previousHwmIfAny)
             throws StatusException {
 
         log.debug("finding command on primary ...");
@@ -84,7 +84,7 @@ public class CommandFetcher {
      * @param previousHwmIfAny
      * @throws StatusException
      */
-    private CommandsDto fetchCommands(final CommandJdo previousHwmIfAny)
+    private CommandsDto fetchCommands(final CommandModel previousHwmIfAny)
             throws StatusException {
 
         final UUID transactionId = previousHwmIfAny != null ? previousHwmIfAny.getInteractionId() : null;
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
index e3403353..2590ad8 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
@@ -27,9 +27,9 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.services.command.CommandExecutorService;
 import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
-import org.apache.isis.extensions.commandlog.impl.jdo.ReplayState;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModelRepository;
+import org.apache.isis.extensions.commandlog.model.command.ReplayState;
 import org.apache.isis.extensions.commandreplay.secondary.SecondaryStatus;
 import org.apache.isis.extensions.commandreplay.secondary.StatusException;
 import org.apache.isis.extensions.commandreplay.secondary.analysis.CommandReplayAnalysisService;
@@ -57,7 +57,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
     @Inject CommandExecutorService commandExecutorService;
     @Inject TransactionService transactionService;
     @Inject CommandFetcher commandFetcher;
-    @Inject CommandJdoRepository commandJdoRepository;
+    @Inject CommandModelRepository<? extends CommandModel> commandModelRepository;
     @Inject CommandReplayAnalysisService analysisService;
     @Inject Optional<ReplayCommandExecutionController> controller;
 
@@ -78,18 +78,18 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
             return;
         }
 
-        List<CommandJdo> commandsToReplay;
+        List<? extends CommandModel> commandsToReplay;
 
         while(isRunning()) {
 
             // is there a pending command already?
             // (we fetch several at a time, so we may not have processed them all yet)
-            commandsToReplay = commandJdoRepository.findNotYetReplayed();
+            commandsToReplay = commandModelRepository.findNotYetReplayed();
 
             if(commandsToReplay.isEmpty()) {
 
                 // look for previously replayed on secondary
-                CommandJdo hwm = commandJdoRepository.findMostRecentReplayed().orElse(null);
+                CommandModel hwm = commandModelRepository.findMostRecentReplayed().orElse(null);
 
                 if (hwm != null) {
                     // give up if there was a failure; admin will need to fix issue and retry
@@ -102,7 +102,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
                     // after a DB restore from primary to secondary, there won't be
                     // any that have been replayed.  So instead we simply use
                     // latest completed (on primary) as the HWM.
-                    hwm = commandJdoRepository.findMostRecentCompleted().orElse(null);
+                    hwm = commandModelRepository.findMostRecentCompleted().orElse(null);
                 }
 
                 // fetch next command(s) from primary (if any)
@@ -110,10 +110,11 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
                 commandsToReplay = commandDtos.stream()
                         .map(dto ->
                                 transactionService.callWithinCurrentTransactionElseCreateNew(
-                                    () -> commandJdoRepository.saveForReplay(dto))
+                                    () -> commandModelRepository.saveForReplay(dto))
                                 .optionalElseFail()
                                 .orElse(null)
-                        ).collect(Collectors.toList());
+                        )
+                        .collect(Collectors.toList());
 
                 if(commandsToReplay.isEmpty()) {
                     return; // nothing more to do for now.
@@ -129,16 +130,16 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
      * @param commandsToReplay
      * @apiNote could return, whether there was a command to process (and so continue)
      */
-    private void replay(List<CommandJdo> commandsToReplay) {
+    private void replay(List<? extends CommandModel> commandsToReplay) {
 
-        commandsToReplay.forEach(commandJdo -> {
+        commandsToReplay.forEach(commandModel -> {
 
-            log.info("replaying {}", commandJdo.getInteractionId());
+            log.info("replaying {}", commandModel.getInteractionId());
 
             //
             // run command
             //
-            val replayState = executeCommandInTranAndAnalyse(commandJdo);
+            val replayState = executeCommandInTranAndAnalyse(commandModel);
             if(replayState.isFailed()) {
                 // will effectively block the running of any further commands
                 // until the issue is fixed.
@@ -148,10 +149,11 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
             //
             // find child commands, and run them
             //
-            val parent = commandJdo;
+            val parent = commandModel;
+            
             val childCommands =
                     transactionService.callWithinCurrentTransactionElseCreateNew(
-                            () -> commandJdoRepository.findByParent(parent))
+                            () -> commandModelRepository.findByParent(parent))
                     .optionalElseFail()
                     .orElse(null);
             for (val childCommand : childCommands) {
@@ -167,7 +169,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
 
     }
 
-    private ReplayState executeCommandInTranAndAnalyse(final CommandJdo commandJdo) {
+    private ReplayState executeCommandInTranAndAnalyse(final CommandModel commandJdo) {
         transactionService.runWithinCurrentTransactionElseCreateNew(
                 () -> {
                     commandExecutorService.executeCommand(
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayQueue.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayQueue.java
index f0e5aa3..81e34a1 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayQueue.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_replayQueue.java
@@ -24,8 +24,8 @@ import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.CollectionLayout;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModelRepository;
 import org.apache.isis.extensions.commandreplay.secondary.IsisModuleExtCommandReplaySecondary;
 import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
 
@@ -45,19 +45,18 @@ import lombok.RequiredArgsConstructor;
 public class CommandJdo_replayQueue {
 
     public static class CollectionDomainEvent
-            extends IsisModuleExtCommandReplaySecondary.CollectionDomainEvent<CommandJdo_replayQueue, CommandJdo> { }
+            extends IsisModuleExtCommandReplaySecondary.CollectionDomainEvent<CommandJdo_replayQueue, CommandModel> { }
 
-    final CommandJdo commandJdo;
+    final CommandModel commandModel;
 
-    
-    public List<CommandJdo> coll() {
-        return commandJdoRepository.findReplayedOnSecondary();
+    public List<? extends CommandModel> coll() {
+        return commandModelRepository.findReplayedOnSecondary();
     }
     public boolean hideColl() {
         return !secondaryConfig.isConfigured();
     }
 
     @Inject SecondaryConfig secondaryConfig;
-    @Inject CommandJdoRepository commandJdoRepository;
+    @Inject CommandModelRepository<? extends CommandModel> commandModelRepository;
 
 }
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_exclude.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandModel_exclude.java
similarity index 73%
rename from extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_exclude.java
rename to extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandModel_exclude.java
index 475bc8f..81190cf 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandJdo_exclude.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/mixins/CommandModel_exclude.java
@@ -25,9 +25,9 @@ import javax.inject.Inject;
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
 import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.ReplayState;
+import org.apache.isis.extensions.commandlog.model.IsisModuleExtCommandLogModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.ReplayState;
 import org.apache.isis.extensions.commandreplay.secondary.config.SecondaryConfig;
 
 import lombok.RequiredArgsConstructor;
@@ -38,22 +38,22 @@ import lombok.RequiredArgsConstructor;
  */
 @Action(
     semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE,
-    domainEvent = CommandJdo_exclude.ActionDomainEvent.class,
+    domainEvent = CommandModel_exclude.ActionDomainEvent.class,
     associateWith = "executeIn"
 )
 @ActionLayout(sequence = "2")
 @RequiredArgsConstructor
 //@Log4j2
-public class CommandJdo_exclude {
+public class CommandModel_exclude {
 
     public static class ActionDomainEvent
-            extends IsisModuleExtCommandLogImpl.ActionDomainEvent<CommandJdo_exclude> { }
+            extends IsisModuleExtCommandLogModel.ActionDomainEvent<CommandModel_exclude> { }
 
-    final CommandJdo commandJdo;
+    final CommandModel commandModel;
 
-    public CommandJdo act() {
-        commandJdo.setReplayState(ReplayState.EXCLUDED);
-        return commandJdo;
+    public CommandModel act() {
+        commandModel.setReplayState(ReplayState.EXCLUDED);
+        return commandModel;
     }
 
     public boolean hideAct() {
@@ -61,7 +61,7 @@ public class CommandJdo_exclude {
     }
     public String disableAct() {
         final boolean notInError =
-                commandJdo.getReplayState() == null || !commandJdo.getReplayState().isFailed();
+                commandModel.getReplayState() == null || !commandModel.getReplayState().isFailed();
         return notInError
                 ? "This command is not in error, so cannot be excluded."
                 : null;
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
index d40ddc7..0742f19 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/ui/CommandReplayOnSecondaryService.java
@@ -35,8 +35,8 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.value.Clob;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdoRepository;
+import org.apache.isis.extensions.commandlog.model.command.CommandModel;
+import org.apache.isis.extensions.commandlog.model.command.CommandModelRepository;
 import org.apache.isis.extensions.commandreplay.secondary.IsisModuleExtCommandReplaySecondary;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 import org.apache.isis.schema.cmd.v2.CommandsDto;
@@ -61,7 +61,7 @@ import lombok.val;
 //@Log4j2
 public class CommandReplayOnSecondaryService {
 
-    @Inject final CommandJdoRepository commandJdoRepository;
+    @Inject CommandModelRepository<? extends CommandModel> commandModelRepository;
     @Inject final JaxbService jaxbService;
 
     public static abstract class ActionDomainEvent
@@ -70,12 +70,10 @@ public class CommandReplayOnSecondaryService {
     public static class FindMostRecentReplayedDomainEvent extends ActionDomainEvent { }
     @Action(domainEvent = FindMostRecentReplayedDomainEvent.class, semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa = "fa-bath", sequence="60.1")
-    public CommandJdo findMostRecentReplayed() {
-        return commandJdoRepository.findMostRecentReplayed().orElse(null);
+    public CommandModel findMostRecentReplayed() {
+        return commandModelRepository.findMostRecentReplayed().orElse(null);
     }
 
-
-
     public static class UploadCommandsDomainEvent extends ActionDomainEvent { }
     @Action(
         domainEvent = UploadCommandsDomainEvent.class,
@@ -96,7 +94,7 @@ public class CommandReplayOnSecondaryService {
         }
 
         for (final CommandDto commandDto : commandDtoList) {
-            commandJdoRepository.saveForReplay(commandDto);
+            commandModelRepository.saveForReplay(commandDto);
         }
     }
 
diff --git a/extensions/pom.xml b/extensions/pom.xml
index f7be91f..72b51e9 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -67,12 +67,24 @@
 
 			<dependency>
 				<groupId>org.apache.isis.extensions</groupId>
+				<artifactId>isis-extensions-command-log-model</artifactId>
+				<version>2.0.0-SNAPSHOT</version>
+			</dependency>
+
+			<dependency>
+				<groupId>org.apache.isis.extensions</groupId>
 				<artifactId>isis-extensions-command-log-jdo</artifactId>
 				<version>2.0.0-SNAPSHOT</version>
 			</dependency>
 
 			<dependency>
 				<groupId>org.apache.isis.extensions</groupId>
+				<artifactId>isis-extensions-command-log-jpa</artifactId>
+				<version>2.0.0-SNAPSHOT</version>
+			</dependency>
+
+			<dependency>
+				<groupId>org.apache.isis.extensions</groupId>
 				<artifactId>isis-extensions-quartz-impl</artifactId>
 				<version>2.0.0-SNAPSHOT</version>
 			</dependency>