packages feed

keiro-dsl-0.17.0.0: test/fixtures/structural-nominal-leaves.keiro

language keiro-dsl 6
context structural-nominal-leaves

id TemplateId prefix=template

id ClaimId prefix=claim using {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=ClaimId
  binding = "Conformance.StructuralNominals.Bindings.claimIdBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.ClaimId.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.claimIdFixtures"
}

enum TemplateKind { Draft=draft Published=published }

enum Channel { Email=email Sms=sms } using {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=Channel
  binding = "Conformance.StructuralNominals.Bindings.channelBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.Channel.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.channelFixtures"
}

mapped nominal AccountNumber : Text {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=AccountNumber
  binding = "Conformance.StructuralNominals.Bindings.accountNumberBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.AccountNumber.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.accountNumberFixtures"
}

mapped structural record TemplateState {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=TemplateState
  binding = "Conformance.StructuralNominals.Bindings.templateStateBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.TemplateState.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.templateStateFixtures"
  wire object constructor=TemplateState unknown-fields=reject {
    templateId as "templateId" : TemplateId required
    holder as "holder" : Optional ClaimId optional on-missing=null
    account as "account" : AccountNumber required
    channel as "channel" : Channel required
    kind as "kind" : TemplateKind optional on-missing=Draft
    fallbackChannel as "fallbackChannel" : Channel optional on-missing=Email
  }
}

mapped structural union TemplateRef {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=TemplateRef
  binding = "Conformance.StructuralNominals.Bindings.templateRefBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.TemplateRef.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.templateRefFixtures"
  wire tagged-object tag="tag" contents="contents" unknown-fields=reject {
    ById as "by_id" : TemplateId
    ByAccount as "by_account" : AccountNumber
    ByChannel as "by_channel" : Channel
    Unknown as "unknown"
  }
}

mapped structural record TemplateBook {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=TemplateBook
  binding = "Conformance.StructuralNominals.Bindings.templateBookBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.TemplateBook.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.templateBookFixtures"
  initial = "Conformance.StructuralNominals.Bindings.initialTemplateBook"
  wire object constructor=TemplateBook unknown-fields=reject {
    templates as "templates" : List TemplateState required
    holders as "holders" : List (Optional ClaimId) required
    byKey as "byKey" : Map TemplateId required
    byTemplate as "by_template" : Map[TemplateId] Text required
    claims as "claims" : Map[ClaimId] TemplateState optional on-missing={}
  }
}

mapped structural record TemplateLookupInput {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=TemplateLookupInput
  binding = "Conformance.StructuralNominals.Bindings.templateLookupInputBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.TemplateLookupInput.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.templateLookupInputFixtures"
  wire object constructor=TemplateLookupInput unknown-fields=reject {
    claimId as "claimId" : ClaimId required
  }
}

mapped structural record TemplateLookupRow {
  haskell package=keiro-dsl module=Conformance.StructuralNominals.Domain type=TemplateLookupRow
  binding = "Conformance.StructuralNominals.Bindings.templateLookupRowBinding"
  binding-version = "1"
  canonical-type = "conformance.structural-nominals.TemplateLookupRow.v1"
  fixtures = "Conformance.StructuralNominals.Bindings.templateLookupRowFixtures"
  wire object constructor=TemplateLookupRow unknown-fields=reject {
    templateId as "templateId" : TemplateId required
    claimId as "claimId" : ClaimId required
  }
}

aggregate TemplateCatalog
  regs
    book TemplateBook = initial
    activeTemplateId TemplateId = placeholder
  states Empty Recorded Routed!

  command RecordTemplate { state:TemplateState reference:TemplateRef book:TemplateBook }
  command RouteTemplate { templateId:TemplateId claimId:ClaimId }
  event TemplateRecorded = fields(RecordTemplate)
  event TemplateRouted = fields(RouteTemplate)

  Empty -- RecordTemplate -->
    guard cmd.state.templateId == reg.activeTemplateId
    write book := cmd.book
    emit TemplateRecorded
    goto Recorded

  Recorded -- RouteTemplate -->
    emit TemplateRouted
    goto Routed

  wire kind=ctorName fields=camelCase schemaVersion=1
  snapshot every 1
    state-codec version=1 shape-hash="structural-nominal-leaves-v1"

workqueue template_work {
  queue logical = "template.work"
  derive physical = "template_work"
         dlq = "template_work_dlq"
         table = "pgmq.q_template_work"
  payload TemplateWork {
    templateId -> "template_id" : TemplateId
    holder -> "holder" : Optional ClaimId
  }
  retry maxRetries = 3 delay = 1s dlq = on
  disposition {
    storeFailure -> retry 1s
    commandRejected -> deadLetter
    decodeFailure -> deadLetter
    onCodecReject -> deadLetter
  }
}

target template_table {
  schema = "public"
  table = "templates"
  reset = clear
}

rebuild-group template_rebuild {
  targets = [ template_table ]
  order = [ template_table ]
}

projection-owner template_writer {
  source = all
  delivery = subscription
  group = template_rebuild
  targets = [ template_table ]
  order = 10
  subscription = "template-writer"
  dedup = "template-writer-v1"
  checkpoint-on-missing = from-beginning
  replay = explicit
}

readmodel template_lookup {
  columns {}
  query input = TemplateLookupInput
  query result = List TemplateLookupRow
  version = 1
  shape = "fnv1a:3c07a19c552c3547"
  freshness = wait-for-head entire-log
  group = template_rebuild
  targets = [ template_table ]
}

router TemplateDeliveryRouter
  name "template-delivery-router"
  input TemplateDeliveryRequested : TemplateLookupInput
  key input.claimId
  resolve declarative {
    identity = "template-nominal-selection"
    version = 1
    query = read-model template_lookup with input
    where = row.claimId == input.claimId && row.templateId == TemplateId("template_01h455vb4pex5vsknk084sn02q")
    recipient = row.templateId
    order = target-stream
    dedupe = target-stream
    max-recipients = 16
    empty => ack
    failure => retry
    redelivery = stable-union
    partial = retain-successes
  }
  target TemplateCatalog
  projections []
  dispatch-each RouteTemplate {
    templateId=row.templateId
    claimId=row.claimId
  }
    on-appended AckOk ; on-duplicate AckOk ; on-failed Retry
  dispatch-id strategy=uuidv5 from=(name, key, sourceEventId, targetStreamName, occurrence)
  rejected => deadLetter
  poison => halt