Adding meta timestamps

In this example we can easily create both updatedAt and createdAt attributes on our model. createdAt will use ElectroDB’s set and readOnly attribute properties, while updatedAt will make use of readOnly, and watch with the “watchAll” syntax: {watch: "*"}. By supplying an asterisk, instead of an array of attribute names, attributes can be defined to watch all changes to all attributes.

Using watch in conjunction with readOnly is another powerful modeling technique. This combination allows you to model attributes that can only be modified via the model and not via the user. This is useful for attributes that need to be locked down and/or strictly calculated.

Notice that both updatedAt and createdAt use the set property without using its arguments. The readOnly prevents modification of an attributes on update, patch, and upsert. By discarding the arguments passed to set, the createdAt attribute becomes effectively locked down from user influence/manipulation.

Additionally, updatedAt and createdAt are required and have default options. The required option ensures that new items cannot be created without these properties, and that these properties cannot be deleted. Lastly, default option then has the typing implication that it becomes an optional property to provide on create, patch and upsert operations.

{
  model: {
    entity: "transaction",
    service: "bank",
    version: "1"
  },
  attributes: {
    accountNumber: {
      type: "string"
    },
    transactionId: {
      type: "string"
    },
    description: {
      type: "string",
    },
    createdAt: {
      type: "number",
      readOnly: true,
      required: true,
      default: () => Date.now(),
      set: () => Date.now(),
    },
    updatedAt: {
      type: "number",
      watch: "*",
      required: true,
      default: () => Date.now(),
      set: () => Date.now(),
    }
  },
  indexes: {
    transactions: {
      pk: {
        field: "pk",
        composite: ["accountNumber"]
      },
      sk: {
        field: "sk",
        composite: ["transactionId"]
      }
    }
  }
}