# Reihenfolge beim Anlegen

> Was vor jedem Aufruf existieren muss, woher jede ID kommt, die Abfolge der gängigen Abläufe und die Fehler, die erscheinen, wenn ein Schritt übersprungen wird.

Fast alles bei Memberfy hängt von etwas ab, das vorher angelegt wurde: Die Lektion braucht das Modul, das Modul den Kurs, der Kurs den Bereich. Ruft man die API in der falschen Reihenfolge auf, geht nichts kaputt, aber jeder vorgezogene Aufruf wird abgelehnt. Dieser Leitfaden zeigt die richtige Reihenfolge und die ID, die von einem Aufruf an den nächsten weitergegeben wird.

## Die Abhängigkeitskarte

<div class="flow">
<div class="flow-row"><span class="flow-label">Struktur und Inhalte</span><span class="flow-node">Community</span><span class="flow-arrow">→</span><span class="flow-node">Abschnitt</span><span class="flow-arrow">→</span><span class="flow-node">Bereich (Modul)</span><span class="flow-arrow">→</span><span class="flow-node">Beitrag · Veranstaltung · Bild</span></div>
<div class="flow-row"><span class="flow-label">Kurse</span><span class="flow-node">Kursbereich</span><span class="flow-arrow">→</span><span class="flow-node">Kurs</span><span class="flow-arrow">→</span><span class="flow-node">Modul</span><span class="flow-arrow">→</span><span class="flow-node">Lektion</span></div>
<div class="flow-row"><span class="flow-label">Verkauf</span><span class="flow-node">Auszahlungskonto genehmigt</span><span class="flow-arrow">→</span><span class="flow-node">Verkaufen und auszahlen</span></div>
<div class="flow-row"><span class="flow-label">Abonnement</span><span class="flow-node">Abrechnungsoption</span><span class="flow-arrow">→</span><span class="flow-node">Plan</span><span class="flow-arrow">→</span><span class="flow-node">Zusatzprodukte des Plans</span><span class="flow-arrow">→</span><span class="flow-node">Downsell</span></div>
<div class="flow-row"><span class="flow-label">Zugriff</span><span class="flow-node">Plan oder Produkt</span><span class="flow-arrow">→</span><span class="flow-node">Zugriff auf den Bereich</span></div>
<div class="flow-row"><span class="flow-label">Rabatt</span><span class="flow-node">Produkte</span><span class="flow-arrow">→</span><span class="flow-node">Gutschein</span></div>
</div>

Anders gelesen:

| Um … anzulegen | brauchst du vorher … | und übergibst |
|---|---|---|
| Bereich | einen Abschnitt | `sectionId` |
| Beitrag, Veranstaltung, Kurs, Bild | einen Bereich | `spaceId` |
| Kursmodul | einen Kurs | `courseId` |
| Lektion | ein Modul | `moduleId` |
| Plan | die Abrechnungsoptionen (Produkte vom Typ `SUBSCRIPTION`) | `productIds` |
| Zusatzprodukt im Plan | den Plan und ein monatliches Produkt, das keine Option eines Plans ist | `addOnProductIds` |
| Zugriff auf einen Bereich per Plan oder Produkt | den Plan oder das Produkt | `access.subscriptionGroupIds`, `access.productIds` |
| Gutschein nur für bestimmte Produkte | die Produkte | `applicableProducts` |
| Jeder Verkauf und jede Auszahlung | genehmigte Geschäftsinformationen und ein genehmigtes Auszahlungskonto | — |

Bei allen Aufrufen unten gehören `Authorization` und `X-CommunityId` dazu. Siehe [Authentifizierung](/api/autenticacao) und [X-CommunityId](/api/x-community-id).

## Kurs

1. **Abschnitt** (falls noch keiner existiert): [`POST /api/sections`](/api/referencia/sections-spaces/post-sections) mit `title` und `visibility`. Speichere `data.id` als `sectionId`.
2. **Kursbereich**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) mit `sectionId`, `title` und `module: "courses"`. Speichere die `spaceId`.
3. **Kurs**: [`POST /api/courses`](/api/referencia/courses/post-courses) mit `communityId` (dieselbe wie im Header), `spaceId`, `title`, `slug` und `level` (`beginner`, `intermediate`, `advanced`). Er entsteht als Entwurf. Speichere die `courseId`.
4. **Module**: [`POST /api/courses/module`](/api/referencia/courses/post-courses-module) mit `courseId` und `title`, eines pro Modul. Speichere jede `moduleId`.
5. **Lektionen**: [`POST /api/courses/lesson`](/api/referencia/courses/post-courses-lesson) mit `moduleId`, `title` und `type` (`text`, `image`, `video`, `link`).
6. **Veröffentlichen**: [`PUT /api/courses/{id}`](/api/referencia/courses/put-courses-by-id) mit `status: "published"`. Nur ein veröffentlichter Kurs nimmt Einschreibungen an.

Für spätere Anpassungen: [`PUT`](/api/referencia/courses/put-courses-module-by-module-id) und [`DELETE /api/courses/module/{moduleId}`](/api/referencia/courses/delete-courses-module-by-module-id) benennen ein Modul um, ändern seine Reihenfolge und löschen es (samt Lektionen); [`PUT`](/api/referencia/courses/put-courses-lesson-by-lesson-id) und [`DELETE /api/courses/lesson/{lessonId}`](/api/referencia/courses/delete-courses-lesson-by-lesson-id) ändern Titel, Typ, Dauer und Reihenfolge einer Lektion, verschieben sie in ein anderes Modul desselben Kurses (`moduleId`) und löschen sie. Beim Löschen bleibt der Fortschritt aller erhalten, die sie schon angesehen haben.

Um den Kurs zu verkaufen, mach weiter mit einem Produkt, das den Bereich freigibt (siehe [Veranstaltung](#veranstaltung), Schritte 3 und 4, die genauso gelten).

## Mentoring

Eine Gruppe mit eigener Pinnwand, Treffen und monatlicher Abrechnung. (Mit der [Vertragslaufzeit](/monetizacao/duracao-do-contrato) bekommt die Option aus Schritt 3 zusätzlich `commitmentMonths`.)

1. **Privater Bereich der Gruppe**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) mit `module: "feed"` und `visibility: "private"`. Speichere die `spaceId`.
2. **Treffen**: [`POST /api/events`](/api/referencia/events/post-events), eines pro Treffen, mit `spaceId`, `title`, `slug`, `type: "online"`, `startTime` und `endTime`.
3. **Abrechnungsoption**: [`POST /api/products`](/api/referencia/products/post-communities-by-community-id-products) mit `type: "SUBSCRIPTION"`, `title`, `price`, `billingInterval: "MONTHLY"` und `allowedPaymentMethods`. Speichere die `id` des Produkts.
4. **Plan**: [`POST /api/subscription-groups`](/api/referencia/subscriptions/post-communities-by-community-id-subscription-groups) mit `name` und `productIds: [<ID aus Schritt 3>]`. Speichere die `id` des Plans.
5. **Den Bereich für den Plan freigeben**: [`PUT /api/spaces/{id}`](/api/referencia/sections-spaces/put-spaces-by-id) mit `access: { "subscriptionGroupIds": [<ID des Plans>] }`.

Schritt 5 funktioniert erst nach Schritt 4: Der Plan muss existieren, damit er im Zugriff genannt werden kann.

## Veranstaltung

Eine Präsenzveranstaltung mit bezahltem Ticket und Hinweis im Feed.

1. **Veranstaltungsbereich**: [`POST /api/spaces`](/api/referencia/sections-spaces/post-spaces) mit `module: "events"`.
2. **Veranstaltung**: [`POST /api/events`](/api/referencia/events/post-events) mit `spaceId`, `title`, `slug`, `type: "in_person"`, `startTime`, `endTime` und der Adresse (`street`, `number`, `city` …).
3. **Ticket**: [`POST /api/products`](/api/referencia/products/post-communities-by-community-id-products) mit `type: "ONE_TIME"`, `price`, `hasStock: true` und `stockQuantity`. Danach [veröffentlichen](/api/referencia/products/post-communities-by-community-id-products-by-id-publish).
4. **Den Bereich für Käufer freigeben**: [`PUT /api/spaces/{id}`](/api/referencia/sections-spaces/put-spaces-by-id) mit `visibility: "private"` und `access: { "productIds": [<ID des Tickets>] }`.
5. **Angehefteter Hinweis**: [`POST /api/content`](/api/referencia/content/post-content) im Feed-Bereich und [`PUT /api/feed/{type}/{id}/pin`](/api/referencia/feed/put-feed-by-type-by-id-pin) mit der ID des Beitrags.

## Plan mit Zusatzprodukten

1. **Abrechnungsoptionen des Plans**: ein [`POST .../products`](/api/referencia/products/post-communities-by-community-id-products) pro Option (Monatlich, Jährlich), `type: "SUBSCRIPTION"`.
2. **Das Zusatzprodukt**: ein weiteres `POST .../products`, `type: "SUBSCRIPTION"`, `billingInterval: "MONTHLY"`. Es kommt in **keine** `productIds` eines Plans.
3. **Plan**: [`POST .../subscription-groups`](/api/referencia/subscriptions/post-communities-by-community-id-subscription-groups) mit den `productIds` aus Schritt 1.
4. **Zusatzprodukte im Plan**: [`PUT .../subscription-groups/{id}`](/api/referencia/subscriptions/put-communities-by-community-id-subscription-groups-by-id) mit `addOnProductIds: [<ID aus Schritt 2>]`.

## Vor dem Verkaufen: das Auszahlungskonto

Eine Reihenfolge, die für jeden Verkauf gilt:

1. [`POST .../business-information`](/api/referencia/business/post-communities-by-community-id-business-information) und [`.../submit`](/api/referencia/business/post-communities-by-community-id-business-information-submit).
2. [`POST .../payout-settings`](/api/referencia/payouts/post-communities-by-community-id-payout-settings) und [`.../submit`](/api/referencia/payouts/post-communities-by-community-id-payout-settings-submit).
3. Auf beide Genehmigungen warten (bis zu 7 Werktage). [`GET .../payout-settings/prerequisites`](/api/referencia/payouts/get-communities-by-community-id-payout-settings-prerequisites) sagt, was noch fehlt.

Produkte, Optionen, Pläne, Add-ons, Gutscheine und Downsell-Angebote kannst du schon vor der Genehmigung anlegen und bearbeiten: Das Produkt entsteht als `DRAFT`, in der Währung des Landes aus den Geschäftsinformationen (in jedem Status) oder ohne sie in `BRL`. Das Veröffentlichen ([`POST .../products/{id}/publish`](/api/referencia/products/post-communities-by-community-id-products-by-id-publish) oder `PUT .../products/{id}` mit `status: ACTIVE`), der Checkout und die Auszahlung warten auf die Genehmigung. Werden genehmigte Geschäftsinformationen bearbeitet, gehen sie zurück auf `PENDING` und brauchen erneut `.../submit`; bis zur neuen Genehmigung lehnt der Checkout ab.

## Die Fehler, wenn ein Schritt fehlt

| Aufruf | Was fehlte | Antwort |
|---|---|---|
| `POST /api/spaces` | der Abschnitt | `400` · Abschnitt nicht gefunden oder gehört nicht zu dieser Community |
| `POST /api/spaces` (oder `PUT`) | der Abschnitt ist enger gefasst | `400` · *This space cannot be more open than the section "…", which is …* |
| `PUT /api/spaces/{id}` mit `access` | der genannte Plan, das Produkt oder die Gruppe | `400` · *The access grant "…" does not exist in this community.* (`param: access`) |
| `POST /api/courses` | der Bereich | `400` · Bereichs-ID ist Pflicht, oder Bereich nicht gefunden bzw. gehört nicht zu dieser Community |
| `POST /api/courses/module` | der Kurs | `404` · *Course not found* |
| `POST /api/courses/lesson` | das Modul | `404` · *Module not found* |
| `POST .../subscription-groups` | die Abrechnungsoptionen | `400` · *Produkt nicht gefunden* |
| `PUT .../subscription-groups/{id}` mit `addOnProductIds` | das Produkt des Zusatzes, oder es ist schon Option eines Plans | `400` · *Eines der Add-ons existiert in dieser Community nicht oder wurde gelöscht.* / *Ein Produkt, das Abrechnungsoption eines Tarifs ist, kann kein Add-on eines anderen sein.* |
| Checkout-Konfiguration | das genehmigte Auszahlungskonto | `400` · Für diese Community wurde keine Zahlungskonfiguration eingerichtet |
| `POST .../products/{id}/publish` (oder `PUT` mit `status: ACTIVE`) | die genehmigten Geschäftsinformationen | `403` · *Um zu veröffentlichen und zu verkaufen, braucht die Community genehmigte Geschäftsinformationen…* |
| `POST .../products/{id}/publish` | das Produkt in der Währung des genehmigten Landes | `400` · *Dieses Produkt ist in …, die genehmigten Geschäftsinformationen verwenden aber …* (`param: currency`) |
| `POST /api/checkout` | die genehmigten Geschäftsinformationen | `403` · *Die Community muss genehmigte Geschäftsinformationen haben, um bezahlte Produkte zu aktivieren* |
| `POST .../payouts` | Guthaben für Betrag und Gebühr | `400` · *Unzureichendes Guthaben. Verfügbar: …* |
| Jeder | der Header | `400` · `X-CommunityId` ist Pflicht |

Einige Formatvalidierungen antworten noch auf Englisch (etwa *Valid course ID is required*, wenn die ID keine UUID ist).

## Tipps

- **Speichere jede ID**, die in `data.id` zurückkommt: Genau die verlangt der nächste Aufruf.
- **Schick dieselbe `communityId`** im Body (wenn die Route sie verlangt) und im Header.
- **Wiederholen macht nichts rückgängig**: Bricht eine Abfolge mittendrin ab, mach bei dem Schritt weiter, der fehlgeschlagen ist, statt neu anzufangen (Neuanfangen erzeugt Duplikate).
- Im [MCP](/mcp/ferramentas) werden die zusammengesetzten Werkzeuge diese Reihenfolge selbst einhalten.
