third iteration server side implementation
diff --git a/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/Charge.java b/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/Charge.java
index 20dcf56..d408616 100644
--- a/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/Charge.java
+++ b/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/Charge.java
@@ -22,8 +22,6 @@
 public class Charge {
 
   @ValidIdentifier
-  private String identifier;
-  @ValidIdentifier
   private String actionIdentifier;
   @ValidIdentifier
   private String incomeAccountIdentifier;
@@ -37,15 +35,7 @@
     super();
   }
 
-  public String getIdentifier() {
-    return this.identifier;
-  }
-
-  public void setIdentifier(final String identifier) {
-    this.identifier = identifier;
-  }
-
-  public String getActionIdentifier() {
+ public String getActionIdentifier() {
     return this.actionIdentifier;
   }
 
diff --git a/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java b/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java
index 98171f2..d17694d 100644
--- a/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java
+++ b/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java
@@ -16,7 +16,6 @@
 package io.mifos.deposit.api.v1.definition.domain;
 
 import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
 
 public class ProductDefinitionCommand {
 
@@ -29,7 +28,7 @@
   private Action action;
   private String note;
   private String createdBy;
-  private LocalDateTime createdOn;
+  private String createdOn;
 
   public ProductDefinitionCommand() {
     super();
@@ -59,11 +58,11 @@
     this.createdBy = createdBy;
   }
 
-  public LocalDateTime getCreatedOn() {
+  public String getCreatedOn() {
     return this.createdOn;
   }
 
-  public void setCreatedOn(final LocalDateTime createdOn) {
+  public void setCreatedOn(final String createdOn) {
     this.createdOn = createdOn;
   }
 }
diff --git a/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/StateChange.java b/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/StateChange.java
deleted file mode 100644
index 9e678fe..0000000
--- a/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/StateChange.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.deposit.api.v1.instance.domain;
-
-import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
-
-public class StateChange {
-
-  @NotNull
-  private String state;
-  private String note;
-  private String createdBy;
-  private LocalDateTime createdOn;
-
-  public StateChange() {
-    super();
-  }
-
-  public String getState() {
-    return this.state;
-  }
-
-  public void setState(final String state) {
-    this.state = state;
-  }
-
-  public String getNote() {
-    return this.note;
-  }
-
-  public void setNote(final String note) {
-    this.note = note;
-  }
-
-  public String getCreatedBy() {
-    return this.createdBy;
-  }
-
-  public void setCreatedBy(final String createdBy) {
-    this.createdBy = createdBy;
-  }
-
-  public LocalDateTime getCreatedOn() {
-    return this.createdOn;
-  }
-
-  public void setCreatedOn(final LocalDateTime createdOn) {
-    this.createdOn = createdOn;
-  }
-}
diff --git a/component-test/src/main/java/io/mifos/deposit/AbstractDepositAccountManagementTest.java b/component-test/src/main/java/io/mifos/deposit/AbstractDepositAccountManagementTest.java
new file mode 100644
index 0000000..fa16c72
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/AbstractDepositAccountManagementTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit;
+
+import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import io.mifos.core.api.context.AutoUserContext;
+import io.mifos.core.lang.ApplicationName;
+import io.mifos.core.test.env.TestEnvironment;
+import io.mifos.core.test.fixture.TenantDataStoreContextTestRule;
+import io.mifos.core.test.fixture.cassandra.CassandraInitializer;
+import io.mifos.core.test.fixture.mariadb.MariaDBInitializer;
+import io.mifos.core.test.listener.EnableEventRecording;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.deposit.api.v1.EventConstants;
+import io.mifos.deposit.api.v1.client.DepositAccountManager;
+import io.mifos.deposit.service.DepositAccountManagementConfiguration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(
+    webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
+    classes = {AbstractDepositAccountManagementTest.TestConfiguration.class})
+public abstract class AbstractDepositAccountManagementTest {
+
+  private static final String APP_NAME = "deposit-v1";
+  private static final String TEST_USER = "shed";
+  public static final String TEST_LOGGER = "test-logger";
+
+  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
+  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+  @ClassRule
+  public static TestRule orderClassRules = RuleChain
+      .outerRule(testEnvironment)
+      .around(cassandraInitializer)
+      .around(mariaDBInitializer)
+      .around(tenantDataStoreContext);
+
+  @Rule
+  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+      = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+
+  @Autowired
+  @Qualifier(TEST_LOGGER)
+  private Logger logger;
+
+  @Autowired
+  DepositAccountManager depositAccountManager;
+
+  @Autowired
+  private ApplicationName applicationName;
+
+  @Autowired
+  EventRecorder eventRecorder;
+
+  private AutoUserContext autoUserContext;
+
+  AbstractDepositAccountManagementTest() {
+    super();
+  }
+
+  @Before
+  public void prepTest() throws Exception {
+    this.autoUserContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(AbstractDepositAccountManagementTest.TEST_USER);
+  }
+
+  @After
+  public void cleanTest() throws Exception {
+    this.autoUserContext.close();
+  }
+
+  public boolean waitForInitialize() {
+    try {
+      final String version = this.applicationName.getVersionString();
+      this.logger.info("Waiting on initialize event for version: {}.", version);
+      return this.eventRecorder.wait(EventConstants.INITIALIZE, version);
+    } catch (final InterruptedException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Configuration
+  @EnableEventRecording
+  @EnableFeignClients(basePackages = {"io.mifos.deposit.api.v1"})
+  @RibbonClient(name = APP_NAME)
+  @Import({DepositAccountManagementConfiguration.class})
+  @ComponentScan("io.mifos.deposit.listener")
+  public static class TestConfiguration {
+    public TestConfiguration() {
+      super();
+    }
+
+    @Bean(name= TEST_LOGGER)
+    public Logger logger() {
+      return LoggerFactory.getLogger(TEST_LOGGER);
+    }
+  }
+}
+
diff --git a/component-test/src/main/java/io/mifos/deposit/Fixture.java b/component-test/src/main/java/io/mifos/deposit/Fixture.java
new file mode 100644
index 0000000..21cee88
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/Fixture.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit;
+
+import io.mifos.deposit.api.v1.definition.domain.Charge;
+import io.mifos.deposit.api.v1.definition.domain.Currency;
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
+import io.mifos.deposit.api.v1.definition.domain.Term;
+import io.mifos.deposit.api.v1.domain.InterestPayable;
+import io.mifos.deposit.api.v1.domain.TimeUnit;
+import io.mifos.deposit.api.v1.domain.Type;
+import org.apache.commons.lang3.RandomStringUtils;
+
+import java.util.Arrays;
+
+public class Fixture {
+
+  public Fixture() {
+    super();
+  }
+
+  static ProductDefinition productDefinition() {
+    final Charge openingCharge = new Charge();
+    openingCharge.setActionIdentifier("Open");
+    openingCharge.setAmount(2.00D);
+    openingCharge.setName("Opening Account Charge");
+    openingCharge.setIncomeAccountIdentifier("10123");
+    openingCharge.setProportional(Boolean.FALSE);
+
+    final Charge closingCharge = new Charge();
+    closingCharge.setActionIdentifier("Close");
+    closingCharge.setAmount(2.00D);
+    closingCharge.setName("Closing Account Fee");
+    closingCharge.setIncomeAccountIdentifier("10123");
+    closingCharge.setProportional(Boolean.FALSE);
+
+    final Term term = new Term();
+    term.setPeriod(12);
+    term.setTimeUnit(TimeUnit.MONTH.name());
+    term.setInterestPayable(InterestPayable.MATURITY.name());
+
+    final Currency currency = new Currency();
+    currency.setCode("USD");
+    currency.setName("US Dollar");
+    currency.setSign("$");
+    currency.setScale(3);
+
+    final ProductDefinition productDefinition = new ProductDefinition();
+    productDefinition.setType(Type.SHARE.name());
+    productDefinition.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    productDefinition.setName(RandomStringUtils.randomAlphanumeric(256));
+    productDefinition.setDescription(RandomStringUtils.randomAlphanumeric(2048));
+    productDefinition.setCharges(Arrays.asList(openingCharge, closingCharge));
+    productDefinition.setCurrency(currency);
+    productDefinition.setInterest(1.25D);
+    productDefinition.setEquityLedgerIdentifier("20300");
+    productDefinition.setExpenseAccountIdentifier("30300");
+    productDefinition.setFlexible(Boolean.FALSE);
+    productDefinition.setMinimumBalance(50.00);
+    productDefinition.setTerm(term);
+
+    return productDefinition;
+  }
+
+}
diff --git a/component-test/src/main/java/io/mifos/deposit/TestActions.java b/component-test/src/main/java/io/mifos/deposit/TestActions.java
new file mode 100644
index 0000000..4d34f83
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/TestActions.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit;
+
+import io.mifos.deposit.api.v1.definition.domain.Action;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+public class TestActions extends AbstractDepositAccountManagementTest {
+
+  public TestActions() {
+    super();
+  }
+
+  @Test
+  public void shouldFetchDefaultActions() {
+    final List<Action> actions = super.depositAccountManager.fetchActions();
+
+    Assert.assertEquals(5, actions.size());
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/deposit/TestProductDefinition.java b/component-test/src/main/java/io/mifos/deposit/TestProductDefinition.java
new file mode 100644
index 0000000..f7011a9
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/TestProductDefinition.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit;
+
+import io.mifos.deposit.api.v1.EventConstants;
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestProductDefinition extends AbstractDepositAccountManagementTest {
+
+  public TestProductDefinition() {
+    super();
+  }
+
+  @Test
+  public void shouldCreateProductDefinition() throws Exception {
+    final ProductDefinition productDefinition = Fixture.productDefinition();
+
+    super.depositAccountManager.create(productDefinition);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier());
+  }
+
+  @Test
+  public void shouldFindProductDefinition() throws Exception {
+    final ProductDefinition productDefinition = Fixture.productDefinition();
+
+    super.depositAccountManager.create(productDefinition);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier());
+
+    final ProductDefinition fetchedProductDefinition = super.depositAccountManager.findProductDefinition(productDefinition.getIdentifier());
+
+    Assert.assertNotNull(fetchedProductDefinition);
+    Assert.assertNotNull(fetchedProductDefinition.getCharges());
+    Assert.assertEquals(2, fetchedProductDefinition.getCharges().size());
+    Assert.assertNotNull(fetchedProductDefinition.getCurrency());
+    Assert.assertNotNull(fetchedProductDefinition.getTerm());
+    Assert.assertFalse(fetchedProductDefinition.getActive());
+  }
+
+  @Test
+  public void shouldActivateProductDefinition() throws Exception {
+    final ProductDefinition productDefinition = Fixture.productDefinition();
+
+    super.depositAccountManager.create(productDefinition);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier());
+
+    final ProductDefinitionCommand productDefinitionCommand = new ProductDefinitionCommand();
+    productDefinitionCommand.setAction(ProductDefinitionCommand.Action.ACTIVATE.name());
+    productDefinitionCommand.setNote(RandomStringUtils.randomAlphanumeric(2048));
+
+    super.depositAccountManager.process(productDefinition.getIdentifier(), productDefinitionCommand);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION_COMMAND, productDefinition.getIdentifier());
+
+    final ProductDefinition fetchedProductDefinition = super.depositAccountManager.findProductDefinition(productDefinition.getIdentifier());
+
+    Assert.assertTrue(fetchedProductDefinition.getActive());
+  }
+
+  @Test
+  public void shouldDeactivateProductDefinition() throws Exception {
+    final ProductDefinition productDefinition = Fixture.productDefinition();
+
+    super.depositAccountManager.create(productDefinition);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier());
+
+    final ProductDefinitionCommand productDefinitionCommand = new ProductDefinitionCommand();
+    productDefinitionCommand.setAction(ProductDefinitionCommand.Action.DEACTIVATE.name());
+    productDefinitionCommand.setNote(RandomStringUtils.randomAlphanumeric(2048));
+
+    super.depositAccountManager.process(productDefinition.getIdentifier(), productDefinitionCommand);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION_COMMAND, productDefinition.getIdentifier());
+
+    final ProductDefinition fetchProductDefinition = super.depositAccountManager.findProductDefinition(productDefinition.getIdentifier());
+
+    Assert.assertFalse(fetchProductDefinition.getActive());
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java b/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java
new file mode 100644
index 0000000..f6c6224
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit;
+
+import io.mifos.deposit.api.v1.EventConstants;
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
+import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+public class TestProductInstance extends AbstractDepositAccountManagementTest {
+
+  public TestProductInstance() {
+    super();
+  }
+
+  @Test
+  public void shouldCreateProductInstance() throws Exception {
+    final String customerIdentifier = "08154711";
+    final ProductDefinition productDefinition = Fixture.productDefinition();
+
+    super.depositAccountManager.create(productDefinition);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier());
+
+    final ProductInstance productInstance = new ProductInstance();
+    productInstance.setProductIdentifier(productDefinition.getIdentifier());
+    productInstance.setCustomerIdentifier(customerIdentifier);
+    productInstance.setAccountIdentifier("60606");
+
+    super.depositAccountManager.create(productInstance);
+
+    super.eventRecorder.wait(EventConstants.POST_PRODUCT_INSTANCE, customerIdentifier);
+
+    final List<ProductInstance> productInstances = super.depositAccountManager.findProductInstances(productDefinition.getIdentifier());
+    Assert.assertNotNull(productInstances);
+    Assert.assertEquals(1, productInstances.size());
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/deposit/listener/MigrationEventListener.java b/component-test/src/main/java/io/mifos/deposit/listener/MigrationEventListener.java
new file mode 100644
index 0000000..7cd9a44
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/listener/MigrationEventListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit.listener;
+
+import io.mifos.core.lang.config.TenantHeaderFilter;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.deposit.AbstractDepositAccountManagementTest;
+import io.mifos.deposit.api.v1.EventConstants;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MigrationEventListener {
+
+  private final Logger logger;
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public MigrationEventListener(@Qualifier(AbstractDepositAccountManagementTest.TEST_LOGGER) final Logger logger,
+                                final EventRecorder eventRecorder) {
+    super();
+    this.logger = logger;
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_INITIALIZE,
+      subscription = EventConstants.DESTINATION
+  )
+  public void onInitialize(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                          final String payload) {
+    this.logger.debug("Service initialized.");
+    this.eventRecorder.event(tenant, EventConstants.INITIALIZE, payload, String.class);
+  }
+
+}
diff --git a/component-test/src/main/java/io/mifos/deposit/listener/ProductDefinitionEventListener.java b/component-test/src/main/java/io/mifos/deposit/listener/ProductDefinitionEventListener.java
new file mode 100644
index 0000000..1000cbd
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/listener/ProductDefinitionEventListener.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit.listener;
+
+import io.mifos.core.lang.config.TenantHeaderFilter;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.deposit.AbstractDepositAccountManagementTest;
+import io.mifos.deposit.api.v1.EventConstants;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ProductDefinitionEventListener {
+
+  private final Logger logger;
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public ProductDefinitionEventListener(@Qualifier(AbstractDepositAccountManagementTest.TEST_LOGGER) final Logger logger,
+                                        final EventRecorder eventRecorder) {
+    super();
+    this.logger = logger;
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_PRODUCT_DEFINITION,
+      subscription = EventConstants.DESTINATION
+  )
+  public void onCreateProductDefinition(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                                        final String payload) {
+    this.logger.debug("Product definition created.");
+    this.eventRecorder.event(tenant, EventConstants.POST_PRODUCT_DEFINITION, payload, String.class);
+  }
+
+  @JmsListener(
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_PRODUCT_COMMAND,
+      subscription = EventConstants.DESTINATION
+  )
+  public void onActivateProductDefinition(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                                          final String payload) {
+    this.logger.debug("Product definition activated.");
+    this.eventRecorder.event(tenant, EventConstants.POST_PRODUCT_DEFINITION_COMMAND, payload, String.class);
+  }
+}
diff --git a/component-test/src/main/java/io/mifos/deposit/listener/ProductInstanceEventListener.java b/component-test/src/main/java/io/mifos/deposit/listener/ProductInstanceEventListener.java
new file mode 100644
index 0000000..94b36c9
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/deposit/listener/ProductInstanceEventListener.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit.listener;
+
+import io.mifos.core.lang.config.TenantHeaderFilter;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.deposit.api.v1.EventConstants;
+import io.mifos.deposit.service.ServiceConstants;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ProductInstanceEventListener {
+
+  private final Logger logger;
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public ProductInstanceEventListener(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                                      final EventRecorder eventRecorder) {
+    super();
+    this.logger = logger;
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_PRODUCT_INSTANCE,
+      subscription = EventConstants.DESTINATION
+  )
+  public void onCreateInstance(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String payload) {
+    this.logger.debug("Product instance created.");
+    this.eventRecorder.event(tenant, EventConstants.POST_PRODUCT_INSTANCE, payload, String.class);
+  }
+}
diff --git a/component-test/src/main/resources/logback-test.xml b/component-test/src/main/resources/logback-test.xml
new file mode 100644
index 0000000..f34f73c
--- /dev/null
+++ b/component-test/src/main/resources/logback-test.xml
@@ -0,0 +1,32 @@
+<!--
+
+    Copyright 2017 The Mifos Initiative.
+
+    Licensed 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.
+
+-->
+<configuration>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="org" level="INFO"/>
+    <logger name="com" level="INFO"/>
+    <logger name="ch" level="OFF"/>
+
+    <root level="DEBUG">
+        <appender-ref ref="STDOUT"/>
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/MigrationCommand.java b/service/src/main/java/io/mifos/deposit/service/internal/command/MigrationCommand.java
new file mode 100644
index 0000000..5f405a9
--- /dev/null
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/MigrationCommand.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit.service.internal.command;
+
+public class MigrationCommand {
+
+  public MigrationCommand() {
+    super();
+  }
+}
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ActionAggregate.java b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ActionAggregate.java
index 81aa4af..8dcde7c 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ActionAggregate.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ActionAggregate.java
@@ -27,6 +27,7 @@
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Transactional;
 
 @Aggregate
 public class ActionAggregate {
@@ -43,6 +44,7 @@
 
   @CommandHandler
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_ACTION)
+  @Transactional
   public String createAction(final CreateActionCommand createActionCommand) {
     final Action action = createActionCommand.action();
     this.actionRepository.save(ActionMapper.map(action));
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/MigrationAggregate.java
new file mode 100644
index 0000000..436cf42
--- /dev/null
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/MigrationAggregate.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.deposit.service.internal.command.handler;
+
+import io.mifos.core.command.annotation.Aggregate;
+import io.mifos.core.command.annotation.CommandHandler;
+import io.mifos.core.command.annotation.EventEmitter;
+import io.mifos.core.lang.ApplicationName;
+import io.mifos.core.mariadb.domain.FlywayFactoryBean;
+import io.mifos.deposit.api.v1.EventConstants;
+import io.mifos.deposit.service.ServiceConstants;
+import io.mifos.deposit.service.internal.command.MigrationCommand;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.sql.DataSource;
+
+@Aggregate
+public class MigrationAggregate {
+
+  private final Logger logger;
+  private final DataSource dataSource;
+  private final FlywayFactoryBean flywayFactoryBean;
+  private final ApplicationName applicationName;
+
+  @Autowired
+  public MigrationAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+                            final DataSource dataSource,
+                            final FlywayFactoryBean flywayFactoryBean,
+                            final ApplicationName applicationName) {
+    super();
+    this.logger = logger;
+    this.dataSource = dataSource;
+    this.flywayFactoryBean = flywayFactoryBean;
+    this.applicationName = applicationName;
+  }
+
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.INITIALIZE)
+  @Transactional
+  public String process(final MigrationCommand migrationCommand) {
+    this.logger.info("Starting migration for deposit account management version: {}.", applicationName.getVersionString());
+    this.flywayFactoryBean.create(this.dataSource).migrate();
+
+    this.logger.info("Migration finished.");
+    return this.applicationName.getVersionString();
+  }
+}
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java
index f37211a..1173d7f 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java
@@ -19,6 +19,7 @@
 import io.mifos.core.command.annotation.Aggregate;
 import io.mifos.core.command.annotation.CommandHandler;
 import io.mifos.core.command.annotation.EventEmitter;
+import io.mifos.core.lang.DateConverter;
 import io.mifos.deposit.api.v1.EventConstants;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
@@ -29,12 +30,14 @@
 import io.mifos.deposit.service.internal.mapper.ProductDefinitionCommandMapper;
 import io.mifos.deposit.service.internal.mapper.ProductDefinitionMapper;
 import io.mifos.deposit.service.internal.repository.ActionRepository;
+import io.mifos.deposit.service.internal.repository.ProductDefinitionCommandEntity;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionCommandRepository;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionEntity;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionRepository;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.Clock;
 import java.time.LocalDateTime;
@@ -62,12 +65,14 @@
 
   @CommandHandler
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_DEFINITION)
+  @Transactional
   public String createProductDefinition(final CreateProductDefinitionCommand createProductDefinitionCommand) {
 
     final ProductDefinition productDefinition = createProductDefinitionCommand.productDefinition();
 
     final ProductDefinitionEntity productDefinitionEntity =
         ProductDefinitionMapper.map(productDefinition, this.actionRepository);
+    productDefinitionEntity.setActive(Boolean.FALSE);
 
     productDefinitionEntity.setCreatedBy(UserContextHolder.checkedGetUser());
     productDefinitionEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
@@ -79,19 +84,25 @@
 
   @CommandHandler
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_DEFINITION_COMMAND)
+  @Transactional
   public String activateProductdefintion(final ActivateProductDefinitionCommand activateProductDefinitionCommand) {
     final Optional<ProductDefinitionEntity> optionalProductDefinition = productDefinitionRepository.findByIdentifier(activateProductDefinitionCommand.identifier());
 
     if (optionalProductDefinition.isPresent()) {
       final ProductDefinitionCommand command = activateProductDefinitionCommand.command();
+      command.setCreatedBy(UserContextHolder.checkedGetUser());
+      command.setCreatedOn(DateConverter.toIsoString(LocalDateTime.now(Clock.systemUTC())));
 
       final ProductDefinitionEntity productDefinitionEntity = optionalProductDefinition.get();
       productDefinitionEntity.setActive(Boolean.TRUE);
       productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
       productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
-      this.productDefinitionRepository.save(productDefinitionEntity);
+      final ProductDefinitionEntity savedProductDefinitionEntity = this.productDefinitionRepository.save(productDefinitionEntity);
 
-      this.productDefinitionCommandRepository.save(ProductDefinitionCommandMapper.map(command));
+      final ProductDefinitionCommandEntity productDefinitionCommandEntity = ProductDefinitionCommandMapper.map(command);
+      productDefinitionCommandEntity.setProductDefinition(savedProductDefinitionEntity);
+
+      this.productDefinitionCommandRepository.save(productDefinitionCommandEntity);
       return activateProductDefinitionCommand.identifier();
     } else {
       this.logger.warn("Could not activate production definition {}, not found.", activateProductDefinitionCommand.identifier());
@@ -101,18 +112,25 @@
 
   @CommandHandler
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_DEFINITION_COMMAND)
+  @Transactional
   public String deactivateProductdefintion(final DeactivateProductDefinitionCommand activateProductDefinitionCommand) {
     final Optional<ProductDefinitionEntity> optionalProductDefinition = productDefinitionRepository.findByIdentifier(activateProductDefinitionCommand.identifier());
 
     if (optionalProductDefinition.isPresent()) {
       final ProductDefinitionCommand command = activateProductDefinitionCommand.command();
+      command.setCreatedBy(UserContextHolder.checkedGetUser());
+      command.setCreatedOn(DateConverter.toIsoString(LocalDateTime.now(Clock.systemUTC())));
 
-      final ProductDefinitionEntity productDefinitionEntity = optionalProductDefinition.get();productDefinitionEntity.setActive(Boolean.FALSE);
+      final ProductDefinitionEntity productDefinitionEntity = optionalProductDefinition.get();
+      productDefinitionEntity.setActive(Boolean.FALSE);
       productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
       productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
-      this.productDefinitionRepository.save(productDefinitionEntity);
+      final ProductDefinitionEntity savedProductDefinitionEntity = this.productDefinitionRepository.save(productDefinitionEntity);
 
-      this.productDefinitionCommandRepository.save(ProductDefinitionCommandMapper.map(command));
+      final ProductDefinitionCommandEntity productDefinitionCommandEntity = ProductDefinitionCommandMapper.map(command);
+      productDefinitionCommandEntity.setProductDefinition(savedProductDefinitionEntity);
+
+      this.productDefinitionCommandRepository.save(productDefinitionCommandEntity);
       return activateProductDefinitionCommand.identifier();
     } else {
       this.logger.warn("Could not activate production definition {}, not found.", activateProductDefinitionCommand.identifier());
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java
index 84badec..edcfbba 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java
@@ -15,6 +15,7 @@
  */
 package io.mifos.deposit.service.internal.command.handler;
 
+import io.mifos.core.api.util.UserContextHolder;
 import io.mifos.core.command.annotation.Aggregate;
 import io.mifos.core.command.annotation.CommandHandler;
 import io.mifos.core.command.annotation.EventEmitter;
@@ -29,6 +30,10 @@
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.Clock;
+import java.time.LocalDateTime;
 
 @Aggregate
 public class ProductInstanceAggregate {
@@ -48,12 +53,17 @@
 
   @CommandHandler
   @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_INSTANCE)
+  @Transactional
   public String createProductInstance(final CreateProductInstanceCommand createProductInstanceCommand) {
     final ProductInstance productInstance = createProductInstanceCommand.productInstance();
 
     final ProductInstanceEntity productInstanceEntity =
         ProductInstanceMapper.map(productInstance, this.productDefinitionRepository);
 
+    productInstanceEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+    productInstanceEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+    productInstanceEntity.setState("PENDING");
+
     this.productInstanceRepository.save(productInstanceEntity);
     return productInstance.getCustomerIdentifier();
   }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ChargesMapper.java b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ChargeMapper.java
similarity index 87%
rename from service/src/main/java/io/mifos/deposit/service/internal/mapper/ChargesMapper.java
rename to service/src/main/java/io/mifos/deposit/service/internal/mapper/ChargeMapper.java
index 3bde640..7aa29cb 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ChargesMapper.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ChargeMapper.java
@@ -23,9 +23,9 @@
 
 import java.util.Optional;
 
-public class ChargesMapper {
+public class ChargeMapper {
 
-  private ChargesMapper() {
+  private ChargeMapper() {
     super();
   }
 
@@ -33,7 +33,6 @@
     final Optional<ActionEntity> optionalActionEntity = actionRepository.findByIdentifier(charge.getActionIdentifier());
     if (optionalActionEntity.isPresent()) {
       final ChargeEntity chargeEntity = new ChargeEntity();
-      chargeEntity.setIdentifier(charge.getIdentifier());
       chargeEntity.setAction(optionalActionEntity.get());
       chargeEntity.setIncomeAccountIdentifier(charge.getIncomeAccountIdentifier());
       chargeEntity.setName(charge.getName());
@@ -43,14 +42,13 @@
 
       return chargeEntity;
     } else {
-      throw ServiceException.notFound("Can not create charge {0}, action {1} not found.",
-          charge.getIdentifier(), charge.getActionIdentifier());
+      throw ServiceException.notFound("Can not create charge, action {1} not found.",
+          charge.getActionIdentifier());
     }
   }
 
   public static Charge map(final ChargeEntity chargeEntity) {
     final Charge charge = new Charge();
-    charge.setIdentifier(chargeEntity.getIdentifier());
     charge.setActionIdentifier(chargeEntity.getAction().getIdentifier());
     charge.setIncomeAccountIdentifier(chargeEntity.getIncomeAccountIdentifier());
     charge.setName(chargeEntity.getName());
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionCommandMapper.java b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionCommandMapper.java
index 288ea70..4377c09 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionCommandMapper.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionCommandMapper.java
@@ -15,6 +15,7 @@
  */
 package io.mifos.deposit.service.internal.mapper;
 
+import io.mifos.core.lang.DateConverter;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionCommandEntity;
 
@@ -28,8 +29,10 @@
     final ProductDefinitionCommandEntity entity = new ProductDefinitionCommandEntity();
     entity.setAction(command.getAction());
     entity.setNote(command.getNote());
-    entity.setCreatedBy(command.getCreatedBy());
-    entity.setCreatedOn(command.getCreatedOn());
+    if (command.getCreatedBy() != null) {
+      entity.setCreatedBy(command.getCreatedBy());
+      entity.setCreatedOn(DateConverter.fromIsoString(command.getCreatedOn()));
+    }
 
     return entity;
   }
@@ -39,7 +42,7 @@
     command.setAction(entity.getAction());
     command.setNote(entity.getNote());
     command.setCreatedBy(entity.getCreatedBy());
-    command.setCreatedOn(entity.getCreatedOn());
+    command.setCreatedOn(DateConverter.toIsoString(entity.getCreatedOn()));
 
     return command;
   }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionMapper.java b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionMapper.java
index a559dd2..8c149ef 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionMapper.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionMapper.java
@@ -41,7 +41,7 @@
     productDefinitionEntity.setTerm(TermMapper.map(productDefinition.getTerm()));
     productDefinitionEntity.setCharges(productDefinition.getCharges()
         .stream()
-        .map(charge -> ChargesMapper.map(charge, actionRepository))
+        .map(charge -> ChargeMapper.map(charge, actionRepository))
         .collect(Collectors.toList())
     );
     productDefinitionEntity.setFlexible(productDefinition.getFlexible());
@@ -63,10 +63,11 @@
     productDefinition.setTerm(TermMapper.map(productDefinitionEntity.getTerm()));
     productDefinition.setCharges(productDefinitionEntity.getCharges()
         .stream()
-        .map(ChargesMapper::map)
+        .map(ChargeMapper::map)
         .collect(Collectors.toList())
     );
     productDefinition.setFlexible(productDefinitionEntity.getFlexible());
+    productDefinition.setActive(productDefinitionEntity.getActive());
 
     return productDefinition;
   }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/repository/ActionEntity.java b/service/src/main/java/io/mifos/deposit/service/internal/repository/ActionEntity.java
index 3df6279..a31bd81 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/repository/ActionEntity.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/repository/ActionEntity.java
@@ -32,7 +32,7 @@
   private Long id;
   @Column(name = "identifier", nullable = false, unique = true, length = 32)
   private String identifier;
-  @Column(name = "name", nullable = false)
+  @Column(name = "a_name", nullable = false)
   private String name;
   @Column(name = "description", nullable = true)
   private String description;
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/repository/ChargeEntity.java b/service/src/main/java/io/mifos/deposit/service/internal/repository/ChargeEntity.java
index c8071e2..eb5d304 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/repository/ChargeEntity.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/repository/ChargeEntity.java
@@ -33,8 +33,6 @@
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id", nullable = false, unique = true)
   private Long id;
-  @Column(name = "identifier", nullable = false, unique = true, length = 32)
-  private String identifier;
   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumn(name = "action_id", nullable = false)
   private ActionEntity action;
@@ -43,7 +41,7 @@
   @ManyToOne
   @JoinColumn(name = "product_definition_id", nullable = false)
   private ProductDefinitionEntity productDefinition;
-  @Column(name = "name", nullable = false)
+  @Column(name = "a_name", nullable = false)
   private String name;
   @Column(name = "description", nullable = true)
   private String description;
@@ -64,14 +62,6 @@
     this.id = id;
   }
 
-  public String getIdentifier() {
-    return this.identifier;
-  }
-
-  public void setIdentifier(final String identifier) {
-    this.identifier = identifier;
-  }
-
   public ActionEntity getAction() {
     return this.action;
   }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandEntity.java b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandEntity.java
index a3c9dc2..6eae234 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandEntity.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandEntity.java
@@ -15,8 +15,11 @@
  */
 package io.mifos.deposit.service.internal.repository;
 
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
+import javax.persistence.Convert;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
@@ -44,6 +47,7 @@
   private String note;
   @Column(name = "created_by", nullable = false, length = 32)
   private String createdBy;
+  @Convert(converter = LocalDateTimeConverter.class)
   @Column(name = "created_on", nullable = false)
   private LocalDateTime createdOn;
 
diff --git a/service/src/main/java/io/mifos/deposit/service/rest/ActionRestController.java b/service/src/main/java/io/mifos/deposit/service/rest/ActionRestController.java
index c1af8cf..93649aa 100644
--- a/service/src/main/java/io/mifos/deposit/service/rest/ActionRestController.java
+++ b/service/src/main/java/io/mifos/deposit/service/rest/ActionRestController.java
@@ -56,7 +56,7 @@
   }
 
   @RequestMapping(
-      value = "/actions",
+      value = "",
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE
@@ -72,7 +72,7 @@
   }
 
   @RequestMapping(
-      value = "/actions",
+      value = "",
       method = RequestMethod.GET,
       consumes = MediaType.ALL_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE
diff --git a/service/src/main/java/io/mifos/deposit/service/rest/DepositAccountManagementRestController.java b/service/src/main/java/io/mifos/deposit/service/rest/DepositAccountManagementRestController.java
index 3fd5b99..5de075b 100644
--- a/service/src/main/java/io/mifos/deposit/service/rest/DepositAccountManagementRestController.java
+++ b/service/src/main/java/io/mifos/deposit/service/rest/DepositAccountManagementRestController.java
@@ -19,6 +19,7 @@
 import io.mifos.anubis.annotation.Permittable;
 import io.mifos.core.command.gateway.CommandGateway;
 import io.mifos.deposit.service.ServiceConstants;
+import io.mifos.deposit.service.internal.command.MigrationCommand;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -54,6 +55,7 @@
   public
   @ResponseBody
   ResponseEntity<Void> initialize() {
+    this.commandGateway.process(new MigrationCommand());
     return ResponseEntity.accepted().build();
   }
 }
diff --git a/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java b/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java
index 3a9583f..3a828d8 100644
--- a/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java
+++ b/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java
@@ -68,7 +68,7 @@
 
   @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION_MANAGEMENT)
   @RequestMapping(
-      value = "/",
+      value = "",
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE
@@ -81,7 +81,7 @@
 
   @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION_MANAGEMENT)
   @RequestMapping(
-      value = "/",
+      value = "",
       method = RequestMethod.GET,
       consumes = MediaType.ALL_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE
@@ -107,7 +107,7 @@
   }
 
   @RequestMapping(
-      value = "/definitions/{identifier}/instances",
+      value = "/{identifier}/instances",
       method = RequestMethod.GET,
       consumes = MediaType.ALL_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE
diff --git a/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java b/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java
index 157890c..7006b39 100644
--- a/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java
+++ b/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java
@@ -21,6 +21,7 @@
 import io.mifos.deposit.api.v1.PermittableGroupIds;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
 import io.mifos.deposit.service.ServiceConstants;
+import io.mifos.deposit.service.internal.command.CreateProductInstanceCommand;
 import io.mifos.deposit.service.internal.service.ProductInstanceService;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -57,19 +58,20 @@
 
   @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
   @RequestMapping(
-      value = "/",
+      value = "",
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE
   )
   @ResponseBody
   public ResponseEntity<Void> create(@RequestBody @Valid final ProductInstance productInstance) {
+    this.commandGateway.process(new CreateProductInstanceCommand(productInstance));
     return ResponseEntity.accepted().build();
   }
 
   @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
   @RequestMapping(
-      value = "/",
+      value = "",
       method = RequestMethod.GET,
       consumes = MediaType.ALL_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index 08f075e..9c46c88 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -28,7 +28,7 @@
 
 server:
   port: 8081
-  contextPath: /deposit/v1/*
+  contextPath: /deposit/v1
 
 cassandra:
   clusterName: staging_cluster
diff --git a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
index 9a2e18c..c7ac510 100644
--- a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
+++ b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
@@ -61,7 +61,8 @@
   a_name           VARCHAR(256)  NOT NULL,
   description      VARCHAR(2048) NULL,
   transaction_type VARCHAR(32)   NOT NULL,
-  CONSTRAINT shed_actions PRIMARY KEY (id)
+  CONSTRAINT shed_actions PRIMARY KEY (id),
+  CONSTRAINT shed_actions_identifier_uq UNIQUE (identifier)
 );
 
 INSERT INTO shed_actions
@@ -91,10 +92,9 @@
 
 CREATE TABLE shed_charges (
   id                        BIGINT        NOT NULL AUTO_INCREMENT,
-  identifier                VARCHAR(32)   NOT NULL,
   action_id                 BIGINT        NOT NULL,
   product_definition_id     BIGINT        NOT NULL,
-  income_account_identifier BIGINT        NOT NULL,
+  income_account_identifier VARCHAR(32)   NOT NULL,
   a_name                    VARCHAR(256)  NOT NULL,
   description               VARCHAR(2048) NULL,
   proportional              BOOLEAN   NOT NULL,
@@ -107,7 +107,7 @@
 CREATE TABLE shed_commands (
   id                    BIGINT        NOT NULL AUTO_INCREMENT,
   product_definition_id BIGINT        NOT NULL,
-  action                VARCHAR(256)  NOT NULL,
+  a_action              VARCHAR(256)  NOT NULL,
   note                  VARCHAR(2048) NOT NULL,
   created_on            TIMESTAMP(3)  NOT NULL,
   created_by            VARCHAR(32)   NOT NULL,
@@ -118,7 +118,7 @@
 CREATE TABLE shed_product_instances (
   id                    BIGINT       NOT NULL AUTO_INCREMENT,
   customer_identifier   VARCHAR(32)  NOT NULL,
-  product_definition_id VARCHAR(32)  NOT NULL,
+  product_definition_id BIGINT       NOT NULL,
   account_identifier    VARCHAR(32)  NOT NULL,
   a_state               VARCHAR(32)  NOT NULL,
   created_on            TIMESTAMP(3) NOT NULL,
@@ -126,5 +126,6 @@
   last_modified_on      TIMESTAMP(3) NULL,
   last_modified_by      VARCHAR(32)  NULL,
   CONSTRAINT shed_product_instances_pk PRIMARY KEY (id),
+  CONSTRAINT shed_prod_inst_identifier_uq UNIQUE (account_identifier),
   CONSTRAINT shed_prod_inst_prod_def_fk FOREIGN KEY (product_definition_id) REFERENCES shed_product_definitions (id)
 );
diff --git a/service/src/main/resources/logback.xml b/service/src/main/resources/logback.xml
new file mode 100644
index 0000000..8c8621b
--- /dev/null
+++ b/service/src/main/resources/logback.xml
@@ -0,0 +1,55 @@
+<!--
+
+    Copyright 2017 The Mifos Initiative.
+
+    Licensed 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.
+
+-->
+<configuration>
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>logs/accounting.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>logs/archive/accounting.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <maxHistory>7</maxHistory>
+            <totalSizeCap>2GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="com" level="WARN">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="org" level="WARN">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="io" level="WARN">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="net" level="WARN">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <root level="INFO">
+        <appender-ref ref="FILE"/>
+    </root>
+</configuration>
\ No newline at end of file