Beide Dateien mit dem Read-Tool lesen. Ohne Lebenslauf keine Bewertung, ohne Zugangsdaten kein CRM-Eintrag.
Alle drei mit dem Read-Tool lesen. Ohne Lebenslauf keine fachliche Bewertung, ohne Rahmenbedingungen keine automatische Misc-Bewertung, ohne Zugangsdaten kein CRM-Eintrag.
Die Zugangsdaten-Datei enthält Base-URL, Auth-Header-Schema, API-Key sowie verifizierte Entitäts- und Feldnamen. **Der API-Key darf niemals im Chat angezeigt, in Dateien geschrieben oder in Commits/Doku übernommen werden** — er wird nur zur Laufzeit in eine Shell-Variable gelesen und direkt in `curl`-Aufrufe eingesetzt.
Die Zugangsdaten-Datei enthält Base-URL, Auth-Header-Schema, API-Key sowie verifizierte Entitäts- und Feldnamen. **Der API-Key darf niemals im Chat angezeigt, in Dateien geschrieben oder in Commits/Doku übernommen werden** — er wird nur zur Laufzeit in eine Shell-Variable gelesen und direkt in `curl`-Aufrufe eingesetzt.
## Schritt 1: Ausschreibung beschaffen
## Schritt 1: Ausschreibung beschaffen und Eckdaten extrahieren
Die Projektausschreibung kommt auf zwei Wegen:
Die Projektausschreibung kommt auf zwei Wegen:
- **URL:** Nennt der Nutzer eine URL, hole den Seitentext mit dem **WebFetch-Tool**.
- **URL:** Nennt der Nutzer eine URL, hole den Seitentext mit dem **WebFetch-Tool**.
@@ -39,6 +40,11 @@ Daraus entnehmen:
- **Projekt-URL**: die tatsächliche URL der Seite, falls vorhanden.
- **Projekt-URL**: die tatsächliche URL der Seite, falls vorhanden.
- **Beschreibung und Aufgaben**: nur Kontext für die Bewertung, keine Tabellenzeilen.
- **Beschreibung und Aufgaben**: nur Kontext für die Bewertung, keine Tabellenzeilen.
- **Anforderungen**: jede Anforderung einzeln, im Originalwortlaut (behutsam kürzen ist erlaubt, Bedeutung nie verändern). Rahmenbedingungen (Start, Einsatzort/Remote-Anteil, Auslastung, Laufzeit) zählen als Anforderungen der Kategorie Misc.
- **Anforderungen**: jede Anforderung einzeln, im Originalwortlaut (behutsam kürzen ist erlaubt, Bedeutung nie verändern). Rahmenbedingungen (Start, Einsatzort/Remote-Anteil, Auslastung, Laufzeit) zählen als Anforderungen der Kategorie Misc.
- **Käufer-Typ**: Agentur (Wiederverkäufer) ODER Endkunde (Direktauftrag).
- **❌** wenn der Lebenslauf nichts Belastbares hergibt. Streng bleiben — eine geschönte Bewertung macht die Match-Zahlen wertlos. Kalibrierung aus der Praxis: Proof-of-Concept-Erfahrung deckt „produktiven Betrieb" nicht ab; „mehrjährig" wörtlich nehmen; ein ALM-Produktname (z. B. „Azure DevOps Server") belegt keine Cloud-Plattform-Erfahrung.
- **❌** wenn der Lebenslauf nichts Belastbares hergibt. Streng bleiben — eine geschönte Bewertung macht die Match-Zahlen wertlos. Kalibrierung aus der Praxis: Proof-of-Concept-Erfahrung deckt „produktiven Betrieb" nicht ab; „mehrjährig" wörtlich nehmen; ein ALM-Produktname (z. B. „Azure DevOps Server") belegt keine Cloud-Plattform-Erfahrung.
- **❔** nur bei echter Teilevidenz, wenn die Entscheidung von Wissen abhängt, das nur Thomas hat — solche Fälle klärt das Review.
- **❔** nur bei echter Teilevidenz, wenn die Entscheidung von Wissen abhängt, das nur Thomas hat — solche Fälle klärt das Review.
- „wie z. B."-Aufzählungen: gleichwertige Alternativen zählen als Abdeckung (Beispiel: Ollama/llama.cpp/Transformers decken „LLM-Inference-Stacks wie z. B. vLLM, TGI, Triton" ab).
- „wie z. B."-Aufzählungen: gleichwertige Alternativen zählen als Abdeckung (Beispiel: Ollama/llama.cpp/Transformers decken „LLM-Inference-Stacks wie z. B. vLLM, TGI, Triton" ab).
- Rahmenbedingungen (Misc): Ortsbezug kann der Lebenslauf beantworten (Büro in Unterhaching bei München). Verfügbarkeit, Auslastung und Laufzeit kann er nicht beantworten → ❔ vorschlagen, Thomas setzt im Review ✅ oder ❌.
- Rahmenbedingungen (Misc) werden NICHT hier, sondern in Schritt 3b automatisch gegen `vorgaben/rahmenbedingungen.md` bewertet.
`vorgaben/rahmenbedingungen.md` lesen und jede Misc-Anforderung danach bewerten:
- **Verfügbar ab / Projektstart:** Start ≤ heute + 8 Wochen (56 Tage) → ✅; > 8 Wochen → ❌; nicht genannt → ❔. („heute" = aktuelles Datum.)
- **Auslastung:** 75–100 % → ✅; < 75 % → ❔; nicht genannt → ❔.
- **Laufzeit:** jede → ✅.
- **Einsatzort/Remote:** 100 % Remote → ✅. Bei < 100 % Remote (Hybrid/Onsite) Distanz des Onsite-Orts zu Sauerlach bestimmen (siehe unten): ≤ 50 km → ✅; 50–60 km → ❔; > 60 km → ❌. Einsatzort/Remote-Anteil unklar oder nicht genannt → ❌.
**Distanzbestimmung (Geokodierung, Pflicht bei Onsite/Hybrid):** Onsite-Ort per Nominatim auflösen und Luftlinie zu Sauerlach (47,9721 N / 11,6528 O) per Haversine rechnen. Bei Geokodierungs-Fehler/Mehrdeutigkeit (Ausgabe `UNBEKANNT`) → ❔. Nominatim-Policy: max. 1 Request/s.
```bash
python3 - "<ONSITE_ORT>"<<'PY'
import sys, json, urllib.request, urllib.parse
from math import radians, sin, cos, asin, sqrt
ort = sys.argv[1]
UA = 'bewerb-projekt-anlegen/1.0 (Thomas.Langer@destengs.com)'
- Beide Match-Zahlen in einer Zeile, getrennt durch ` · `.
- Beide Match-Zahlen in einer Zeile, getrennt durch ` · `.
## Schritt 6: Review im Chat — immer vor dem CRM-Eintrag
## Schritt 6: Review im Chat — immer vor jedem CRM-Schreibvorgang
Niemals ohne explizite Freigabe ins CRM schreiben. Im Chat zeigen:
Niemals ohne explizite Freigabe ins CRM schreiben. Im Chat zeigen:
1. Vorgesehener **Name** der Opportunity (= Projektname) und **Projektlink**.
1. Vorgesehener **Name** der Opportunity (= Projektname) und **Projektlink**.
2.Den wörtlichen Beschreibungs-Markdown in einem Codeblock (damit das Format sichtbar ist).
2.**Käufer-Typ** (Agentur/Direktauftrag) mit Kurzbegründung.
3.Kurze Begründungen zu allen ❌- und ❔-Bewertungen außerhalb der Tabelle — hier stecken die Ermessensentscheidungen, die Thomas korrigieren können muss.
3.**Firma:** Name und `type` (Reseller bei Agentur, Customer bei Direktauftrag); „neu anlegen" oder „bestehende nutzen: <Name/ID>". Bei ähnlichen, nicht identischen Treffern die Kandidatenliste zeigen und entscheiden lassen.
4.**Kontakt:** Name; „neu anlegen" oder „bestehend nutzen: <Name/ID>".
5.**Verknüpfungs-Zuordnung** der Verkaufschance (account vs. cAccount1, Kontakt).
6. Den wörtlichen Beschreibungs-Markdown in einem Codeblock.
7. Kurze Begründungen zu allen ❌- und ❔-Bewertungen (Must/Nice/Misc) außerhalb der Tabelle.
Korrekturen kommen als „Nr. X → ✅/❌/❔". Danach Matches neu berechnen und die geänderten Werte nennen. Erst nach Freigabe weiter zu Schritt 7.
Korrekturen kommen als „Nr. X → ✅/❌/❔" oder als Korrektur zu Firma/Kontakt/Typ. Danach betroffene Matches neu berechnen und geänderte Werte nennen. Erst nach Freigabe weiter zu Schritt 7.
## Schritt 7: CRM-Eintrag per Shell (curl)
## Schritt 7: CRM-Eintrag per Shell — Reihenfolge Firma → Kontakt → Verkaufschance
Diese Umgebung erreicht die CRM-Domain direkt — der API-Zugriff läuft per `curl` aus der Shell (kein Browser nötig).
Diese Umgebung erreicht die CRM-Domain direkt; der Zugriff läuft per `curl`. Key/Base sicher laden (Werte nicht ausgeben):
**Key und Base-URL sicher laden** (Werte landen in Variablen, werden nicht ausgegeben):
```bash
```bash
KEY=$(grep -oE '[0-9a-f]{32}' .secrets/espocrm-api.md | head -1)
KEY=$(grep -oE '[0-9a-f]{32}' .secrets/espocrm-api.md | head -1)
BASE=$(grep -oE 'https://[^ `]+/api/v1' .secrets/espocrm-api.md | head -1)
BASE=$(grep -oE 'https://[^ `]+/api/v1' .secrets/espocrm-api.md | head -1)
```
```
**Duplikat-Prüfung** — existiert der Name schon, „ (2)", „ (3)", … anhängen:
### 7.1 Firma (Account)
Dedup-Suche mit einem Kern-Token des Namens (z. B. „Aristo"):
Treffer gemäß Review-Entscheidung behandeln. Bestehende Firma → deren `id` als ACCOUNT_ID merken. Sonst neu anlegen — Payload mit dem **Write-Tool** nach `/tmp/account.json` (`type`: `Reseller` bei Agentur, `Customer` bei Direktauftrag):
Bestehenden Kontakt → dessen `id` als CONTACT_ID merken. Sonst neu anlegen — Payload nach `/tmp/contact.json`; die **Verknüpfung zur Firma über `accountId` ist beim Neu-Anlegen zwingend**:
`id` aus der Antwort als CONTACT_ID merken. Namensaufteilung: letztes Token = `lastName`, der Rest = `firstName`; ungewöhnliche Fälle im Review klären.
**Anlegen:** Die Beschreibung enthält Markdown mit Zeilenumbrüchen und `|`. Um Shell-Escaping zu vermeiden, den Payload mit dem **Write-Tool** als JSON-Datei nach `/tmp/opp.json` schreiben:
{"name":"<EINDEUTIGER_NAME>","description":"<BESCHREIBUNG_MARKDOWN>","cProjektlink":"<PROJEKT_URL>","contactsIds":["<CONTACT_ID>"],"cAccount1Id":"<ACCOUNT_ID — nur bei Agentur, sonst Feld weglassen und stattdessen accountId setzen>"}
```
```
Dann posten (`-i` zeigt die Header inkl. `X-Status-Reason` bei Fehlern):
```bash
```bash
curl -s -i -X POST "$BASE/Opportunity" -H "X-Api-Key: $KEY"\
Der minimale Payload (`name`, `description`, `cProjektlink`) reicht — Stage und Wahrscheinlichkeit setzt das CRM selbst. Bei HTTP 400 steht die Ursache im `X-Status-Reason`-Header. Nachträgliche Korrekturen: `PUT "$BASE/Opportunity/<id>"` mit den geänderten Feldern. Danach `/tmp/opp.json` löschen.
Minimaler Payload genügt (Stage/Wahrscheinlichkeit setzt das CRM). Bei HTTP 400 steht die Ursache im `X-Status-Reason`-Header. Nachträgliche Korrekturen: `PUT "$BASE/Opportunity/<id>"`. Danach `/tmp/account.json /tmp/contact.json /tmp/opp.json` löschen.
## Schritt 8: Verifizieren und berichten
## Schritt 8: Verifizieren und berichten
@@ -142,4 +228,4 @@ Nach dem POST den Datensatz gegenlesen:
Prüfen: stimmen Name und Projektlink, hat die Beschreibung die Match-Zeile und alle Tabellenzeilen, sind ✅/❌/❔ intakt. Dann im Chat melden: gewählter Name (inkl. evtl. Duplikat-Suffix), beide Match-Zahlen und der Direktlink `https://crm.creature-go.com/#Opportunity/view/<id>`.
Prüfen: stimmen Name und Projektlink, hat die Beschreibung die Match-Zeile und alle Tabellenzeilen, sind ✅/❌/❔ intakt; sind die Verknüpfungen korrekt — Agentur: `cAccount1Name` gesetzt und `accountName` leer; Direktauftrag: `accountName` gesetzt; `contactsIds`/`contactId` enthält den Kontakt. Dann im Chat melden: gewählter Name (inkl. evtl. Duplikat-Suffix), beide Match-Zahlen, Firma und Kontakt (jeweils neu/bestehend) und der Direktlink `https://crm.creature-go.com/#Opportunity/view/<id>`.
-`vorgaben/` — feste Quellen: `Lebenslauf_Dr-Ing_Thomas_Langer.md`, `marketing.md`. Referenz; nicht ohne Auftrag ändern.
-`vorgaben/` — feste Quellen: `Lebenslauf_Dr-Ing_Thomas_Langer.md`, `marketing.md`, `rahmenbedingungen.md` (Misc-Kriterien für `projekt-anlegen`). Referenz; nicht ohne Auftrag ändern.
-`bewerbungen/` — je Bewerbung ein Ordner; `bewerbungen/index.md` ist das zentrale Register.
-`bewerbungen/` — je Bewerbung ein Ordner; `bewerbungen/index.md` ist das zentrale Register.
| Einsatzort / Remote | 100 % Remote oder Onsite ≤ 50 km um Sauerlach | siehe Einsatzort-Regel |
## Einsatzort-Regel
- 100 % Remote → ✅ (Ort egal).
- Onsite/Hybrid, Ort ≤ 50 km Luftlinie um Sauerlach → ✅.
- Onsite/Hybrid, Ort 50–60 km (grenzwertig) → ❔.
- Onsite/Hybrid, Ort > 60 km → ❌.
- Einsatzort/Remote-Anteil unklar oder nicht genannt → ❌.
Distanz = Luftlinie zwischen Onsite-Ort und Sauerlach (47,9721 N / 11,6528 O),
bestimmt per Geokodierung (Nominatim/OpenStreetMap, nur Deutschland) und Haversine.
Unbekannter/mehrdeutiger Ort → ❔.
Hinweis: „heute" = aktuelles Datum der Session. „8 Wochen" = 56 Tage.
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.