1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
//! ERP command names shared between `makod`'s command registry and its clients.
//!
//! `makod` exposes `POST /api/v1/commands` whose `command` field must match an
//! entry in its command registry — an unknown name is rejected with HTTP 422.
//! Services that dispatch commands (`processd`, `invoicd`, …) MUST use these
//! constants instead of string literals so the wire name cannot drift from the
//! registry: `makod` carries a registry test asserting every constant in
//! [`DISPATCHED_BY_SERVICES`] is registered.
//!
//! Only names actually posted by out-of-process callers are listed here; the
//! registry itself remains the single source of truth for roles, PIDs, and
//! dispatch functions.
// ── GPKE (electricity supplier processes) ─────────────────────────────────────
/// LF: initiate a Lieferbeginn Anmeldung (UTILMD 55001).
pub const GPKE_LIEFERBEGINN_ANMELDEN: &str = "gpke.lieferbeginn.anmelden";
/// NB: confirm an inbound Lieferbeginn Anmeldung (UTILMD 55002 / 55078).
pub const GPKE_LIEFERBEGINN_BESTAETIGEN: &str = "gpke.lieferbeginn.bestaetigen";
/// NB: confirm a Neuanlage — inbound 55600 / 55601, answered UTILMD 55602 /
/// 55603 (EBD `E_0608`, Zustimmung `A09` / `A18`).
pub const GPKE_NEUANLAGE_BESTAETIGEN: &str = "gpke.neuanlage.bestaetigen";
/// NB: refuse a Neuanlage — inbound 55600 / 55601, answered UTILMD 55604 /
/// 55605 (EBD `E_0608`).
pub const GPKE_NEUANLAGE_ABLEHNEN: &str = "gpke.neuanlage.ablehnen";
/// NB: assign a contractless `MaLo` to the Grundversorger (UTILMD 55013, §38 `EnWG`).
pub const GPKE_EOG_ANMELDEN: &str = "gpke.eog.anmelden";
/// The E/G supplier confirms an assignment under § 36 / § 38 `EnWG` — 55014,
/// `E_0615`. The Gas twin is [`GELI_EOG_BESTAETIGEN`].
pub const GPKE_EOG_BESTAETIGEN: &str = "gpke.eog.bestaetigen";
/// Refuse one — 55015, `E_0615` `A02` / `A03` / `A04` / `A05` / `A99`.
pub const GPKE_EOG_ABLEHNEN: &str = "gpke.eog.ablehnen";
/// NB: reject an inbound Lieferbeginn Anmeldung (UTILMD 55003 / 55080).
pub const GPKE_LIEFERBEGINN_ABLEHNEN: &str = "gpke.lieferbeginn.ablehnen";
/// LF: initiate a Lieferende Abmeldung (UTILMD 55004).
pub const GPKE_LIEFERENDE_ANMELDEN: &str = "gpke.lieferende.anmelden";
/// LFN: send the Kündigung to the Altlieferant — UTILMD 55016, answered
/// 55017 / 55018 (`E_0614`). The Gas twin is [`GELI_KUENDIGUNG_ANMELDEN`].
pub const GPKE_KUENDIGUNG_ANMELDEN: &str = "gpke.kuendigung.anmelden";
/// NB: confirm an inbound Abmeldung (inbound 55004 → UTILMD 55005, EBD `E_0607`).
pub const GPKE_LIEFERENDE_BESTAETIGEN: &str = "gpke.lieferende.bestaetigen";
/// NB: reject an inbound Abmeldung (inbound 55004 → UTILMD 55006, EBD `E_0607`).
pub const GPKE_LIEFERENDE_ABLEHNEN: &str = "gpke.lieferende.ablehnen";
/// LF: confirm an NB-initiated Lieferende — inbound 55007, answered
/// UTILMD 55008 (EBD `E_0609`).
pub const GPKE_NB_LIEFERENDE_BESTAETIGEN: &str = "gpke.nb-lieferende.bestaetigen";
/// LF: reject an NB-initiated Lieferende — inbound 55007, answered
/// UTILMD 55009 (EBD `E_0609`).
pub const GPKE_NB_LIEFERENDE_ABLEHNEN: &str = "gpke.nb-lieferende.ablehnen";
/// LFA: confirm an NB `Anfrage zur Beendigung der Zuordnung` (UTILMD 55011).
///
/// The inbound PID is 55010 and the EBD is **`E_0624`** ("Anfrage zur Beendigung
/// der Zuordnung prüfen") — distinct from the NB-seitiges Lieferende above
/// (55007 → 55008/55009, EBD `E_0609`).
pub const GPKE_BEENDIGUNG_ZUORDNUNG_BESTAETIGEN: &str = "gpke.beendigung-zuordnung.bestaetigen";
/// LFA: reject an NB `Anfrage zur Beendigung der Zuordnung` (UTILMD 55012).
pub const GPKE_BEENDIGUNG_ZUORDNUNG_ABLEHNEN: &str = "gpke.beendigung-zuordnung.ablehnen";
/// NB → LFA: UTILMD 55010 `Anfrage zur Beendigung der Zuordnung`.
///
/// GPKE Teil 2 § 2.1.2 SD Lieferbeginn Nr. 3, „parallel zu Nr. 2": whenever an
/// Anmeldung lands on a Marktlokation that is already assigned at the
/// Zuordnungsbeginn, the NB must ask the incumbent LFA to release it before it
/// may confirm. The LFA answers by **09:00 Uhr des 1. WT**, and silence counts
/// as Zustimmung — so the window closing is a result, not a timeout.
///
/// `E_0623` Prüfschritte 20–50 read that answer, which is why an NB that never
/// sends this cannot reach `A50` „Der LFA hat der Anfrage zur Beendigung der
/// Zuordnung widersprochen" at all.
pub const GPKE_BEENDIGUNG_ZUORDNUNG_ANFRAGEN: &str = "gpke.beendigung-zuordnung.anfragen";
/// NB → LFN: UTILMD 55036 „Information über existierende Zuordnung".
///
/// One of the three **Meldepflichten** around the Lieferbeginn — messages the
/// Festlegung obliges the NB to send with no answer expected back. GPKE Teil 2
/// § 2.1.2 SD Lieferbeginn Nr. 2: owed whenever the Marktlokation is already
/// assigned at the Zuordnungsbeginn, „auch dann …, sofern LFA und LFN identisch
/// sind", and it is what tells the LFN **die Identität des LFA**.
pub const GPKE_ZUORDNUNG_INFORMIEREN: &str = "gpke.zuordnung.informieren";
/// NB → LFA: UTILMD 55037 „Beendigung der Zuordnung" (SD Lieferbeginn Nr. 10).
pub const GPKE_ZUORDNUNG_BEENDEN: &str = "gpke.zuordnung.beenden";
/// NB → LFZ: UTILMD 55038 „Aufhebung einer zukünftigen Zuordnung"
/// (SD Lieferbeginn Nr. 13).
pub const GPKE_ZUORDNUNG_AUFHEBEN: &str = "gpke.zuordnung.aufheben";
/// NB → `MSB` / `MSBZ`: UTILMD 55611 „Beendigung der Zuordnung des `MSB` zur
/// `MaLo` / `MeLo`".
///
/// A Meldepflicht of the SD **Lieferende von NB an LF** (§ 2.5.2 Nr. 11 and
/// Nr. 13), not of the Lieferbeginn: the NB opens that process itself with a
/// 55007, and this tells the `MSB` — or, on `ZH1`, the `MSBZ` — that its own
/// Zuordnung ends. It is the one message in the family that may address a
/// **Messlokation**, because the `MSB` is assigned to the `MeLo` and not to the
/// `MaLo`.
pub const GPKE_MSB_ZUORDNUNG_BEENDEN: &str = "gpke.msb-zuordnung.beenden";
// ── GeLi Gas ──────────────────────────────────────────────────────────────────
/// LF: initiate a gas Lieferbeginn Anmeldung (UTILMD 44001).
pub const GELI_LIEFERBEGINN_ANMELDEN: &str = "geli.lieferbeginn.anmelden";
/// NB: confirm an inbound gas Lieferbeginn Anmeldung.
pub const GELI_LIEFERBEGINN_BESTAETIGEN: &str = "geli.lieferbeginn.bestaetigen";
/// NB: reject an inbound gas Lieferbeginn Anmeldung.
pub const GELI_LIEFERBEGINN_ABLEHNEN: &str = "geli.lieferbeginn.ablehnen";
/// LF: initiate a gas Lieferende Abmeldung (UTILMD 44004).
pub const GELI_LIEFERENDE_ANMELDEN: &str = "geli.lieferende.anmelden";
/// LFG: send the Kündigung to the Altlieferant — UTILMD G 44016, answered
/// 44017 / 44018 (`E_3001`). BK7-24-01-009 § 3.1; the Strom twin is
/// [`GPKE_KUENDIGUNG_ANMELDEN`].
pub const GELI_KUENDIGUNG_ANMELDEN: &str = "geli.kuendigung.anmelden";
/// GNB: confirm an inbound gas Abmeldung (inbound 44004 → UTILMD 44005).
pub const GELI_LIEFERENDE_BESTAETIGEN: &str = "geli.lieferende.bestaetigen";
/// GNB: reject an inbound gas Abmeldung (inbound 44004 → UTILMD 44006).
pub const GELI_LIEFERENDE_ABLEHNEN: &str = "geli.lieferende.ablehnen";
/// LF: initiate a `GeLi` Gas Stornierung (UTILMD 44022/44023).
pub const GELI_STORNIERUNG_INITIIEREN: &str = "geli.stornierung.initiieren";
// ── WiM Strom ─────────────────────────────────────────────────────────────────
/// NB (PID 55042) / MSBA (PID 55039): answer an inbound MSB-Wechsel order
/// positively. The Anmeldung/Kündigung distinction lives in the spawned
/// `wim-geraetewechsel` process (keyed by `MeLo`), not in the command name.
pub const WIM_GERAETEWECHSEL_BESTAETIGEN: &str = "wim.geraetewechsel.bestaetigen";
/// NB (PID 55042) / MSBA (PID 55039): answer an inbound MSB-Wechsel order
/// negatively (APERAK with reason).
pub const WIM_GERAETEWECHSEL_ABLEHNEN: &str = "wim.geraetewechsel.ablehnen";
/// The **technical** acknowledgement on a `WiM` MSB-Wechsel process — 45
/// minutes for Strom `UTILMD`, and not the business answer.
///
/// [`WIM_GERAETEWECHSEL_BESTAETIGEN`] carries that, on its own clock of
/// 3 / 5 / 7 / 1 Werktagen. Two messages, two Fristen, two commands.
pub const WIM_GERAETEWECHSEL_APERAK: &str = "wim.geraetewechsel.aperak";
/// MSB: answer an inbound Steuerungsauftrag positively (ORDRSP).
pub const WIM_STEUERUNGSAUFTRAG_BESTAETIGEN: &str = "wim.steuerungsauftrag.bestaetigen";
/// MSB: answer an inbound Steuerungsauftrag negatively (ORDRSP).
pub const WIM_STEUERUNGSAUFTRAG_ABLEHNEN: &str = "wim.steuerungsauftrag.ablehnen";
/// aMSB: answer an inbound REQOTE Preisanfrage (35001/35002/35004/35005) with the
/// QUOTES Angebot (15001/15002/15004/15005).
pub const WIM_PREISANFRAGE_ANGEBOT_SENDEN: &str = "wim.preisanfrage.angebot-senden";
// ── Cross-check list ──────────────────────────────────────────────────────────
/// Every command name dispatched by out-of-process services.
///
/// `makod` has a registry test asserting each of these is registered; adding a
/// constant above without registering the command in `makod` fails that test.
/// LFN: agree to an announced Zuordnung to an erzeugende Marktlokation or
/// Tranche — inbound 55607, answered UTILMD 55608 (EBDs `E_0603`–`E_0606`).
///
/// The Zustimmung names the Bilanzkreis; without an answer by 15:00 Uhr am ÜT
/// the NB assigns the LFN anyway (GPKE Teil 2 § 2.4.2.2 Nr. 3).
pub const GPKE_ZUORDNUNG_LF_BESTAETIGEN: &str = "gpke.zuordnung-lf.bestaetigen";
/// LFN: refuse an announced Zuordnung — inbound 55607, answered UTILMD 55609.
pub const GPKE_ZUORDNUNG_LF_ABLEHNEN: &str = "gpke.zuordnung-lf.ablehnen";
/// UTILMD 55017 — the LFA agrees to an inbound Kündigung (EBD `E_0614`).
pub const GPKE_KUENDIGUNG_BESTAETIGEN: &str = "gpke.kuendigung.bestaetigen";
/// UTILMD 55018 — the LFA refuses an inbound Kündigung (EBD `E_0614`).
pub const GPKE_KUENDIGUNG_ABLEHNEN: &str = "gpke.kuendigung.ablehnen";
/// UTILMD G 44008 — the LF agrees to an Abmeldung NN vom NB (`E_3002`).
pub const GELI_NB_LIEFERENDE_BESTAETIGEN: &str = "geli.nb-lieferende.bestaetigen";
/// UTILMD G 44009 — the LF refuses an Abmeldung NN vom NB (`E_3002`).
pub const GELI_NB_LIEFERENDE_ABLEHNEN: &str = "geli.nb-lieferende.ablehnen";
/// UTILMD G 44011 — the LFA agrees to an Abmeldeanfrage des NB (`E_3020`).
pub const GELI_BEENDIGUNG_ZUORDNUNG_BESTAETIGEN: &str = "geli.beendigung-zuordnung.bestaetigen";
/// UTILMD G 44012 — the LFA refuses an Abmeldeanfrage des NB (`E_3020`).
pub const GELI_BEENDIGUNG_ZUORDNUNG_ABLEHNEN: &str = "geli.beendigung-zuordnung.ablehnen";
/// NB → LFN: UTILMD G 44036 „Informationsmeldung über existierende Zuordnung"
/// (AWH `GeLi` Gas V1.2 Kap. 2.5.2 Nr. 2).
pub const GELI_ZUORDNUNG_INFORMIEREN: &str = "geli.zuordnung.informieren";
/// NB → LFA: UTILMD G 44037 „Informationsmeldung zur Beendigung der Zuordnung"
/// (Kap. 2.5.2 Nr. 6, „am selben Tag wie in Prozessschritt 5").
pub const GELI_ZUORDNUNG_BEENDEN: &str = "geli.zuordnung.beenden";
/// NB → LFZ: UTILMD G 44038 „Informationsmeldung zur Aufhebung einer zuk.
/// Zuordnung" (Kap. 2.5.2 Nr. 7).
pub const GELI_ZUORDNUNG_AUFHEBEN: &str = "geli.zuordnung.aufheben";
/// UTILMD G 44017 — the LFA agrees to a Gas Kündigung (`E_3001`).
pub const GELI_KUENDIGUNG_BESTAETIGEN: &str = "geli.kuendigung.bestaetigen";
/// UTILMD G 44018 — the LFA refuses a Gas Kündigung (`E_3001`).
pub const GELI_KUENDIGUNG_ABLEHNEN: &str = "geli.kuendigung.ablehnen";
/// UTILMD G 44014 — the E/G agrees to a Gas EoG-Anmeldung (`E_3008`).
pub const GELI_EOG_BESTAETIGEN: &str = "geli.eog.bestaetigen";
/// UTILMD G 44015 — the E/G refuses a Gas EoG-Anmeldung (`E_3008`).
pub const GELI_EOG_ABLEHNEN: &str = "geli.eog.ablehnen";
// ── INVOIC billing (the answer to an inbound invoice) ─────────────────────────
//
// `invoicd` runs the plausibility check and answers with one of these. Five
// families, one pair each — the whole INVOIC settle/dispute surface, which is
// `mako-invoic`'s single state machine seen from the outside.
/// LF: settle an inbound Netznutzungs- or MMM-Rechnung Strom
/// (PIDs 31001 / 31002 / 31005 / 31006) → REMADV 33001.
pub const GPKE_ABRECHNUNG_ANNEHMEN: &str = "gpke.abrechnung.annehmen";
/// LF: dispute one → REMADV 33002 / 33003 / 33004.
pub const GPKE_ABRECHNUNG_ABLEHNEN: &str = "gpke.abrechnung.ablehnen";
/// Settle an inbound `WiM` invoice — the MSB-Rechnung 31009 and the
/// WiM-Rechnung 31003 (Dienstleistungen im Messwesen, **both Sparten**).
///
/// There is no `wim.gas.*` twin: the Gas 31003 rides this command too, which is
/// why its descriptor carries `Gnb` among the permitted roles.
pub const WIM_RECHNUNG_ANNEHMEN: &str = "wim.rechnung.annehmen";
/// Dispute one, by the Zahlungsziel the invoice carries (`SG8 DTM+265`).
pub const WIM_RECHNUNG_ABLEHNEN: &str = "wim.rechnung.ablehnen";
/// Settle an inbound `GaBi` Gas invoice — the aggregated MMM-Rechnung
/// 31007 / 31008 (received by the **MGV**) and the Kapazitätsrechnung 31010
/// (received by the **BKV**).
pub const GABI_RECHNUNG_ANNEHMEN: &str = "gabi.rechnung.annehmen";
/// Dispute one.
pub const GABI_RECHNUNG_ABLEHNEN: &str = "gabi.rechnung.ablehnen";
/// Settle an inbound Stornorechnung (PID 31004) — Sparte-neutral and
/// cross-process (INVOIC AHB § 3.1.2), so it cancels an invoice from any family.
pub const INVOIC_STORNORECHNUNG_ANNEHMEN: &str = "invoic.stornorechnung.annehmen";
/// Dispute one.
pub const INVOIC_STORNORECHNUNG_ABLEHNEN: &str = "invoic.stornorechnung.ablehnen";
/// Settle an inbound Rechnung sonstige Leistung (PID 31011) — Sparte-neutral
/// (GPKE Teil 2 · AWH Sperrprozesse Gas).
pub const INVOIC_SONSTIGE_LEISTUNG_ANNEHMEN: &str = "invoic.sonstige-leistung.annehmen";
/// Dispute one.
pub const INVOIC_SONSTIGE_LEISTUNG_ABLEHNEN: &str = "invoic.sonstige-leistung.ablehnen";
// ── MaBiS Clearingverfahren ───────────────────────────────────────────────────
/// Answer a `MaBiS` Clearingliste with a **Korrekturliste** — one entry per
/// disputed `Marktlokation`, and an empty list when nothing was found.
///
/// The reply is obligatory either way: silence reads as acceptance of whatever
/// the distributor filed, so „reconciled, nothing to correct" is a message and
/// not an omission (BK6-24-174 Anlage 3, Clearingverfahren).
pub const MABIS_LISTE_KORRIGIEREN: &str = "mabis.liste.korrigieren";
/// Refuse a `MaBiS` Clearingliste **entire** and demand a new one.
///
/// The second, disjoint cluster every Clearinglisten-Tree publishes: it names no
/// `Marktlokation` at all — the Abonnement was never ordered, the version is not
/// admitted, the Zeitraum is implausible, or the list arrived outside the
/// Clearingphase DZÜ. Answering such a list with an empty Korrekturliste would
/// state the opposite of what happened.
pub const MABIS_LISTE_ABLEHNEN: &str = "mabis.liste.ablehnen";
pub const DISPATCHED_BY_SERVICES: & = &;