OpportunitiesEntities
Docs
    Ring Platform

    Dezentralisierte selbstbauende Zukunft

    Anmelden
    Entities
    Opportunities
    Store
    Docs
    Plattformkonzepte
    RING ÖkonomieSonoratek LLCGlobaler ImpactKI trifft Web3
    Loslegen
    SchnellstartKalkulatorRoadmap
    Datenschutz|Kontakt
    v1.106.26|Sonoratek LLC

    Documentation

    Konzepte, Nutzen und typische Clone-Szenarien — weniger Code.

    Erste Schritte
    Voraussetzungen
    Installation
    Validierung des ersten Erfolgs
    Nächste Schritte
    Funktionen
    Multi-Vendor-Store
    Membership
    Seitenvorhang
    Entities
    Opportunities
    Echtzeit-Messaging
    News-Modul
    Mitglieder-Blogs
    Benachrichtigungen
    Anpassung
    Ringization playbook
    Deployment
    Selbst gehostetes Deployment
    Architektur
    News-Kingdom-Architektur
    Entwicklung
    OSS und Enterprise

    Schnelleinstieg (CTOs · Auditoren · Agenten)

    Willkommen — Mission & Zielgruppen
    Schnellreferenz
    Erste Schritte
    Architektur & Auth.js
    Backend-Modi & Datenbanken (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Sicherheit & Compliance
    ringdom.org — LegioX-Homebase
    Quellcode — MIT-Lizenz (GitHub)

    Documentation

    Konzepte, Nutzen und typische Clone-Szenarien — weniger Code.

    Erste Schritte
    Voraussetzungen
    Installation
    Validierung des ersten Erfolgs
    Nächste Schritte
    Funktionen
    Multi-Vendor-Store
    Membership
    Seitenvorhang
    Entities
    Opportunities
    Echtzeit-Messaging
    News-Modul
    Mitglieder-Blogs
    Benachrichtigungen
    Anpassung
    Ringization playbook
    Deployment
    Selbst gehostetes Deployment
    Architektur
    News-Kingdom-Architektur
    Entwicklung
    OSS und Enterprise

    Schnelleinstieg (CTOs · Auditoren · Agenten)

    Willkommen — Mission & Zielgruppen
    Schnellreferenz
    Erste Schritte
    Architektur & Auth.js
    Backend-Modi & Datenbanken (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Sicherheit & Compliance
    ringdom.org — LegioX-Homebase
    Quellcode — MIT-Lizenz (GitHub)

    Documentation

    Konzepte, Nutzen und typische Clone-Szenarien — weniger Code.

    Erste Schritte
    Voraussetzungen
    Installation
    Validierung des ersten Erfolgs
    Nächste Schritte
    Funktionen
    Multi-Vendor-Store
    Membership
    Seitenvorhang
    Entities
    Opportunities
    Echtzeit-Messaging
    News-Modul
    Mitglieder-Blogs
    Benachrichtigungen
    Anpassung
    Ringization playbook
    Deployment
    Selbst gehostetes Deployment
    Architektur
    News-Kingdom-Architektur
    Entwicklung
    OSS und Enterprise

    Schnelleinstieg (CTOs · Auditoren · Agenten)

    Willkommen — Mission & Zielgruppen
    Schnellreferenz
    Erste Schritte
    Architektur & Auth.js
    Backend-Modi & Datenbanken (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Sicherheit & Compliance
    ringdom.org — LegioX-Homebase
    Quellcode — MIT-Lizenz (GitHub)
    Ring Logo

    Loading documentation...

    Preparing Ring content

    Ring Logo

    Loading documentation...

    Preparing Ring content

    Ring Logo

    Loading documentation...

    Preparing Ring content

    Opportunities API

    REST für den Marktplatz mit doppelter Natur. Die Browse-Liste ist für Besucher offen; alles andere erfordert eine Sitzung. Die Browse-Liste (GET /api/opportunities) ist eine rollenbewusste Cursor-Paginierung plus Anreicherung pro Betrachter. Die Suche ist eine eigene Route. Like / Save / Hide / Contact sind Server Actions, keine HTTP-Ressourcen.

    Nutze die Tabs Founder / Developer, um diese Seite zu filtern. Produktkreislauf und Karten-UX: Opportunities.

    Nicht sieben Typen

    Ältere API-Texte nannten feste "7 Typen". Laufzeittypen sind die Union OpportunityType in features/opportunities/types/index.ts, begrenzt durch ring-config.json → opportunities.enabledTypes. Dokumentiere keine geschlossene Siebenermenge.

    Oberflächen (gemeinsam)

    MethodeRouteAuthentifizierungHinweise
    GET/api/opportunitiesOptionallimit, startAfter. Die Filterparameter types/type, q/query, categories/category, location, priority schalten auf den Suchdienst um. Übergibt viewerUserId, wenn eine Sitzung besteht. Liefert { opportunities, items, lastVisible, cursor, hasMore }
    POST/api/opportunitiesSitzungBody createOpportunityBodySchema → { opportunity } 201
    GET/api/opportunities/{id}SitzungEin Eintrag
    PUT / PATCH/api/opportunities/{id}SitzungAktualisieren
    DELETE/api/opportunities/{id}SitzungLöschen
    GET/api/opportunities/searchSitzungErfordert q. Optional types, categories, location, limit
    POST/api/opportunities/searchSitzungJSON-Body SearchOpportunitiesParams
    POST/api/opportunities/{id}/signSitzungBeratende Petitionsunterschrift, eine pro Nutzer. Liefert signatureCount, signatureTarget
    GET/api/opportunities/mySitzungListe des Eigentümers; view= all | drafts | pending | active | archived
    POST/api/opportunities/uploadSitzungAnhänge
    GET / POST/api/mcp/v1/opportunitiesMCP-GuardDie Liste übergibt heute kein viewerUserId

    Seit 2026-10-17 liefert ein nicht authentifiziertes GET /api/opportunities öffentliche, nicht vertrauliche Zeilen für die Rolle visitor. Der Besucherfilter greift nach dem Abruf der Seite, daher kann eine Gastseite weniger als limit Zeilen haben. Detail, Suche und Änderungen liefern ohne Sitzung weiterhin 401.

    Was Betreiber wissen sollten

    • Browsen vs. Suchen. Die Seite /opportunities lädt GET /api/opportunities (eine Seite mit Einträgen). Filter im rechten Panel werden als Abfrageparameter gesendet und auf dem Server angewendet. Besucher können ohne Konto browsen.
    • Ausgeblendete Einträge. Wenn ein Mitglied auf Hide tippt, lässt das nächste Browsen oder Suchen dieses Kontos die ID weg. Andere Mitglieder sehen den Eintrag weiterhin.
    • Namen auf Karten. Antworten von Liste und Suche hängen einen öffentlich sicheren creator-Snapshot an, sodass die UI nie eine rohe UUID zeigt.
    • Im Produkt erstellen. Das Formular zum Hinzufügen von Opportunities bevorzugt weiterhin die Server Action createOpportunity (app/_actions/opportunities.ts). REST-POST ist für API- und MCP-Clients; beide rufen denselben Service auf.

    Feature-Kreislauf

    Matcher, aktivierte Typen, Aktionen der Feed-Karten, My Opportunities.

    Discovery-Synchronisierung

    Cache-Tags, revalidatePath, Tunnel opportunity:* nach Erstellen, Aktualisieren oder Löschen.

    Anreicherung der Liste

    GET /api/opportunities (app/api/opportunities/route.ts):

    1. auth(). Ohne Sitzung ist die Rolle visitor, ohne Betrachter-Anreicherung.
    2. Mit Filterparametern: searchOpportunities. Sonst getOpportunitiesForRole({ userRole, limit, startAfter, viewerUserId }).
    3. Wenn viewerUserId gesetzt ist: getViewerHiddenOpportunityIds, dann der DatabaseService-Filter { field: 'id', operator: 'not-in', value: hiddenIds }.
    4. attachOpportunityFeedFields hängt creator, viewer, likes an.

    searchOpportunities liest intern session.user.id (oder die ID des MCP-Akteurs); Aufrufer übergeben kein viewerUserId. Ausschluss ausgeblendeter Einträge und Anreicherung laufen, wenn diese ID existiert.

    MCP GET /api/mcp/v1/opportunities ruft getOpportunitiesForRole ohne viewerUserId auf (kein Ausblendfilter, kein creator/viewer in dieser Liste).

    Zusätze in SerializedOpportunity (Liste/Suche)

    Kanonische Typdatei: features/opportunities/types/index.ts. Datumswerte sind ISO-Strings. Firestore-Timestamp-Formen existieren nur für DB_BACKEND_MODE=firebase-full.

    Create-Body (Pflicht)

    createOpportunityBodySchema (features/opportunities/lib/create-opportunity-schema.ts): title, briefDescription, organizationId, category, location, visibility, contactInfo.linkedEntity, contactInfo.contactAccount.

    POST liefert 201 { opportunity }. Danach ruft das Erstellen syncOpportunityDiscovery mit einem Fragment auf, das aus der Sitzung enthält (live eingefügte Karten).

    Zugriffskontrolle

    • Sichtbarkeit im Dokument: public | subscriber | member | confidential | entity. entity-Zeilen sind nur für Admins, den Autor und Mitglieder der verknüpften Entity lesbar. Listenabfragen wenden Sichtbarkeitsfilter nach Rolle an (buildOpportunityVisibilityFilters).
    • Vertrauliche Einträge erfordern Rollen mit vertraulichem Zugriff.
    • Bewerben passiert in der App (in der Alpha gibt es keine eigene REST-Route /apply).

    Häufige Fragen

    Auswirkungen

    Kann ich Opportunities ohne Sitzung auflisten?

    Ja, nur öffentliche, nicht vertrauliche Zeilen. GET /api/opportunities/{id} und die Suche erfordern weiterhin eine Sitzung.

    Respektiert die Suche Hide?

    Ja, wenn searchOpportunities die Nutzer-ID der Sitzung (oder des MCP-Akteurs) hat. Die HTTP-Suchrouten GET/POST erfordern eine Sitzung.

    Migration

    Ist createdBy weg?

    Nein. Es ist weiterhin die Nutzer-ID. creator ist ein optionaler öffentlicher Snapshot für die UI.

    Betrieb

    Warum zeigen MCP-Listen noch UUIDs auf Karten?

    Die MCP-Liste lässt viewerUserId weg, daher greift attachOpportunityFeedFields auf diesem Pfad nicht.

    Verwandte Dokumentation

    Related documentation

    Opportunities

    Voraussetzung: Produktkreislauf, Aktionen der Feed-Karten und Grenzen der aktivierten Typen.

    Discovery Mutation Sync

    Hängt ab von: Cache-Tags, revalidatePath und Tunnel opportunity:* nach Änderungen.

    Ring Tasks

    Gleicher Ablauf: Umwandeln in ein Gesuch schreibt metadata.source, das die Listenkarten lesen.

    Entities

    Gleicher Ablauf: Die Verknüpfung mit der Organisation ist beim Erstellen Pflicht (`organizationId` / linkedEntity).

    1. Docs
    2. /API
    3. /Opportunities API

    Aktualisiert 26. Okt. 20265 Min. Anhören

    Opportunities API

    REST für den Marktplatz mit doppelter Natur. Die Browse-Liste ist für Besucher offen; alles andere erfordert eine Sitzung. Die Browse-Liste (GET /api/opportunities) ist eine rollenbewusste Cursor-Paginierung plus Anreicherung pro Betrachter. Die Suche ist eine eigene Route. Like / Save / Hide / Contact sind Server Actions, keine HTTP-Ressourcen.

    Nutze die Tabs Founder / Developer, um diese Seite zu filtern. Produktkreislauf und Karten-UX: Opportunities.

    Nicht sieben Typen

    Ältere API-Texte nannten feste "7 Typen". Laufzeittypen sind die Union OpportunityType in features/opportunities/types/index.ts, begrenzt durch ring-config.json → opportunities.enabledTypes. Dokumentiere keine geschlossene Siebenermenge.

    Oberflächen (gemeinsam)

    MethodeRouteAuthentifizierungHinweise
    GET/api/opportunitiesOptionallimit, startAfter. Die Filterparameter types/type, q/query, categories/category, location, priority schalten auf den Suchdienst um. Übergibt viewerUserId, wenn eine Sitzung besteht. Liefert { opportunities, items, lastVisible, cursor, hasMore }
    POST/api/opportunitiesSitzungBody createOpportunityBodySchema → { opportunity } 201
    GET/api/opportunities/{id}SitzungEin Eintrag
    PUT / PATCH/api/opportunities/{id}SitzungAktualisieren
    DELETE/api/opportunities/{id}SitzungLöschen
    GET/api/opportunities/searchSitzungErfordert q. Optional types, categories, location, limit
    POST/api/opportunities/searchSitzungJSON-Body SearchOpportunitiesParams
    POST/api/opportunities/{id}/signSitzungBeratende Petitionsunterschrift, eine pro Nutzer. Liefert signatureCount, signatureTarget
    GET/api/opportunities/mySitzungListe des Eigentümers; view= all | drafts | pending | active | archived
    POST/api/opportunities/uploadSitzungAnhänge
    GET / POST/api/mcp/v1/opportunitiesMCP-GuardDie Liste übergibt heute kein viewerUserId

    Seit 2026-10-17 liefert ein nicht authentifiziertes GET /api/opportunities öffentliche, nicht vertrauliche Zeilen für die Rolle visitor. Der Besucherfilter greift nach dem Abruf der Seite, daher kann eine Gastseite weniger als limit Zeilen haben. Detail, Suche und Änderungen liefern ohne Sitzung weiterhin 401.

    Was Betreiber wissen sollten

    • Browsen vs. Suchen. Die Seite /opportunities lädt GET /api/opportunities (eine Seite mit Einträgen). Filter im rechten Panel werden als Abfrageparameter gesendet und auf dem Server angewendet. Besucher können ohne Konto browsen.
    • Ausgeblendete Einträge. Wenn ein Mitglied auf Hide tippt, lässt das nächste Browsen oder Suchen dieses Kontos die ID weg. Andere Mitglieder sehen den Eintrag weiterhin.
    • Namen auf Karten. Antworten von Liste und Suche hängen einen öffentlich sicheren creator-Snapshot an, sodass die UI nie eine rohe UUID zeigt.
    • Im Produkt erstellen. Das Formular zum Hinzufügen von Opportunities bevorzugt weiterhin die Server Action createOpportunity (app/_actions/opportunities.ts). REST-POST ist für API- und MCP-Clients; beide rufen denselben Service auf.

    Feature-Kreislauf

    Matcher, aktivierte Typen, Aktionen der Feed-Karten, My Opportunities.

    Discovery-Synchronisierung

    Cache-Tags, revalidatePath, Tunnel opportunity:* nach Erstellen, Aktualisieren oder Löschen.

    Anreicherung der Liste

    GET /api/opportunities (app/api/opportunities/route.ts):

    1. auth(). Ohne Sitzung ist die Rolle visitor, ohne Betrachter-Anreicherung.
    2. Mit Filterparametern: searchOpportunities. Sonst getOpportunitiesForRole({ userRole, limit, startAfter, viewerUserId }).
    3. Wenn viewerUserId gesetzt ist: getViewerHiddenOpportunityIds, dann der DatabaseService-Filter { field: 'id', operator: 'not-in', value: hiddenIds }.
    4. attachOpportunityFeedFields hängt creator, viewer, likes an.

    searchOpportunities liest intern session.user.id (oder die ID des MCP-Akteurs); Aufrufer übergeben kein viewerUserId. Ausschluss ausgeblendeter Einträge und Anreicherung laufen, wenn diese ID existiert.

    MCP GET /api/mcp/v1/opportunities ruft getOpportunitiesForRole ohne viewerUserId auf (kein Ausblendfilter, kein creator/viewer in dieser Liste).

    Zusätze in SerializedOpportunity (Liste/Suche)

    Kanonische Typdatei: features/opportunities/types/index.ts. Datumswerte sind ISO-Strings. Firestore-Timestamp-Formen existieren nur für DB_BACKEND_MODE=firebase-full.

    Create-Body (Pflicht)

    createOpportunityBodySchema (features/opportunities/lib/create-opportunity-schema.ts): title, briefDescription, organizationId, category, location, visibility, contactInfo.linkedEntity, contactInfo.contactAccount.

    POST liefert 201 { opportunity }. Danach ruft das Erstellen syncOpportunityDiscovery mit einem Fragment auf, das aus der Sitzung enthält (live eingefügte Karten).

    Zugriffskontrolle

    • Sichtbarkeit im Dokument: public | subscriber | member | confidential | entity. entity-Zeilen sind nur für Admins, den Autor und Mitglieder der verknüpften Entity lesbar. Listenabfragen wenden Sichtbarkeitsfilter nach Rolle an (buildOpportunityVisibilityFilters).
    • Vertrauliche Einträge erfordern Rollen mit vertraulichem Zugriff.
    • Bewerben passiert in der App (in der Alpha gibt es keine eigene REST-Route /apply).

    Häufige Fragen

    Auswirkungen

    Kann ich Opportunities ohne Sitzung auflisten?

    Ja, nur öffentliche, nicht vertrauliche Zeilen. GET /api/opportunities/{id} und die Suche erfordern weiterhin eine Sitzung.

    Respektiert die Suche Hide?

    Ja, wenn searchOpportunities die Nutzer-ID der Sitzung (oder des MCP-Akteurs) hat. Die HTTP-Suchrouten GET/POST erfordern eine Sitzung.

    Migration

    Ist createdBy weg?

    Nein. Es ist weiterhin die Nutzer-ID. creator ist ein optionaler öffentlicher Snapshot für die UI.

    Betrieb

    Warum zeigen MCP-Listen noch UUIDs auf Karten?

    Die MCP-Liste lässt viewerUserId weg, daher greift attachOpportunityFeedFields auf diesem Pfad nicht.

    Verwandte Dokumentation

    Related documentation

    Opportunities

    Voraussetzung: Produktkreislauf, Aktionen der Feed-Karten und Grenzen der aktivierten Typen.

    Discovery Mutation Sync

    Hängt ab von: Cache-Tags, revalidatePath und Tunnel opportunity:* nach Änderungen.

    Ring Tasks

    Gleicher Ablauf: Umwandeln in ein Gesuch schreibt metadata.source, das die Listenkarten lesen.

    Entities

    Gleicher Ablauf: Die Verknüpfung mit der Organisation ist beim Erstellen Pflicht (`organizationId` / linkedEntity).

    1. Docs
    2. /API
    3. /Opportunities API

    Aktualisiert 26. Okt. 20265 Min. Anhören

    Opportunities API

    REST für den Marktplatz mit doppelter Natur. Die Browse-Liste ist für Besucher offen; alles andere erfordert eine Sitzung. Die Browse-Liste (GET /api/opportunities) ist eine rollenbewusste Cursor-Paginierung plus Anreicherung pro Betrachter. Die Suche ist eine eigene Route. Like / Save / Hide / Contact sind Server Actions, keine HTTP-Ressourcen.

    Nutze die Tabs Founder / Developer, um diese Seite zu filtern. Produktkreislauf und Karten-UX: Opportunities.

    Nicht sieben Typen

    Ältere API-Texte nannten feste "7 Typen". Laufzeittypen sind die Union OpportunityType in features/opportunities/types/index.ts, begrenzt durch ring-config.json → opportunities.enabledTypes. Dokumentiere keine geschlossene Siebenermenge.

    Oberflächen (gemeinsam)

    MethodeRouteAuthentifizierungHinweise
    GET/api/opportunitiesOptionallimit, startAfter. Die Filterparameter types/type, q/query, categories/category, location, priority schalten auf den Suchdienst um. Übergibt viewerUserId, wenn eine Sitzung besteht. Liefert { opportunities, items, lastVisible, cursor, hasMore }
    POST/api/opportunitiesSitzungBody createOpportunityBodySchema → { opportunity } 201
    GET/api/opportunities/{id}SitzungEin Eintrag
    PUT / PATCH/api/opportunities/{id}SitzungAktualisieren
    DELETE/api/opportunities/{id}SitzungLöschen
    GET/api/opportunities/searchSitzungErfordert q. Optional types, categories, location, limit
    POST/api/opportunities/searchSitzungJSON-Body SearchOpportunitiesParams
    POST/api/opportunities/{id}/signSitzungBeratende Petitionsunterschrift, eine pro Nutzer. Liefert signatureCount, signatureTarget
    GET/api/opportunities/mySitzungListe des Eigentümers; view= all | drafts | pending | active | archived
    POST/api/opportunities/uploadSitzungAnhänge
    GET / POST/api/mcp/v1/opportunitiesMCP-GuardDie Liste übergibt heute kein viewerUserId

    Seit 2026-10-17 liefert ein nicht authentifiziertes GET /api/opportunities öffentliche, nicht vertrauliche Zeilen für die Rolle visitor. Der Besucherfilter greift nach dem Abruf der Seite, daher kann eine Gastseite weniger als limit Zeilen haben. Detail, Suche und Änderungen liefern ohne Sitzung weiterhin 401.

    Was Betreiber wissen sollten

    • Browsen vs. Suchen. Die Seite /opportunities lädt GET /api/opportunities (eine Seite mit Einträgen). Filter im rechten Panel werden als Abfrageparameter gesendet und auf dem Server angewendet. Besucher können ohne Konto browsen.
    • Ausgeblendete Einträge. Wenn ein Mitglied auf Hide tippt, lässt das nächste Browsen oder Suchen dieses Kontos die ID weg. Andere Mitglieder sehen den Eintrag weiterhin.
    • Namen auf Karten. Antworten von Liste und Suche hängen einen öffentlich sicheren creator-Snapshot an, sodass die UI nie eine rohe UUID zeigt.
    • Im Produkt erstellen. Das Formular zum Hinzufügen von Opportunities bevorzugt weiterhin die Server Action createOpportunity (app/_actions/opportunities.ts). REST-POST ist für API- und MCP-Clients; beide rufen denselben Service auf.

    Feature-Kreislauf

    Matcher, aktivierte Typen, Aktionen der Feed-Karten, My Opportunities.

    Discovery-Synchronisierung

    Cache-Tags, revalidatePath, Tunnel opportunity:* nach Erstellen, Aktualisieren oder Löschen.

    Anreicherung der Liste

    GET /api/opportunities (app/api/opportunities/route.ts):

    1. auth(). Ohne Sitzung ist die Rolle visitor, ohne Betrachter-Anreicherung.
    2. Mit Filterparametern: searchOpportunities. Sonst getOpportunitiesForRole({ userRole, limit, startAfter, viewerUserId }).
    3. Wenn viewerUserId gesetzt ist: getViewerHiddenOpportunityIds, dann der DatabaseService-Filter { field: 'id', operator: 'not-in', value: hiddenIds }.
    4. attachOpportunityFeedFields hängt creator, viewer, likes an.

    searchOpportunities liest intern session.user.id (oder die ID des MCP-Akteurs); Aufrufer übergeben kein viewerUserId. Ausschluss ausgeblendeter Einträge und Anreicherung laufen, wenn diese ID existiert.

    MCP GET /api/mcp/v1/opportunities ruft getOpportunitiesForRole ohne viewerUserId auf (kein Ausblendfilter, kein creator/viewer in dieser Liste).

    Zusätze in SerializedOpportunity (Liste/Suche)

    Kanonische Typdatei: features/opportunities/types/index.ts. Datumswerte sind ISO-Strings. Firestore-Timestamp-Formen existieren nur für DB_BACKEND_MODE=firebase-full.

    Create-Body (Pflicht)

    createOpportunityBodySchema (features/opportunities/lib/create-opportunity-schema.ts): title, briefDescription, organizationId, category, location, visibility, contactInfo.linkedEntity, contactInfo.contactAccount.

    POST liefert 201 { opportunity }. Danach ruft das Erstellen syncOpportunityDiscovery mit einem Fragment auf, das aus der Sitzung enthält (live eingefügte Karten).

    Zugriffskontrolle

    • Sichtbarkeit im Dokument: public | subscriber | member | confidential | entity. entity-Zeilen sind nur für Admins, den Autor und Mitglieder der verknüpften Entity lesbar. Listenabfragen wenden Sichtbarkeitsfilter nach Rolle an (buildOpportunityVisibilityFilters).
    • Vertrauliche Einträge erfordern Rollen mit vertraulichem Zugriff.
    • Bewerben passiert in der App (in der Alpha gibt es keine eigene REST-Route /apply).

    Häufige Fragen

    Auswirkungen

    Kann ich Opportunities ohne Sitzung auflisten?

    Ja, nur öffentliche, nicht vertrauliche Zeilen. GET /api/opportunities/{id} und die Suche erfordern weiterhin eine Sitzung.

    Respektiert die Suche Hide?

    Ja, wenn searchOpportunities die Nutzer-ID der Sitzung (oder des MCP-Akteurs) hat. Die HTTP-Suchrouten GET/POST erfordern eine Sitzung.

    Migration

    Ist createdBy weg?

    Nein. Es ist weiterhin die Nutzer-ID. creator ist ein optionaler öffentlicher Snapshot für die UI.

    Betrieb

    Warum zeigen MCP-Listen noch UUIDs auf Karten?

    Die MCP-Liste lässt viewerUserId weg, daher greift attachOpportunityFeedFields auf diesem Pfad nicht.

    Verwandte Dokumentation

    Related documentation

    Opportunities

    Voraussetzung: Produktkreislauf, Aktionen der Feed-Karten und Grenzen der aktivierten Typen.

    Discovery Mutation Sync

    Hängt ab von: Cache-Tags, revalidatePath und Tunnel opportunity:* nach Änderungen.

    Ring Tasks

    Gleicher Ablauf: Umwandeln in ein Gesuch schreibt metadata.source, das die Listenkarten lesen.

    Entities

    Gleicher Ablauf: Die Verknüpfung mit der Organisation ist beim Erstellen Pflicht (`organizationId` / linkedEntity).

    1. Docs
    2. /API
    3. /Opportunities API

    Aktualisiert 26. Okt. 20265 Min. Anhören

    API-Beispiele

    curl mit Sitzungs-Cookies auf einem lokalen Klon.

    creator { id, name, avatar }

    Interaktionen (kein REST)

    AktionModul
    LiketoggleOpportunityLike → like-service / likes
    SavetoggleOpportunitySave → user_content_interactions
    HidemarkOpportunityNotInterested → user_content_interactions
    KommentarcreateOpportunityComment
    KontaktabsichtrecordOpportunityContactIntent (Matcher; die UI macht weiterhin router.push zu /messages?user=)

    Datei: app/_actions/opportunity-interactions.ts.

    Mapping und not-in

    mapDbQueryRowToSerializedOpportunity() in features/opportunities/lib/opportunity-db-mapper.ts. Nutze lib/converters/opportunity-converter.ts nicht auf Postgres.

    Der Operator 'not-in' steht in IDatabaseService DatabaseFilterOperator. PostgreSQL: NOT (field = ANY($n)). Der Firebase-Adapter filtert nachträglich.

    Discovery-Synchronisierung nach Änderungen

    Erstellen, Aktualisieren, Löschen und Statusänderungen rufen syncOpportunityDiscovery() auf, das:

    1. revalidateTag: invalidiert die Opportunity-Listen von unstable_cache (lib/cached-data.ts)
    2. revalidatePath: /[locale]/opportunities, /[locale]/opportunities/[id], /[locale]/opportunities/my
    3. Tunnel: opportunity:created|updated|deleted auf dem Kanal opportunities

    Es gibt keinen separaten Befehl zum Neuindexieren der Suche. Siehe Discovery mutation sync. Das Browsen im Client nutzt weiterhin useCursorFeed (24 h); revalidatePath allein leert diesen Cache nicht.

    Beispiele

    Erstellen in der UI: useActionState + createOpportunity aus app/_actions/opportunities.ts, siehe API integration.

    API Integration Examples

    Nächster Schritt: curl mit einem lokalen Sitzungs-Cookie.

    Authentication

    Hängt ab von: Sitzungs-Cookie für jede Opportunities-Route erforderlich.

    API-Beispiele

    curl mit Sitzungs-Cookies auf einem lokalen Klon.

    creator { id, name, avatar }

    Interaktionen (kein REST)

    AktionModul
    LiketoggleOpportunityLike → like-service / likes
    SavetoggleOpportunitySave → user_content_interactions
    HidemarkOpportunityNotInterested → user_content_interactions
    KommentarcreateOpportunityComment
    KontaktabsichtrecordOpportunityContactIntent (Matcher; die UI macht weiterhin router.push zu /messages?user=)

    Datei: app/_actions/opportunity-interactions.ts.

    Mapping und not-in

    mapDbQueryRowToSerializedOpportunity() in features/opportunities/lib/opportunity-db-mapper.ts. Nutze lib/converters/opportunity-converter.ts nicht auf Postgres.

    Der Operator 'not-in' steht in IDatabaseService DatabaseFilterOperator. PostgreSQL: NOT (field = ANY($n)). Der Firebase-Adapter filtert nachträglich.

    Discovery-Synchronisierung nach Änderungen

    Erstellen, Aktualisieren, Löschen und Statusänderungen rufen syncOpportunityDiscovery() auf, das:

    1. revalidateTag: invalidiert die Opportunity-Listen von unstable_cache (lib/cached-data.ts)
    2. revalidatePath: /[locale]/opportunities, /[locale]/opportunities/[id], /[locale]/opportunities/my
    3. Tunnel: opportunity:created|updated|deleted auf dem Kanal opportunities

    Es gibt keinen separaten Befehl zum Neuindexieren der Suche. Siehe Discovery mutation sync. Das Browsen im Client nutzt weiterhin useCursorFeed (24 h); revalidatePath allein leert diesen Cache nicht.

    Beispiele

    Erstellen in der UI: useActionState + createOpportunity aus app/_actions/opportunities.ts, siehe API integration.

    API Integration Examples

    Nächster Schritt: curl mit einem lokalen Sitzungs-Cookie.

    Authentication

    Hängt ab von: Sitzungs-Cookie für jede Opportunities-Route erforderlich.

    API-Beispiele

    curl mit Sitzungs-Cookies auf einem lokalen Klon.

    creator { id, name, avatar }

    Interaktionen (kein REST)

    AktionModul
    LiketoggleOpportunityLike → like-service / likes
    SavetoggleOpportunitySave → user_content_interactions
    HidemarkOpportunityNotInterested → user_content_interactions
    KommentarcreateOpportunityComment
    KontaktabsichtrecordOpportunityContactIntent (Matcher; die UI macht weiterhin router.push zu /messages?user=)

    Datei: app/_actions/opportunity-interactions.ts.

    Mapping und not-in

    mapDbQueryRowToSerializedOpportunity() in features/opportunities/lib/opportunity-db-mapper.ts. Nutze lib/converters/opportunity-converter.ts nicht auf Postgres.

    Der Operator 'not-in' steht in IDatabaseService DatabaseFilterOperator. PostgreSQL: NOT (field = ANY($n)). Der Firebase-Adapter filtert nachträglich.

    Discovery-Synchronisierung nach Änderungen

    Erstellen, Aktualisieren, Löschen und Statusänderungen rufen syncOpportunityDiscovery() auf, das:

    1. revalidateTag: invalidiert die Opportunity-Listen von unstable_cache (lib/cached-data.ts)
    2. revalidatePath: /[locale]/opportunities, /[locale]/opportunities/[id], /[locale]/opportunities/my
    3. Tunnel: opportunity:created|updated|deleted auf dem Kanal opportunities

    Es gibt keinen separaten Befehl zum Neuindexieren der Suche. Siehe Discovery mutation sync. Das Browsen im Client nutzt weiterhin useCursorFeed (24 h); revalidatePath allein leert diesen Cache nicht.

    Beispiele

    Erstellen in der UI: useActionState + createOpportunity aus app/_actions/opportunities.ts, siehe API integration.

    API Integration Examples

    Nächster Schritt: curl mit einem lokalen Sitzungs-Cookie.

    Authentication

    Hängt ab von: Sitzungs-Cookie für jede Opportunities-Route erforderlich.