chore(docs): füge ADRs 0025–0027 und Wizard-DSL-Referenz hinzu, aktualisiere Roadmap und ADR-Index
Signed-off-by: StefanMoCoAt <stefan.mo.co@gmail.com>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
---
|
||||
type: Reference
|
||||
status: ACTIVE
|
||||
owner: Lead Architect
|
||||
date: 2026-04-21
|
||||
---
|
||||
|
||||
# Wizard‑DSL & Orchestrator – Referenz
|
||||
|
||||
## Ziel
|
||||
Deklarative Beschreibung von Wizard‑Flows als Graph (Steps, Guards, Transitions) mit klaren Side‑Effects und Offline‑Draft‑Unterstützung.
|
||||
|
||||
## Kern‑Interfaces (Skizze)
|
||||
```kotlin
|
||||
interface StepId
|
||||
|
||||
data class WizardContext(
|
||||
val origin: AppScreen,
|
||||
val role: String?,
|
||||
val isOnline: Boolean,
|
||||
val stats: MasterdataStats?
|
||||
)
|
||||
|
||||
data class WizardState<S: StepId, A>(
|
||||
val current: S,
|
||||
val history: List<S> = emptyList(),
|
||||
val acc: A,
|
||||
val errors: List<String> = emptyList()
|
||||
)
|
||||
|
||||
typealias Guard<S, A> = (WizardContext, A) -> Boolean
|
||||
|
||||
data class Transition<S: StepId>(val target: S, val guard: Guard<S, *>? = null, val id: String)
|
||||
|
||||
interface StepEffects<S: StepId, A> {
|
||||
suspend fun onEnter(ctx: WizardContext, state: WizardState<S, A>) {}
|
||||
suspend fun onLeave(ctx: WizardContext, state: WizardState<S, A>) {}
|
||||
suspend fun onComplete(ctx: WizardContext, state: WizardState<S, A>) {}
|
||||
}
|
||||
```
|
||||
|
||||
## DSL (Skizze)
|
||||
```kotlin
|
||||
class FlowBuilder<S: StepId, A> {
|
||||
fun step(id: S, block: StepBuilder<S, A>.() -> Unit) { /* … */ }
|
||||
}
|
||||
class StepBuilder<S: StepId, A> {
|
||||
fun onEnter(block: suspend (WizardContext, WizardState<S, A>) -> Unit) { /* … */ }
|
||||
fun whenGuard(id: String, g: Guard<S, A>, go: S) { /* … */ }
|
||||
fun otherwise(go: S) { /* … */ }
|
||||
}
|
||||
fun <S: StepId, A> flow(start: S, build: FlowBuilder<S, A>.() -> Unit): WizardRuntime<S, A> { /* … */ }
|
||||
```
|
||||
|
||||
## Beispiel – Event‑Flow (Auszug)
|
||||
```kotlin
|
||||
sealed interface EventStep: StepId {
|
||||
data object ZnsCheck: EventStep
|
||||
data object VeranstalterSelection: EventStep
|
||||
data object AnsprechpersonMapping: EventStep
|
||||
data object MetaData: EventStep
|
||||
data object TurnierAnlage: EventStep
|
||||
data object Summary: EventStep
|
||||
}
|
||||
|
||||
data class EventAcc(
|
||||
val veranstalterId: Uuid? = null,
|
||||
val veranstalterNr: String = "",
|
||||
val veranstalterName: String = "",
|
||||
val ansprechpersonSatznr: String = "",
|
||||
val name: String = "",
|
||||
val ort: String = "",
|
||||
val start: LocalDate? = null,
|
||||
val end: LocalDate? = null,
|
||||
val turniere: List<TurnierEntry> = emptyList()
|
||||
)
|
||||
|
||||
object EventGuards {
|
||||
val hasZns: Guard<EventStep, EventAcc> = { ctx, _ -> (ctx.stats?.vereinCount ?: 0) > 0 }
|
||||
val needsContactPerson: Guard<EventStep, EventAcc> = { _, acc -> acc.veranstalterId == null || acc.veranstalterNr.startsWith("ORG-") }
|
||||
}
|
||||
|
||||
val EventFlow = flow<EventStep, EventAcc>(start = EventStep.ZnsCheck) {
|
||||
step(EventStep.ZnsCheck) {
|
||||
onEnter { ctx, _ -> /* prefetch stats */ }
|
||||
whenGuard("hasZns", EventGuards.hasZns, go = EventStep.VeranstalterSelection)
|
||||
otherwise(go = EventStep.VeranstalterSelection)
|
||||
}
|
||||
step(EventStep.VeranstalterSelection) {
|
||||
whenGuard("needsContact", EventGuards.needsContactPerson, go = EventStep.AnsprechpersonMapping)
|
||||
otherwise(go = EventStep.MetaData)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## DevTools
|
||||
- Strukturierte Logs je Transition (from, to, guard-id, result, duration).
|
||||
- Graph‑Export (DOT/PlantUML) aus der DSL für Doku & Reviews.
|
||||
|
||||
## Tests (Empfehlungen)
|
||||
- Unit: Guards (100% Branch‑Abdeckung), Runtime‑History.
|
||||
- Property: Resume‑Determinismus (Draft → korrekter Step).
|
||||
- Snapshot: Compose‑Panels mit Beispielkontexten.
|
||||
|
||||
## Verweise
|
||||
- ADR‑0025 Orchestrator · ADR‑0026 Validation‑Policy · ADR‑0027 Draft‑Domain & Delta‑Sync
|
||||
- Roadmap: `docs/01_Architecture/MASTER_ROADMAP.md#3-initiative-wizard-orchestrator--offline-drafts-q2q3-2026`
|
||||
Reference in New Issue
Block a user