Preisoptionen in Formular-Entscheidungsoptionen (Radio/Checkbox) #133

Closed
opened 2026-06-28 14:40:46 +02:00 by niboer · 1 comment
Owner

Beschreibung

Formular-Definitionen sollen bei Entscheidungsoptionen Preise unterstuetzen koennen. Dazu werden zwei neue Feld-Typen benoetigt:

Either/Or (Radio-Buttons, type: "radio")

Einzelauswahl aus mehreren Optionen mit Preisen:

  • Zimmertyp A Fr - So: 150,00 EUR
  • Zimmertyp A Sa - So: 100,00 EUR
  • Zimmertyp B Fr - So: 200,00 EUR
  • Zimmertyp B Sa - So: 120,00 EUR

Multiselection (Checkboxen, type: "checkbox")

Mehrfachauswahl mit Preisen:

  • Fruehstueck: 15,00 EUR
  • Parkplatz: 10,00 EUR
  • Bettwaesche: 5,00 EUR

Akzeptanzkriterien

  1. Formular-Editor erlaubt Anlegen von radio- und checkbox-Feldern mit bepreisten Optionen
  2. Gaeste sehen Radio-Buttons/Checkboxen mit Preisangaben und Gesamtsumme
  3. Organisatoren sehen in der Antworten-Uebersicht die Preise und Gesamtsumme
  4. Antworten koennen ueberschrieben werden (Override-Dialog unterstuetzt neue Typen)
  5. Keine Datenbank-Migration erforderlich (JSONB-Struktur)
  6. Tests fuer Editor, Anzeige und Preisberechnung

Aufgaben

  • openapi.yaml: FormFieldOption-Schema mit label + price
  • orval-Typen regenerieren
  • FormEditor: radio/checkbox mit Preis-Optionen-Editor
  • Gaeste-Formular: Radio/Checkbox mit Preisen und Gesamtsumme
  • Organisator-Ansicht: Preise und Summe in formatFormAnswers
  • Override-Dialog: Radio/Checkbox-Unterstuetzung
  • Tests: Editor, Anzeige, Preisberechnung
  • Dokumentation anpassen (design.md, AGENTS.md)
## Beschreibung Formular-Definitionen sollen bei Entscheidungsoptionen Preise unterstuetzen koennen. Dazu werden zwei neue Feld-Typen benoetigt: ### Either/Or (Radio-Buttons, `type: "radio"`) Einzelauswahl aus mehreren Optionen mit Preisen: - Zimmertyp A Fr - So: 150,00 EUR - Zimmertyp A Sa - So: 100,00 EUR - Zimmertyp B Fr - So: 200,00 EUR - Zimmertyp B Sa - So: 120,00 EUR ### Multiselection (Checkboxen, `type: "checkbox"`) Mehrfachauswahl mit Preisen: - Fruehstueck: 15,00 EUR - Parkplatz: 10,00 EUR - Bettwaesche: 5,00 EUR ### Akzeptanzkriterien 1. Formular-Editor erlaubt Anlegen von `radio`- und `checkbox`-Feldern mit bepreisten Optionen 2. Gaeste sehen Radio-Buttons/Checkboxen mit Preisangaben und Gesamtsumme 3. Organisatoren sehen in der Antworten-Uebersicht die Preise und Gesamtsumme 4. Antworten koennen ueberschrieben werden (Override-Dialog unterstuetzt neue Typen) 5. Keine Datenbank-Migration erforderlich (JSONB-Struktur) 6. Tests fuer Editor, Anzeige und Preisberechnung ### Aufgaben - [ ] openapi.yaml: `FormFieldOption`-Schema mit `label` + `price` - [ ] orval-Typen regenerieren - [ ] FormEditor: radio/checkbox mit Preis-Optionen-Editor - [ ] Gaeste-Formular: Radio/Checkbox mit Preisen und Gesamtsumme - [ ] Organisator-Ansicht: Preise und Summe in formatFormAnswers - [ ] Override-Dialog: Radio/Checkbox-Unterstuetzung - [ ] Tests: Editor, Anzeige, Preisberechnung - [ ] Dokumentation anpassen (design.md, AGENTS.md)
Author
Owner

Detailplan (aus Code-Analyse)

openapi.yaml (backend/openapi.yaml)

  • Neues Schema FormFieldOption eintragen:
    FormFieldOption:
      type: object
      properties:
        label:
          type: string
        price:
          type: integer
          minimum: 0
          description: Preis in Cent (15000 = EUR 150,00)
      required:
        - label
    
  • Die formDefinition-Items in Event/CreateEvent/UpdateEvent/Template/CreateTemplate/UpdateTemplate/Invitation/FormDefinitionRequest bleiben type: object (dynamisch), FormFieldOption dient als Struktur-Doku

FormEditor (frontend/src/lib/components/form-editor.svelte)

  • Lokales Interface FormFieldOption mit label: string, price: number (Cent)
  • FormField.options-Typ aendern: string | FormFieldOption[] (select=string, radio/checkbox=Array)
  • Type-Dropdown um radio und checkbox erweitern
  • Bepreister Options-Editor: pro Option label-Input + price-Input (Euro, Umrechnung cents ↔ Euro)
  • Add/Remove-Buttons fuer Optionen innerhalb eines Felds
  • Serialisierung in handleSave(): radio/checkbox → options: [{ label, price }] (price in Cent)

Gaeste-Formular (frontend/src/routes/app/persons/[personId]/)

  • +page.svelte: formValues-Typ von Record<string, string> auf Record<string, string | string[]> aendern
  • radio-Feld rendern: Radio-Button-Gruppe mit formatEuro(price / 100) pro Option
  • checkbox-Feld rendern: Checkbox-Gruppe mit Preisangabe und dynamischer Gesamtsumme
  • +page.server.ts saveDraft/submitFinal: FormData-Eintraege mit Mehrfachwerten als string[] sammeln
  • Hidden-Inputs in saveDraft/submitFinal: checkbox → mehrere Inputs gleichen Namens

Organisator-Ansicht (frontend/src/routes/app/events/[eventId]/)

  • +page.svelte formatFormAnswers(): radio/checkbox-Preise anzeigen + Gesamtsumme
  • overrideValues-Typ: Record<string, string | string[]>
  • Override-Dialog: radio als Radio-Gruppe, checkbox als Checkbox-Gruppe mit Preisen
  • +page.server.ts overrideForm: Checkbox-Arrays aus FormData verarbeiten

Tests

  • FormEditor erzeugt korrekte Cent-Preise (neu)
  • Guest-Formular berechnet Gesamtsumme korrekt (neu)
  • Server-Actions verarbeiten Checkbox-Arrays (neu)
  • formatFormAnswers zeigt Preise und Summe (events.test.ts erweitern)
  • Override mit Radio/Checkbox (events.test.ts erweitern)

Keine DB-Migration

  • formDefinition ist JSONB, keine Schema-Aenderung noetig
  • Backend-Logik unveraendert (speichert JSONB wie bisher)
## Detailplan (aus Code-Analyse) ### openapi.yaml (`backend/openapi.yaml`) - [ ] Neues Schema `FormFieldOption` eintragen: ```yaml FormFieldOption: type: object properties: label: type: string price: type: integer minimum: 0 description: Preis in Cent (15000 = EUR 150,00) required: - label ``` - [ ] Die `formDefinition`-Items in Event/CreateEvent/UpdateEvent/Template/CreateTemplate/UpdateTemplate/Invitation/FormDefinitionRequest bleiben `type: object` (dynamisch), `FormFieldOption` dient als Struktur-Doku ### FormEditor (`frontend/src/lib/components/form-editor.svelte`) - [ ] Lokales Interface `FormFieldOption` mit `label: string, price: number` (Cent) - [ ] `FormField.options`-Typ aendern: `string | FormFieldOption[]` (select=string, radio/checkbox=Array) - [ ] Type-Dropdown um `radio` und `checkbox` erweitern - [ ] Bepreister Options-Editor: pro Option `label`-Input + `price`-Input (Euro, Umrechnung cents ↔ Euro) - [ ] Add/Remove-Buttons fuer Optionen innerhalb eines Felds - [ ] Serialisierung in `handleSave()`: radio/checkbox → `options: [{ label, price }]` (price in Cent) ### Gaeste-Formular (`frontend/src/routes/app/persons/[personId]/`) - [ ] `+page.svelte`: `formValues`-Typ von `Record<string, string>` auf `Record<string, string | string[]>` aendern - [ ] `radio`-Feld rendern: Radio-Button-Gruppe mit `formatEuro(price / 100)` pro Option - [ ] `checkbox`-Feld rendern: Checkbox-Gruppe mit Preisangabe und dynamischer Gesamtsumme - [ ] `+page.server.ts` `saveDraft`/`submitFinal`: FormData-Eintraege mit Mehrfachwerten als `string[]` sammeln - [ ] Hidden-Inputs in saveDraft/submitFinal: checkbox → mehrere Inputs gleichen Namens ### Organisator-Ansicht (`frontend/src/routes/app/events/[eventId]/`) - [ ] `+page.svelte` `formatFormAnswers()`: radio/checkbox-Preise anzeigen + Gesamtsumme - [ ] `overrideValues`-Typ: `Record<string, string | string[]>` - [ ] Override-Dialog: radio als Radio-Gruppe, checkbox als Checkbox-Gruppe mit Preisen - [ ] `+page.server.ts` `overrideForm`: Checkbox-Arrays aus FormData verarbeiten ### Tests - [ ] FormEditor erzeugt korrekte Cent-Preise (neu) - [ ] Guest-Formular berechnet Gesamtsumme korrekt (neu) - [ ] Server-Actions verarbeiten Checkbox-Arrays (neu) - [ ] formatFormAnswers zeigt Preise und Summe (events.test.ts erweitern) - [ ] Override mit Radio/Checkbox (events.test.ts erweitern) ### Keine DB-Migration - `formDefinition` ist JSONB, keine Schema-Aenderung noetig - Backend-Logik unveraendert (speichert JSONB wie bisher)
Sign in to join this conversation.
No description provided.