Dokumentation: docs/09-anleitung-entwickler.md
This commit is contained in:
@@ -0,0 +1,126 @@
|
|||||||
|
# 09 Anleitung für Entwickler
|
||||||
|
|
||||||
|
## Einrichten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
cd server && npm install && cp .env.example .env # Werte anpassen
|
||||||
|
npm start # Backend :5007
|
||||||
|
cd .. && npm run dev # Frontend :3101, /api wird geproxied
|
||||||
|
```
|
||||||
|
|
||||||
|
Lokal braucht es eine erreichbare MariaDB mit der Datenbank `icon_CRM`; das
|
||||||
|
Schema legt das Backend beim Start selbst an.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tsc --noEmit # Typprüfung, laeuft nicht automatisch im Build
|
||||||
|
npm run build # dist/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Aufbau
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
App.tsx Layout, gemeinsame Daten, Ansichtswechsel
|
||||||
|
main.tsx Provider-Kette
|
||||||
|
types.ts Gemeinsame Typen und Konstanten
|
||||||
|
index.css Tailwind-Theme, Designs, Dunkelmodus
|
||||||
|
lib/api.ts Fetch-Wrapper + typisierte Endpunkte
|
||||||
|
lib/auth.tsx JWT im localStorage
|
||||||
|
lib/theme.tsx Design und hell/dunkel
|
||||||
|
lib/navigation.tsx Karte oeffnen, Einstellungen-Reiter ansteuern
|
||||||
|
lib/options.tsx Auswahllisten aus den Stammdaten
|
||||||
|
lib/mentions.tsx @-Token: Parser, Renderer, Vorschlagsliste
|
||||||
|
lib/richText.ts Altbestand in Editor-HTML, Bereinigung
|
||||||
|
lib/imageCompress.ts Bilder vor dem Upload verkleinern
|
||||||
|
lib/whisper*.ts(x), dictation.tsx, audio.ts Diktat
|
||||||
|
components/… nach Bereichen
|
||||||
|
server/
|
||||||
|
src/server.js Express-App, Routenmontage
|
||||||
|
src/db.js Pool, Schema-Init, Migrationen, Admin-Seed
|
||||||
|
src/schema.sql Idempotentes Schema
|
||||||
|
src/history.js Historie schreiben, Erwaehnungen indizieren
|
||||||
|
src/ai.js OpenAI-Aufruf an einer Stelle
|
||||||
|
src/cvText.js Text aus PDF/DOCX
|
||||||
|
src/migrate.js Einmalige Uebernahme aus Supabase
|
||||||
|
src/linkedinPhoto.js Profilfoto aus der Open-Graph-Vorschau
|
||||||
|
src/middleware/auth.js requireAuth, requireAdmin
|
||||||
|
src/routes/ ein Router je Bereich
|
||||||
|
deploy/ systemd-Unit, Apache-Vhost, deploy.ps1
|
||||||
|
legacy/ der alte Supabase-Stand, nur zum Nachschlagen
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ein neues Feld hinzufügen
|
||||||
|
|
||||||
|
Am Beispiel eines Kontaktfelds – die Reihenfolge ist wichtig, sonst fehlt das
|
||||||
|
Feld an einer Stelle und fällt erst im Betrieb auf:
|
||||||
|
|
||||||
|
1. **Schema:** Spalte in `server/src/schema.sql` ergänzen **und** eine Migration
|
||||||
|
in `server/src/db.js` (`ALTER TABLE … ADD COLUMN IF NOT EXISTS`) – der
|
||||||
|
Bestand auf dem Server wird nicht neu angelegt.
|
||||||
|
2. **Route:** Feld in `server/src/routes/contacts.js` in die Liste der erlaubten
|
||||||
|
Felder aufnehmen (Lesen **und** Schreiben) und in der Aufbereitung der Zeile
|
||||||
|
berücksichtigen.
|
||||||
|
3. **Historie:** Klarnamen in `server/src/history.js` eintragen, sonst steht in
|
||||||
|
der Historie der Spaltenname.
|
||||||
|
4. **Typ:** `src/types.ts`.
|
||||||
|
5. **Formular:** `src/components/contacts/ContactModal.tsx`.
|
||||||
|
6. **Anzeige:** Liste, Kacheln, ggf. `contactUi.tsx`.
|
||||||
|
7. **Erweiterte Suche:** wenn das Feld für Fragen taugt, in den Bestand in
|
||||||
|
`server/src/routes/search.js` aufnehmen – und im Systemprompt erklären, was
|
||||||
|
`null` bedeutet.
|
||||||
|
|
||||||
|
Schritt 7 ist der, der am leichtesten vergessen wird. Die Sätze standen ein
|
||||||
|
halbes Jahr in der Datenbank und fehlten trotzdem in jeder Antwort der Suche,
|
||||||
|
weil sie nicht im mitgelieferten Bestand standen.
|
||||||
|
|
||||||
|
## Eine neue Ansicht hinzufügen
|
||||||
|
|
||||||
|
1. `View` in `src/types.ts` erweitern.
|
||||||
|
2. Eintrag in `src/components/Sidebar.tsx` (optional mit `children` für ein
|
||||||
|
Untermenü und `badge` für die Zahl daneben).
|
||||||
|
3. Block `{view === '…' && <… />}` in `src/App.tsx`.
|
||||||
|
4. Zählwert im Dashboard-Endpunkt ergänzen, falls ein Badge gewünscht ist.
|
||||||
|
|
||||||
|
Der Name der Ansicht ist zugleich ihr Schlüssel – wird er umbenannt (wie
|
||||||
|
„Projekte" → „Laufende Projekte"), müssen alle vier Stellen mitgehen, dazu die
|
||||||
|
Zuordnung in `navigation.open()` und der Filter in der Historie.
|
||||||
|
|
||||||
|
## Bekannte Fallen
|
||||||
|
|
||||||
|
**`gpt-5.6-luna` und `temperature`.** Jeder eigene Wert wird mit HTTP 400
|
||||||
|
abgewiesen. `ai.js` schickt keinen.
|
||||||
|
|
||||||
|
**Instabile Arrays in der Netzwerkansicht.** Ein `= []` als Vorgabewert erzeugt
|
||||||
|
bei jedem Rendern ein neues Array; `useMemo`/`useEffect` laufen dann endlos und
|
||||||
|
alle Knoten liegen auf einem Punkt. Deshalb `NO_EXTERNALS` auf Modulebene und
|
||||||
|
`useMemo` auf der Aufruferseite.
|
||||||
|
|
||||||
|
**Designs aus der Datenbank.** Wird eine Palette entfernt, tragen Benutzer sie
|
||||||
|
weiterhin am Konto. Drei Sicherungen greifen: das Backend liefert unbekannte
|
||||||
|
Werte als `null` aus, der Theme-Kontext prüft den Serverwert, und die Kopfzeile
|
||||||
|
fällt auf `icon` zurück. Ohne das reicht ein gelöschter Palettenname für eine
|
||||||
|
weiße Seite nach dem Anmelden.
|
||||||
|
|
||||||
|
**Altes HTML im Editor.** Der Bestand bringt Inline-Farben, geschützte
|
||||||
|
Leerzeichen und verschachtelte Listen mit. `toEditorHtml()` räumt zurückhaltend
|
||||||
|
auf, `index.css` hebt Inline-Farben im Editor aus. Wer beides umgeht, bekommt im
|
||||||
|
Dunkelmodus schwarze Schrift auf weißen Kästen und Zeilen, die nicht umbrechen.
|
||||||
|
|
||||||
|
**`notes` vs. `details` bei Ausschreibungen.** Der veröffentlichte Text steht in
|
||||||
|
`notes`. `details` ist im gesamten Bestand leer.
|
||||||
|
|
||||||
|
**Deployment ohne Build.** `-SkipBuild` lädt das vorhandene `dist/` hoch. Nach
|
||||||
|
einer Änderung an `src/` oder `index.html` also erst bauen.
|
||||||
|
|
||||||
|
**Kein automatischer Typcheck im Build.** `vite build` prüft die Typen nicht.
|
||||||
|
`npx tsc --noEmit` gehört vor jedes Deployment.
|
||||||
|
|
||||||
|
## Stil
|
||||||
|
|
||||||
|
Die Kommentare in diesem Projekt erklären **warum**, nicht was. Eine Zeile, die
|
||||||
|
nur wiederholt, was der Code sagt, ist eine Zeile zu viel; eine Zeile, die eine
|
||||||
|
Entscheidung begründet, erspart der nächsten Person eine Stunde.
|
||||||
|
|
||||||
|
Beschriftungen und Meldungen sind auf Deutsch, ohne Fachjargon, und sagen im
|
||||||
|
Zweifel, was zu tun ist – nicht nur, dass etwas fehlgeschlagen ist.
|
||||||
Reference in New Issue
Block a user