effect-app / libs

The core libraries to build apps with Effect
44 stars 6 forks source link

Streamline the updating of `updatedAt` #99

Open patroza opened 6 days ago

patroza commented 6 days ago

related to https://github.com/effect-app/libs/issues/91 a way to express: "when making changes to this instance, update the updatedAt field with the current date". Perhaps its just a helper: something.pipe(withUpdatedAt({ title: "new title" })) which is just a variation of copy that includes auto updating updatedAt. Another option would be to have something.pipe(Something.copy({ title: "new title" })) or something.copy({ title: "new title" }) where both will take care of the updatedAt.

I guess with metadata on the schema, copy could look for it or a symbol, and make changes accordingly.

Classically, databases do these things internally, but for document databases this is not the norm, besides I really like our code-first approach, where the master is the code, not the database. Still, we could perhaps apply metadata so that the Repository can take care of it when saving. We have to investigate if that means we should change the save signature to return the updated instance, though as we keep commands and queries separate, this might not be important. Similar to https://github.com/tim-smart/effect-http-play/blob/ad1c4cec0f28e17dc73f0b491a415b40ddb6a203/src/Domain/User.ts#L21

Related would be this pattern in Configurator, which at least syncs the initial updatedAt to createdAt:

export class Timestamps extends S.ExtendedClass<Timestamps, Timestamps.From>()({
  createdAt: S.Date,
  updatedAt: S.Date
}) {}

export function makeTimestamps() {
  const createdAt = new Date()
  return new Timestamps({
    createdAt,
    updatedAt: createdAt
  })
}

export const TimestampsProp = Timestamps.pipe(S.withDefaultConstructor(() => makeTimestamps()))

export const TimestampProps = {
  timestamps: TimestampsProp
}

export interface HasTimestamps {
  timestamps: Timestamps
}
patroza commented 6 days ago

added a basic poc in #100