Anmeldung gilt 7 Tage statt 12 Stunden
JWT-Laufzeit (JWT_EXPIRES_IN) standardmaessig auf 7d gesetzt, damit Benutzer nicht mehr taeglich neu anmelden muessen. Doku (Betrieb, Benutzeranleitung, Glossar) und .env.example angepasst. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+159
-159
@@ -1,159 +1,159 @@
|
|||||||
# 07 Betrieb
|
# 07 Betrieb
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
Gebaut wird **lokal**, auf den Server gehen nur `dist/` plus die Backend-Quellen.
|
Gebaut wird **lokal**, auf den Server gehen nur `dist/` plus die Backend-Quellen.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$env:ICON_CRM_SSH_PASSWORD = '…'
|
$env:ICON_CRM_SSH_PASSWORD = '…'
|
||||||
powershell -File deploy/deploy.ps1
|
powershell -File deploy/deploy.ps1
|
||||||
powershell -File deploy/deploy.ps1 -SkipBuild # ohne neuen Build
|
powershell -File deploy/deploy.ps1 -SkipBuild # ohne neuen Build
|
||||||
powershell -File deploy/deploy.ps1 -Deps # bei neuen Backend-Paketen
|
powershell -File deploy/deploy.ps1 -Deps # bei neuen Backend-Paketen
|
||||||
```
|
```
|
||||||
|
|
||||||
Das Skript (`deploy/deploy.ps1`) macht in dieser Reihenfolge:
|
Das Skript (`deploy/deploy.ps1`) macht in dieser Reihenfolge:
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart LR
|
flowchart LR
|
||||||
B["npm run build"] --> U1["pscp dist/"]
|
B["npm run build"] --> U1["pscp dist/"]
|
||||||
U1 --> U2["pscp server/src + package.json"]
|
U1 --> U2["pscp server/src + package.json"]
|
||||||
U2 --> R["systemctl restart icon-crm-backend"]
|
U2 --> R["systemctl restart icon-crm-backend"]
|
||||||
R --> C["curl /api/health"]
|
R --> C["curl /api/health"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Schlägt der Build fehl, wird **nichts** hochgeladen – sonst stünde auf dem
|
Schlägt der Build fehl, wird **nichts** hochgeladen – sonst stünde auf dem
|
||||||
Server ein halber Stand.
|
Server ein halber Stand.
|
||||||
|
|
||||||
> **Falle aus der Praxis:** Wer `index.html` von Hand ändert und dann mit
|
> **Falle aus der Praxis:** Wer `index.html` von Hand ändert und dann mit
|
||||||
> `-SkipBuild` hochlädt, spielt das alte `dist/` aus. Nach jeder Änderung an
|
> `-SkipBuild` hochlädt, spielt das alte `dist/` aus. Nach jeder Änderung an
|
||||||
> `src/` oder `index.html` gilt: erst bauen, dann hochladen.
|
> `src/` oder `index.html` gilt: erst bauen, dann hochladen.
|
||||||
|
|
||||||
Alte Build-Dateien werden beim Hochladen **nicht** entfernt – `dist/assets/`
|
Alte Build-Dateien werden beim Hochladen **nicht** entfernt – `dist/assets/`
|
||||||
wächst mit jeder Auslieferung. Das ist Absicht: ein Browser mit offenem Tab holt
|
wächst mit jeder Auslieferung. Das ist Absicht: ein Browser mit offenem Tab holt
|
||||||
sonst ein Bruchstück, das es nicht mehr gibt. Gelegentlich aufräumen schadet
|
sonst ein Bruchstück, das es nicht mehr gibt. Gelegentlich aufräumen schadet
|
||||||
trotzdem nicht.
|
trotzdem nicht.
|
||||||
|
|
||||||
## Dienste auf dem Server
|
## Dienste auf dem Server
|
||||||
|
|
||||||
| Was | Befehl |
|
| Was | Befehl |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Zustand | `systemctl status icon-crm-backend` |
|
| Zustand | `systemctl status icon-crm-backend` |
|
||||||
| Neustart | `systemctl restart icon-crm-backend` |
|
| Neustart | `systemctl restart icon-crm-backend` |
|
||||||
| Log | `journalctl -u icon-crm-backend -n 100 --no-pager` |
|
| Log | `journalctl -u icon-crm-backend -n 100 --no-pager` |
|
||||||
| Gesundheit | `curl -s http://127.0.0.1:5007/api/health` → `{"ok":true,"db":"up"}` |
|
| Gesundheit | `curl -s http://127.0.0.1:5007/api/health` → `{"ok":true,"db":"up"}` |
|
||||||
| Apache | `systemctl reload apache2`, Logs unter `/var/log/apache2/icon_crm_*.log` |
|
| Apache | `systemctl reload apache2`, Logs unter `/var/log/apache2/icon_crm_*.log` |
|
||||||
|
|
||||||
Die systemd-Unit begrenzt den Speicher auf 1 GB (`MemoryMax=1024M`). Das ist
|
Die systemd-Unit begrenzt den Speicher auf 1 GB (`MemoryMax=1024M`). Das ist
|
||||||
kein Sparzwang, sondern ein Sicherheitsnetz: ein Leck im Backend soll nicht
|
kein Sparzwang, sondern ein Sicherheitsnetz: ein Leck im Backend soll nicht
|
||||||
Apache und MariaDB mitreißen.
|
Apache und MariaDB mitreißen.
|
||||||
|
|
||||||
## Umgebungsvariablen
|
## Umgebungsvariablen
|
||||||
|
|
||||||
`server/.env`, chmod 600, gehört **nicht** ins Repository. Vorlage:
|
`server/.env`, chmod 600, gehört **nicht** ins Repository. Vorlage:
|
||||||
`server/.env.example`.
|
`server/.env.example`.
|
||||||
|
|
||||||
| Variable | Bedeutung |
|
| Variable | Bedeutung |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `PORT`, `HOST` | `5007` auf `127.0.0.1` – von außen nur über Apache |
|
| `PORT`, `HOST` | `5007` auf `127.0.0.1` – von außen nur über Apache |
|
||||||
| `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME` | MariaDB, Datenbank `icon_CRM` |
|
| `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME` | MariaDB, Datenbank `icon_CRM` |
|
||||||
| `JWT_SECRET`, `JWT_EXPIRES_IN` | Sitzungen, Vorgabe 12 h |
|
| `JWT_SECRET`, `JWT_EXPIRES_IN` | Sitzungen, Vorgabe 7 Tage (`7d`) |
|
||||||
| `ADMIN_USERNAME`, `ADMIN_NAME`, `ADMIN_EMAIL`, `ADMIN_PASSWORD` | erster Administrator, **nur solange `icon_users` leer ist** |
|
| `ADMIN_USERNAME`, `ADMIN_NAME`, `ADMIN_EMAIL`, `ADMIN_PASSWORD` | erster Administrator, **nur solange `icon_users` leer ist** |
|
||||||
| `CORS_ORIGINS` | erlaubte Herkunft für den lokalen Dev-Server |
|
| `CORS_ORIGINS` | erlaubte Herkunft für den lokalen Dev-Server |
|
||||||
| `UPLOAD_DIR` | Ablage der Lebensläufe |
|
| `UPLOAD_DIR` | Ablage der Lebensläufe |
|
||||||
| `OPENAI_API_KEY`, `OPENAI_MODEL` | KI; fehlt der Schlüssel, laufen die übrigen Teile weiter |
|
| `OPENAI_API_KEY`, `OPENAI_MODEL` | KI; fehlt der Schlüssel, laufen die übrigen Teile weiter |
|
||||||
| `PERINCO_API_URL`, `PERINCO_API_TOKEN` | ICON liest perinco |
|
| `PERINCO_API_URL`, `PERINCO_API_TOKEN` | ICON liest perinco |
|
||||||
| `PERINCO_INBOUND_TOKEN` | perinco liest ICON |
|
| `PERINCO_INBOUND_TOKEN` | perinco liest ICON |
|
||||||
|
|
||||||
Ohne `ADMIN_PASSWORD` erzeugt das Backend eines und schreibt es **einmalig** ins
|
Ohne `ADMIN_PASSWORD` erzeugt das Backend eines und schreibt es **einmalig** ins
|
||||||
Log. Danach ist das Passwort nur noch über die Nutzerverwaltung bzw. *Mein
|
Log. Danach ist das Passwort nur noch über die Nutzerverwaltung bzw. *Mein
|
||||||
Konto* änderbar.
|
Konto* änderbar.
|
||||||
|
|
||||||
## Erstaufsetzung (einmalig, bereits erledigt)
|
## Erstaufsetzung (einmalig, bereits erledigt)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
apt-get install -y apache2 mariadb-server certbot python3-certbot-apache nodejs
|
apt-get install -y apache2 mariadb-server certbot python3-certbot-apache nodejs
|
||||||
a2enmod proxy proxy_http rewrite headers expires
|
a2enmod proxy proxy_http rewrite headers expires
|
||||||
mariadb -e "CREATE DATABASE icon_CRM CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
mariadb -e "CREATE DATABASE icon_CRM CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||||
mariadb -e "CREATE USER 'iconcrm'@'localhost' IDENTIFIED BY '…';
|
mariadb -e "CREATE USER 'iconcrm'@'localhost' IDENTIFIED BY '…';
|
||||||
GRANT ALL PRIVILEGES ON icon_CRM.* TO 'iconcrm'@'localhost';"
|
GRANT ALL PRIVILEGES ON icon_CRM.* TO 'iconcrm'@'localhost';"
|
||||||
cd /var/www/icon_CRM/server && npm install --omit=dev
|
cd /var/www/icon_CRM/server && npm install --omit=dev
|
||||||
cp deploy/icon-crm-backend.service /etc/systemd/system/
|
cp deploy/icon-crm-backend.service /etc/systemd/system/
|
||||||
systemctl daemon-reload && systemctl enable --now icon-crm-backend
|
systemctl daemon-reload && systemctl enable --now icon-crm-backend
|
||||||
cp deploy/icrm.icon-experts.de.conf /etc/apache2/sites-available/
|
cp deploy/icrm.icon-experts.de.conf /etc/apache2/sites-available/
|
||||||
a2ensite icrm.icon-experts.de && systemctl reload apache2
|
a2ensite icrm.icon-experts.de && systemctl reload apache2
|
||||||
certbot --apache -d icrm.icon-experts.de
|
certbot --apache -d icrm.icon-experts.de
|
||||||
```
|
```
|
||||||
|
|
||||||
Das Schema legt das Backend beim Start selbst an (`schema.sql` +
|
Das Schema legt das Backend beim Start selbst an (`schema.sql` +
|
||||||
Migrationen in `db.js`). Die Firewall (`ufw`) lässt 22, 80 und 443 durch; das
|
Migrationen in `db.js`). Die Firewall (`ufw`) lässt 22, 80 und 443 durch; das
|
||||||
Zertifikat erneuert certbot selbst.
|
Zertifikat erneuert certbot selbst.
|
||||||
|
|
||||||
## Sicherung
|
## Sicherung
|
||||||
|
|
||||||
Der Bestand steht vollständig in MariaDB; hochgeladene Lebensläufe liegen unter
|
Der Bestand steht vollständig in MariaDB; hochgeladene Lebensläufe liegen unter
|
||||||
`/var/www/icon_CRM/uploads`. Beides gehört in die Sicherung:
|
`/var/www/icon_CRM/uploads`. Beides gehört in die Sicherung:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mariadb-dump --single-transaction icon_CRM | gzip > icon_CRM-$(date +%F).sql.gz
|
mariadb-dump --single-transaction icon_CRM | gzip > icon_CRM-$(date +%F).sql.gz
|
||||||
tar czf uploads-$(date +%F).tar.gz -C /var/www/icon_CRM uploads
|
tar czf uploads-$(date +%F).tar.gz -C /var/www/icon_CRM uploads
|
||||||
```
|
```
|
||||||
|
|
||||||
## Der alte Name crm.icon-experts.de
|
## Der alte Name crm.icon-experts.de
|
||||||
|
|
||||||
Das erste ICON CRM lief unter **crm.icon-experts.de** auf `212.227.135.41`
|
Das erste ICON CRM lief unter **crm.icon-experts.de** auf `212.227.135.41`
|
||||||
(`/var/www/ICON`, Supabase als Datenbank). Seit dem 14.09.2026 zeigt der Name
|
(`/var/www/ICON`, Supabase als Datenbank). Seit dem 14.09.2026 zeigt der Name
|
||||||
auf diesen Server und wird vom Vhost `icrm.icon-experts.de` als `ServerAlias`
|
auf diesen Server und wird vom Vhost `icrm.icon-experts.de` als `ServerAlias`
|
||||||
mitbedient – dasselbe Zertifikat deckt beide Namen ab. Verschickte Links und
|
mitbedient – dasselbe Zertifikat deckt beide Namen ab. Verschickte Links und
|
||||||
Lesezeichen laufen damit weiter, es gibt keinen zweiten Stand zu pflegen.
|
Lesezeichen laufen damit weiter, es gibt keinen zweiten Stand zu pflegen.
|
||||||
|
|
||||||
Der alte Aufbau ist zurückgebaut: Vhosts (`icon`, `icon-le-ssl`) abgeschaltet,
|
Der alte Aufbau ist zurückgebaut: Vhosts (`icon`, `icon-le-ssl`) abgeschaltet,
|
||||||
`/var/www/ICON` gelöscht, das dortige Zertifikat für `crm.icon-experts.de`
|
`/var/www/ICON` gelöscht, das dortige Zertifikat für `crm.icon-experts.de`
|
||||||
entfernt (sonst hätte die Erneuerung ab sofort täglich Fehler gemeldet).
|
entfernt (sonst hätte die Erneuerung ab sofort täglich Fehler gemeldet).
|
||||||
|
|
||||||
Gesichert ist er als `icon-crm-alt-2026-09-14.zip` – Quellcode, Build, `.env`
|
Gesichert ist er als `icon-crm-alt-2026-09-14.zip` – Quellcode, Build, `.env`
|
||||||
und beide Vhost-Dateien, ohne `node_modules`. Die Datei liegt **auf beiden
|
und beide Vhost-Dateien, ohne `node_modules`. Die Datei liegt **auf beiden
|
||||||
Servern** unter `/root/backups/`, Prüfsumme
|
Servern** unter `/root/backups/`, Prüfsumme
|
||||||
`252f7fa3226c2df7c4020a0234c3095c`.
|
`252f7fa3226c2df7c4020a0234c3095c`.
|
||||||
|
|
||||||
> Die Supabase-Instanz `icondb.perinco.de` läuft weiter. Sie war die Datenbank
|
> Die Supabase-Instanz `icondb.perinco.de` läuft weiter. Sie war die Datenbank
|
||||||
> des alten CRM und ist die Quelle der Migration (`server/src/migrate.js`) –
|
> des alten CRM und ist die Quelle der Migration (`server/src/migrate.js`) –
|
||||||
> abzuschalten wäre eine eigene Entscheidung, nicht Teil dieses Rückbaus.
|
> abzuschalten wäre eine eigene Entscheidung, nicht Teil dieses Rückbaus.
|
||||||
|
|
||||||
## Störungssuche
|
## Störungssuche
|
||||||
|
|
||||||
| Symptom | Erster Griff |
|
| Symptom | Erster Griff |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Weiße Seite nach dem Rollout | `index.html` darf nicht aus dem Cache kommen – der Vhost setzt dafür `no-cache`; im Zweifel Strg+F5 |
|
| Weiße Seite nach dem Rollout | `index.html` darf nicht aus dem Cache kommen – der Vhost setzt dafür `no-cache`; im Zweifel Strg+F5 |
|
||||||
| 502 auf `/api` | Backend aus: `systemctl status icon-crm-backend`, dann `journalctl -u …` |
|
| 502 auf `/api` | Backend aus: `systemctl status icon-crm-backend`, dann `journalctl -u …` |
|
||||||
| `{"db":"down"}` | MariaDB aus oder Zugangsdaten falsch |
|
| `{"db":"down"}` | MariaDB aus oder Zugangsdaten falsch |
|
||||||
| Anmeldung schlägt fehl | `icon_users` prüfen: existiert der Benutzer, ist `is_active = 1`? |
|
| Anmeldung schlägt fehl | `icon_users` prüfen: existiert der Benutzer, ist `is_active = 1`? |
|
||||||
| Zertifikatswarnung | `certbot certificates`; deckt das Zertifikat **alle** Namen ab, auch `www`? |
|
| Zertifikatswarnung | `certbot certificates`; deckt das Zertifikat **alle** Namen ab, auch `www`? |
|
||||||
| Website zeigt alte Ausschreibungen | `curl -s https://icon-experts.de/api/public/tenders | head` – kommt das durch den Proxy? |
|
| Website zeigt alte Ausschreibungen | `curl -s https://icon-experts.de/api/public/tenders | head` – kommt das durch den Proxy? |
|
||||||
| perinco-Kontakte fehlen | `GET /api/perinco/status`; Token beidseitig gesetzt? |
|
| perinco-Kontakte fehlen | `GET /api/perinco/status`; Token beidseitig gesetzt? |
|
||||||
| Diktat lädt nicht | siehe [04 Diktat](04-diktat.md) – das ist eine Sache des Browsers, nicht des Servers |
|
| Diktat lädt nicht | siehe [04 Diktat](04-diktat.md) – das ist eine Sache des Browsers, nicht des Servers |
|
||||||
|
|
||||||
### Wenn Daten zu fehlen scheinen
|
### Wenn Daten zu fehlen scheinen
|
||||||
|
|
||||||
Erst messen, dann handeln. Die drei Griffe, die in der Praxis geholfen haben:
|
Erst messen, dann handeln. Die drei Griffe, die in der Praxis geholfen haben:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mysql icon_CRM -e "SELECT COUNT(*) FROM icon_contacts" # steht es in der Datenbank?
|
mysql icon_CRM -e "SELECT COUNT(*) FROM icon_contacts" # steht es in der Datenbank?
|
||||||
curl -s .../api/contacts -H "Authorization: Bearer …" | wc -c # liefert die API es aus?
|
curl -s .../api/contacts -H "Authorization: Bearer …" | wc -c # liefert die API es aus?
|
||||||
tail -n 50 /var/log/apache2/icon_crm_access.log # kam es beim Browser an?
|
tail -n 50 /var/log/apache2/icon_crm_access.log # kam es beim Browser an?
|
||||||
```
|
```
|
||||||
|
|
||||||
Stimmen alle drei, liegt es an der Ansicht – meist an einem aktiven Filter.
|
Stimmen alle drei, liegt es an der Ansicht – meist an einem aktiven Filter.
|
||||||
|
|
||||||
### DNS-Umstellungen
|
### DNS-Umstellungen
|
||||||
|
|
||||||
Nach einem Wechsel des A-Records antworten fremde Resolver unterschiedlich
|
Nach einem Wechsel des A-Records antworten fremde Resolver unterschiedlich
|
||||||
lange mit der alten Adresse. Zum Prüfen die **autoritativen** Nameserver und
|
lange mit der alten Adresse. Zum Prüfen die **autoritativen** Nameserver und
|
||||||
mindestens einen öffentlichen Resolver befragen, nicht nur den eigenen:
|
mindestens einen öffentlichen Resolver befragen, nicht nur den eigenen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dig +short icon-experts.de @1.1.1.1
|
dig +short icon-experts.de @1.1.1.1
|
||||||
dig +short icon-experts.de @8.8.8.8
|
dig +short icon-experts.de @8.8.8.8
|
||||||
```
|
```
|
||||||
|
|
||||||
Ein lokaler Resolver (PiHole, Router) kann den alten Wert deutlich länger
|
Ein lokaler Resolver (PiHole, Router) kann den alten Wert deutlich länger
|
||||||
halten – das sieht dann aus wie ein Serverfehler und ist keiner.
|
halten – das sieht dann aus wie ein Serverfehler und ist keiner.
|
||||||
|
|||||||
+224
-224
@@ -1,224 +1,224 @@
|
|||||||
# 08 Anleitung für Benutzer
|
# 08 Anleitung für Benutzer
|
||||||
|
|
||||||
Diese Anleitung setzt nichts voraus. Adresse: <https://icrm.icon-experts.de>.
|
Diese Anleitung setzt nichts voraus. Adresse: <https://icrm.icon-experts.de>.
|
||||||
|
|
||||||
## Anmelden
|
## Anmelden
|
||||||
|
|
||||||
Benutzername oder E-Mail und Passwort. Die Anmeldung gilt 12 Stunden; danach
|
Benutzername oder E-Mail und Passwort. Die Anmeldung gilt 7 Tage; danach
|
||||||
fragt das CRM erneut. Passwort ändern: *Einstellungen → Mein Konto*.
|
fragt das CRM erneut. Passwort ändern: *Einstellungen → Mein Konto*.
|
||||||
|
|
||||||
Rechts oben stehen zwei Umschalter: die **Farbwelt** (ICON, Half-Life, Pixel
|
Rechts oben stehen zwei Umschalter: die **Farbwelt** (ICON, Half-Life, Pixel
|
||||||
Art) und **hell/dunkel**. Beides hängt am Konto und gilt auf jedem Gerät. Ein
|
Art) und **hell/dunkel**. Beides hängt am Konto und gilt auf jedem Gerät. Ein
|
||||||
Doppelklick auf den Hell/Dunkel-Knopf stellt „wie das System" wieder her.
|
Doppelklick auf den Hell/Dunkel-Knopf stellt „wie das System" wieder her.
|
||||||
|
|
||||||
## Suchen
|
## Suchen
|
||||||
|
|
||||||
Oben in der Kopfleiste, oder mit `Strg+K`. Rechts im Feld zwei Symbole:
|
Oben in der Kopfleiste, oder mit `Strg+K`. Rechts im Feld zwei Symbole:
|
||||||
|
|
||||||
* **Lupe** – die normale Suche. Läuft beim Tippen mit, durchsucht Kontakte,
|
* **Lupe** – die normale Suche. Läuft beim Tippen mit, durchsucht Kontakte,
|
||||||
Unternehmen, Ausschreibungen, Projekte, Leads und die Historie. Ein Klick auf
|
Unternehmen, Ausschreibungen, Projekte, Leads und die Historie. Ein Klick auf
|
||||||
einen Treffer öffnet dessen Karte.
|
einen Treffer öffnet dessen Karte.
|
||||||
* **Funke** – die erweiterte Suche. Hier steht eine ganze Frage:
|
* **Funke** – die erweiterte Suche. Hier steht eine ganze Frage:
|
||||||
*„Wer arbeitet alles bei der KfW?"*, *„Wer hat den höchsten Satz?"*. Antwort
|
*„Wer arbeitet alles bei der KfW?"*, *„Wer hat den höchsten Satz?"*. Antwort
|
||||||
auf Enter, nicht beim Tippen. Die genannten Datensätze stehen darunter als
|
auf Enter, nicht beim Tippen. Die genannten Datensätze stehen darunter als
|
||||||
anklickbare Schaltflächen.
|
anklickbare Schaltflächen.
|
||||||
|
|
||||||
## Dashboard
|
## Dashboard
|
||||||
|
|
||||||
Zahlen zum Bestand und die letzten Tätigkeiten. Von hier führt jeder Eintrag in
|
Zahlen zum Bestand und die letzten Tätigkeiten. Von hier führt jeder Eintrag in
|
||||||
die zugehörige Karte.
|
die zugehörige Karte.
|
||||||
|
|
||||||
## Leads
|
## Leads
|
||||||
|
|
||||||
Die Pipeline als Kanban über acht Spalten, von **Backlog** bis **Absage**.
|
Die Pipeline als Kanban über acht Spalten, von **Backlog** bis **Absage**.
|
||||||
Kacheln lassen sich mit der Maus in eine andere Spalte ziehen; der Wechsel landet
|
Kacheln lassen sich mit der Maus in eine andere Spalte ziehen; der Wechsel landet
|
||||||
in der Historie.
|
in der Historie.
|
||||||
|
|
||||||
Auf jeder Kachel:
|
Auf jeder Kachel:
|
||||||
|
|
||||||
| Zeichen | Bedeutung |
|
| Zeichen | Bedeutung |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Aktenschrank | archivieren – landet unter *Leads → Archiviert* und lässt sich von dort zurückholen |
|
| Aktenschrank | archivieren – landet unter *Leads → Archiviert* und lässt sich von dort zurückholen |
|
||||||
| roter Mülleimer | löschen, mit Rückfrage |
|
| roter Mülleimer | löschen, mit Rückfrage |
|
||||||
| Balken mit Prozentzahl | Stand der ToDo-Liste |
|
| Balken mit Prozentzahl | Stand der ToDo-Liste |
|
||||||
|
|
||||||
Die Karte eines Leads hat drei Reiter:
|
Die Karte eines Leads hat drei Reiter:
|
||||||
|
|
||||||
1. **Stammdaten** – Titel, Unternehmen, Ansprechpartner, Kontaktstand,
|
1. **Stammdaten** – Titel, Unternehmen, Ansprechpartner, Kontaktstand,
|
||||||
Zuständiger, Notizen und die Erinnerung.
|
Zuständiger, Notizen und die Erinnerung.
|
||||||
2. **ToDos** – Checkliste mit Fälligkeitsdatum. Der Fortschritt steht als
|
2. **ToDos** – Checkliste mit Fälligkeitsdatum. Der Fortschritt steht als
|
||||||
Prozentwert auf der Kachel.
|
Prozentwert auf der Kachel.
|
||||||
3. **Historie** – wer wann was geändert hat.
|
3. **Historie** – wer wann was geändert hat.
|
||||||
|
|
||||||
### Erinnerungen
|
### Erinnerungen
|
||||||
|
|
||||||
Zwei Arten, beide als Pop-up, das sich unabhängig von der geöffneten Ansicht
|
Zwei Arten, beide als Pop-up, das sich unabhängig von der geöffneten Ansicht
|
||||||
meldet:
|
meldet:
|
||||||
|
|
||||||
* **gesetzt** – „in 2 Tagen anrufen". Eingegeben werden **Tage**, nicht ein
|
* **gesetzt** – „in 2 Tagen anrufen". Eingegeben werden **Tage**, nicht ein
|
||||||
Datum; gerechnet wird auf dem Server. Quittieren heißt *Erledigt* oder *in n
|
Datum; gerechnet wird auf dem Server. Quittieren heißt *Erledigt* oder *in n
|
||||||
Tagen erneut*.
|
Tagen erneut*.
|
||||||
* **automatisch** – wird ein Lead 30 Tage nicht angefasst, fragt das CRM, ob er
|
* **automatisch** – wird ein Lead 30 Tage nicht angefasst, fragt das CRM, ob er
|
||||||
archiviert werden soll. Bleibt er stehen, läuft die Frist von vorn.
|
archiviert werden soll. Bleibt er stehen, läuft die Frist von vorn.
|
||||||
|
|
||||||
## Kontakte
|
## Kontakte
|
||||||
|
|
||||||
Drei Ansichten, oben rechts umschaltbar: **Kacheln**, **Liste**, **Netzwerk**.
|
Drei Ansichten, oben rechts umschaltbar: **Kacheln**, **Liste**, **Netzwerk**.
|
||||||
|
|
||||||
* In der **Liste** sortiert ein Klick auf eine Spaltenüberschrift; ein zweiter
|
* In der **Liste** sortiert ein Klick auf eine Spaltenüberschrift; ein zweiter
|
||||||
Klick dreht die Richtung um. Leere Felder stehen immer am Ende.
|
Klick dreht die Richtung um. Leere Felder stehen immer am Ende.
|
||||||
* Der Schalter **perinco** blendet zusätzlich die Kontakte des perinco CRM ein –
|
* Der Schalter **perinco** blendet zusätzlich die Kontakte des perinco CRM ein –
|
||||||
grün umrandet, nur zum Lesen.
|
grün umrandet, nur zum Lesen.
|
||||||
* Filter (Art, Status, Unternehmen …) sind sichtbar ausgezeichnet. Steht die
|
* Filter (Art, Status, Unternehmen …) sind sichtbar ausgezeichnet. Steht die
|
||||||
Liste leer da, sagt der Text welche Filter aktiv sind; daneben liegt *Filter
|
Liste leer da, sagt der Text welche Filter aktiv sind; daneben liegt *Filter
|
||||||
zurücksetzen*.
|
zurücksetzen*.
|
||||||
|
|
||||||
Die Karte eines Kontakts hat Stammdaten, Werdegang, Gespräche und Historie.
|
Die Karte eines Kontakts hat Stammdaten, Werdegang, Gespräche und Historie.
|
||||||
|
|
||||||
Im Reiter **Werdegang & Interviews** lässt sich jede Station bearbeiten:
|
Im Reiter **Werdegang & Interviews** lässt sich jede Station bearbeiten:
|
||||||
*Station hinzufügen*, der Stift ändert eine bestehende, der Mülleimer entfernt
|
*Station hinzufügen*, der Stift ändert eine bestehende, der Mülleimer entfernt
|
||||||
sie. Das Unternehmen ist ein Textfeld mit Vorschlagsliste – ein Name, den es
|
sie. Das Unternehmen ist ein Textfeld mit Vorschlagsliste – ein Name, den es
|
||||||
noch nicht gibt, legt das Unternehmen an (wie im CV-Import).
|
noch nicht gibt, legt das Unternehmen an (wie im CV-Import).
|
||||||
|
|
||||||
Der Haken **aktuelle Station** hängt mit dem Arbeitgeber im Reiter Stammdaten
|
Der Haken **aktuelle Station** hängt mit dem Arbeitgeber im Reiter Stammdaten
|
||||||
zusammen: es kann immer nur eine Station laufen. Wird eine dazu erklärt, bekommt
|
zusammen: es kann immer nur eine Station laufen. Wird eine dazu erklärt, bekommt
|
||||||
die bisherige ein Enddatum, und der Arbeitgeber des Kontakts wechselt mit. Wird
|
die bisherige ein Enddatum, und der Arbeitgeber des Kontakts wechselt mit. Wird
|
||||||
die laufende Station gelöscht, hat der Kontakt danach keinen Arbeitgeber mehr –
|
die laufende Station gelöscht, hat der Kontakt danach keinen Arbeitgeber mehr –
|
||||||
die Rückfrage sagt das.
|
die Rückfrage sagt das.
|
||||||
|
|
||||||
| Feld | Hinweis |
|
| Feld | Hinweis |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Art | Experte, Ansprechpartner, Lead – die Liste wird in den Stammdaten gepflegt |
|
| Art | Experte, Ansprechpartner, Lead – die Liste wird in den Stammdaten gepflegt |
|
||||||
| Status | Interessiert, Interview, Gebucht, Inaktiv |
|
| Status | Interessiert, Interview, Gebucht, Inaktiv |
|
||||||
| Stundensatz vor Ort / remote | in **Euro je Stunde**; leer heißt „nicht hinterlegt", nicht „null Euro" |
|
| Stundensatz vor Ort / remote | in **Euro je Stunde**; leer heißt „nicht hinterlegt", nicht „null Euro" |
|
||||||
| Foto | hochladen oder mit *Von LinkedIn* aus dem öffentlichen Profil holen |
|
| Foto | hochladen oder mit *Von LinkedIn* aus dem öffentlichen Profil holen |
|
||||||
| CV | Link oder die hochgeladene Datei aus dem CV-Import |
|
| CV | Link oder die hochgeladene Datei aus dem CV-Import |
|
||||||
|
|
||||||
### CV-Import
|
### CV-Import
|
||||||
|
|
||||||
*Kontakte → CV-Import.* Lebensläufe hineinziehen (PDF, DOCX, Text; bis 20 auf
|
*Kontakte → CV-Import.* Lebensläufe hineinziehen (PDF, DOCX, Text; bis 20 auf
|
||||||
einmal). Danach drei Ordner:
|
einmal). Danach drei Ordner:
|
||||||
|
|
||||||
1. **Eingang** – je Datei entscheiden: *Ja, auslesen* oder *Nein*.
|
1. **Eingang** – je Datei entscheiden: *Ja, auslesen* oder *Nein*.
|
||||||
2. **Screening** – der Vorschlag der KI steht im Formular. Alles ist änderbar;
|
2. **Screening** – der Vorschlag der KI steht im Formular. Alles ist änderbar;
|
||||||
was hier korrigiert wird, gewinnt.
|
was hier korrigiert wird, gewinnt.
|
||||||
3. **Auswahl** – bestätigt, Kontakt angelegt, Lebenslauf hängt daran.
|
3. **Auswahl** – bestätigt, Kontakt angelegt, Lebenslauf hängt daran.
|
||||||
|
|
||||||
Trägt der Lebenslauf ein **Bewerbungsfoto**, steht es oben im Formular, mit
|
Trägt der Lebenslauf ein **Bewerbungsfoto**, steht es oben im Formular, mit
|
||||||
gesetztem Haken. Es wird auf 400 px verkleinert (höchstens 512 kB) und beim
|
gesetztem Haken. Es wird auf 400 px verkleinert (höchstens 512 kB) und beim
|
||||||
Übernehmen als Foto des Kontakts gespeichert. Hat der Automat statt des
|
Übernehmen als Foto des Kontakts gespeichert. Hat der Automat statt des
|
||||||
Portraits das Firmenlogo erwischt, Haken entfernen – ein anderes Bild lässt sich
|
Portraits das Firmenlogo erwischt, Haken entfernen – ein anderes Bild lässt sich
|
||||||
jederzeit in der Kontaktkarte setzen.
|
jederzeit in der Kontaktkarte setzen.
|
||||||
|
|
||||||
Es wird **nichts automatisch angelegt**. Frühere Stationen werden als beendete
|
Es wird **nichts automatisch angelegt**. Frühere Stationen werden als beendete
|
||||||
Anstellungen übernommen – der Kontakt erscheint dadurch beim alten Arbeitgeber
|
Anstellungen übernommen – der Kontakt erscheint dadurch beim alten Arbeitgeber
|
||||||
sofort unter „Ehemalige".
|
sofort unter „Ehemalige".
|
||||||
|
|
||||||
## Unternehmen
|
## Unternehmen
|
||||||
|
|
||||||
Ebenfalls Kacheln, Liste und Netzwerk, dazu der Reiter **Group** (Konzern).
|
Ebenfalls Kacheln, Liste und Netzwerk, dazu der Reiter **Group** (Konzern).
|
||||||
Ein Unternehmen mit gesetztem Haken *Kunde* erscheint zusätzlich in der
|
Ein Unternehmen mit gesetztem Haken *Kunde* erscheint zusätzlich in der
|
||||||
Kundenansicht; der Zustand *aktiv* oder *alumni* unterscheidet laufende von
|
Kundenansicht; der Zustand *aktiv* oder *alumni* unterscheidet laufende von
|
||||||
früheren Kunden.
|
früheren Kunden.
|
||||||
|
|
||||||
Fünf Sterne bewerten das Unternehmen, `Freelancer` sagt, ob dort überhaupt
|
Fünf Sterne bewerten das Unternehmen, `Freelancer` sagt, ob dort überhaupt
|
||||||
freiberuflich gearbeitet wird.
|
freiberuflich gearbeitet wird.
|
||||||
|
|
||||||
### Netzwerkansicht und Stammbaum
|
### Netzwerkansicht und Stammbaum
|
||||||
|
|
||||||
Rechtecke sind Unternehmen, Kreise sind Kontakte. Ziehen verschiebt, das Mausrad
|
Rechtecke sind Unternehmen, Kreise sind Kontakte. Ziehen verschiebt, das Mausrad
|
||||||
zoomt. Ein Klick auf ein Unternehmen mit Kontakten öffnet dessen **Stammbaum**:
|
zoomt. Ein Klick auf ein Unternehmen mit Kontakten öffnet dessen **Stammbaum**:
|
||||||
|
|
||||||
| Ast | Bedeutung |
|
| Ast | Bedeutung |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| golden | Berater (Art „Experte") |
|
| golden | Berater (Art „Experte") |
|
||||||
| hell | Ansprechpartner und übrige |
|
| hell | Ansprechpartner und übrige |
|
||||||
| grau, gestrichelt | Ehemalige – darunter steht, wo die Person heute ist |
|
| grau, gestrichelt | Ehemalige – darunter steht, wo die Person heute ist |
|
||||||
|
|
||||||
In den Kontakten lassen sich zusätzlich Verbindungen anlegen: *Verbindung
|
In den Kontakten lassen sich zusätzlich Verbindungen anlegen: *Verbindung
|
||||||
erstellen*, dann zwei Kontakte anklicken; Esc bricht ab.
|
erstellen*, dann zwei Kontakte anklicken; Esc bricht ab.
|
||||||
|
|
||||||
## Ausschreibungen
|
## Ausschreibungen
|
||||||
|
|
||||||
Eine Tabelle; ein Klick klappt die Zeile auf. Links die zugewiesenen Experten
|
Eine Tabelle; ein Klick klappt die Zeile auf. Links die zugewiesenen Experten
|
||||||
und der Kundenkontakt, rechts der **Ausschreibungstext**.
|
und der Kundenkontakt, rechts der **Ausschreibungstext**.
|
||||||
|
|
||||||
> **Der Schalter „Online" entscheidet, ob die Ausschreibung auf der ICON Website
|
> **Der Schalter „Online" entscheidet, ob die Ausschreibung auf der ICON Website
|
||||||
> in der Projektbörse steht.** Er sitzt deshalb direkt in der Liste.
|
> in der Projektbörse steht.** Er sitzt deshalb direkt in der Liste.
|
||||||
|
|
||||||
Der Text wird automatisch gespeichert, 800 ms nach dem letzten Tastendruck – es
|
Der Text wird automatisch gespeichert, 800 ms nach dem letzten Tastendruck – es
|
||||||
gibt keinen Speichern-Knopf. Über dem Feld liegen die Knöpfe der Schreibhilfe
|
gibt keinen Speichern-Knopf. Über dem Feld liegen die Knöpfe der Schreibhilfe
|
||||||
(*Text erzeugen*, *Verbessern*, *Kürzen*, *Stichpunkte*, *Anforderungsprofil*)
|
(*Text erzeugen*, *Verbessern*, *Kürzen*, *Stichpunkte*, *Anforderungsprofil*)
|
||||||
und der Diktat-Knopf. *Zurück* holt den Stand vor dem letzten KI-Eingriff.
|
und der Diktat-Knopf. *Zurück* holt den Stand vor dem letzten KI-Eingriff.
|
||||||
|
|
||||||
Zwei Untermenüs:
|
Zwei Untermenüs:
|
||||||
|
|
||||||
* **Live!** – dieselben Ausschreibungen als Kanban über die Phasen, mit Ziehen
|
* **Live!** – dieselben Ausschreibungen als Kanban über die Phasen, mit Ziehen
|
||||||
bearbeitbar.
|
bearbeitbar.
|
||||||
* **Archiv** – archivierte Ausschreibungen; von dort zurückholbar.
|
* **Archiv** – archivierte Ausschreibungen; von dort zurückholbar.
|
||||||
|
|
||||||
## Laufende Projekte
|
## Laufende Projekte
|
||||||
|
|
||||||
Titel, Kunde, Experte, Zeitraum, Status, Tagessatz und Notizen. Die Notizen
|
Titel, Kunde, Experte, Zeitraum, Status, Tagessatz und Notizen. Die Notizen
|
||||||
sind ein WYSIWYG-Feld – im übernommenen Bestand steht dort ein Kopfblock aus dem
|
sind ein WYSIWYG-Feld – im übernommenen Bestand steht dort ein Kopfblock aus dem
|
||||||
alten CRM und darunter der Ausschreibungstext.
|
alten CRM und darunter der Ausschreibungstext.
|
||||||
|
|
||||||
### Marge
|
### Marge
|
||||||
|
|
||||||
Jede Projektkachel weist die Marge aus, und in der Projektkarte steht die
|
Jede Projektkachel weist die Marge aus, und in der Projektkarte steht die
|
||||||
Rechnung aufgeschlüsselt:
|
Rechnung aufgeschlüsselt:
|
||||||
|
|
||||||
| Zeile | Woher |
|
| Zeile | Woher |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Tagessatz Kunde | Feld **Tagessatz** am Projekt |
|
| Tagessatz Kunde | Feld **Tagessatz** am Projekt |
|
||||||
| Stundensatz Berater | Kontaktkarte des Experten |
|
| Stundensatz Berater | Kontaktkarte des Experten |
|
||||||
| Kosten (8 h) | Stundensatz × 8 |
|
| Kosten (8 h) | Stundensatz × 8 |
|
||||||
| Marge | Tagessatz − Kosten, dazu der Prozentsatz vom Tagessatz |
|
| Marge | Tagessatz − Kosten, dazu der Prozentsatz vom Tagessatz |
|
||||||
|
|
||||||
**Ein Tag sind 8 Stunden.** Hat der Berater einen Remote- *und* einen
|
**Ein Tag sind 8 Stunden.** Hat der Berater einen Remote- *und* einen
|
||||||
Vor-Ort-Satz, wird mit dem **Remote-Satz** gerechnet; fehlt der, mit dem
|
Vor-Ort-Satz, wird mit dem **Remote-Satz** gerechnet; fehlt der, mit dem
|
||||||
Vor-Ort-Satz. Welcher benutzt wurde, steht daneben.
|
Vor-Ort-Satz. Welcher benutzt wurde, steht daneben.
|
||||||
|
|
||||||
Die Farbe ist eine schnelle Ampel: grün ab 25 %, gelb darüber bis 0, rot bei
|
Die Farbe ist eine schnelle Ampel: grün ab 25 %, gelb darüber bis 0, rot bei
|
||||||
negativer Marge.
|
negativer Marge.
|
||||||
|
|
||||||
Fehlt der Tagessatz oder hat der Berater keinen Stundensatz, steht statt einer
|
Fehlt der Tagessatz oder hat der Berater keinen Stundensatz, steht statt einer
|
||||||
Zahl der Grund dort – eine leere Zeile ließe offen, ob die Marge null oder
|
Zahl der Grund dort – eine leere Zeile ließe offen, ob die Marge null oder
|
||||||
unbekannt ist. Der Tagessatz wird am Projekt gepflegt, die Stundensätze beim
|
unbekannt ist. Der Tagessatz wird am Projekt gepflegt, die Stundensätze beim
|
||||||
Kontakt (*Kontakt → Stundensatz vor Ort / remote*).
|
Kontakt (*Kontakt → Stundensatz vor Ort / remote*).
|
||||||
|
|
||||||
## Historie
|
## Historie
|
||||||
|
|
||||||
Alles, was im CRM getan wurde, mit Zeitpunkt, Person und – bei Änderungen – den
|
Alles, was im CRM getan wurde, mit Zeitpunkt, Person und – bei Änderungen – den
|
||||||
betroffenen Feldern samt Vorher/Nachher. Filterbar nach Art des Datensatzes.
|
betroffenen Feldern samt Vorher/Nachher. Filterbar nach Art des Datensatzes.
|
||||||
|
|
||||||
**@-Erwähnungen:** In jedem Notizfeld öffnet `@` eine Vorschlagsliste über
|
**@-Erwähnungen:** In jedem Notizfeld öffnet `@` eine Vorschlagsliste über
|
||||||
Kontakte, Unternehmen und Benutzer. Im Lesezustand ist jede Erwähnung anklickbar
|
Kontakte, Unternehmen und Benutzer. Im Lesezustand ist jede Erwähnung anklickbar
|
||||||
und führt auf das Profil; im Bearbeiten-Zustand steht dort die rohe Form
|
und führt auf das Profil; im Bearbeiten-Zustand steht dort die rohe Form
|
||||||
`@[Name](contact:12)` – anders ließe sie sich nicht ändern oder löschen.
|
`@[Name](contact:12)` – anders ließe sie sich nicht ändern oder löschen.
|
||||||
|
|
||||||
## Diktat
|
## Diktat
|
||||||
|
|
||||||
*Einstellungen → Diktat*, einmal je Gerät: **Sprachmodell laden** (rund 300 MB,
|
*Einstellungen → Diktat*, einmal je Gerät: **Sprachmodell laden** (rund 300 MB,
|
||||||
bleibt danach im Browser). Anschließend steht in jedem längeren Textfeld ein
|
bleibt danach im Browser). Anschließend steht in jedem längeren Textfeld ein
|
||||||
Mikrofon-Knopf.
|
Mikrofon-Knopf.
|
||||||
|
|
||||||
Aufnahme starten, sprechen, Knopf erneut drücken – der erkannte Text wird
|
Aufnahme starten, sprechen, Knopf erneut drücken – der erkannte Text wird
|
||||||
**angehängt**, nie ersetzt. Das Kreuz daneben verwirft die Aufnahme.
|
**angehängt**, nie ersetzt. Das Kreuz daneben verwirft die Aufnahme.
|
||||||
|
|
||||||
Die Erkennung läuft auf dem eigenen Rechner. Es wird nichts hochgeladen und
|
Die Erkennung läuft auf dem eigenen Rechner. Es wird nichts hochgeladen und
|
||||||
nichts gespeichert. Details: [04 Diktat](04-diktat.md).
|
nichts gespeichert. Details: [04 Diktat](04-diktat.md).
|
||||||
|
|
||||||
## Einstellungen
|
## Einstellungen
|
||||||
|
|
||||||
| Reiter | Wer | Inhalt |
|
| Reiter | Wer | Inhalt |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Nutzerverwaltung | Administratoren | Benutzer anlegen, Rolle, aktiv/inaktiv |
|
| Nutzerverwaltung | Administratoren | Benutzer anlegen, Rolle, aktiv/inaktiv |
|
||||||
| Stammdaten | Administratoren | Auswahllisten: Branchen, Arten der Kontakte |
|
| Stammdaten | Administratoren | Auswahllisten: Branchen, Arten der Kontakte |
|
||||||
| KI | Administratoren | OpenAI-Schlüssel, Modell (Auswahlliste der für den Schlüssel verfügbaren Modelle), Verbindungstest |
|
| KI | Administratoren | OpenAI-Schlüssel, Modell (Auswahlliste der für den Schlüssel verfügbaren Modelle), Verbindungstest |
|
||||||
| Mein Konto | alle | Foto, Farbe, Passwort, Design |
|
| Mein Konto | alle | Foto, Farbe, Passwort, Design |
|
||||||
| Diktat | alle | Spracherkennung einrichten |
|
| Diktat | alle | Spracherkennung einrichten |
|
||||||
|
|
||||||
Beim Pflegen der Stammdaten gelten zwei Regeln: **Umbenennen zieht den Bestand
|
Beim Pflegen der Stammdaten gelten zwei Regeln: **Umbenennen zieht den Bestand
|
||||||
mit**, und **Entfernen geht nur, solange ein Wert nirgends benutzt wird** –
|
mit**, und **Entfernen geht nur, solange ein Wert nirgends benutzt wird** –
|
||||||
hinter jedem Eintrag steht, wie oft er vorkommt.
|
hinter jedem Eintrag steht, wie oft er vorkommt.
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ angemeldeten Benutzer vorbelegt.
|
|||||||
**Diktat / Whisper** – Spracherkennung, die vollständig im Browser läuft. Siehe
|
**Diktat / Whisper** – Spracherkennung, die vollständig im Browser läuft. Siehe
|
||||||
[04 Diktat](04-diktat.md).
|
[04 Diktat](04-diktat.md).
|
||||||
|
|
||||||
**JWT** – das Token der Anmeldung, 12 Stunden gültig, im `localStorage`. Wird
|
**JWT** – das Token der Anmeldung, 7 Tage gültig, im `localStorage`. Wird
|
||||||
bei jeder Anfrage zusätzlich gegen die Datenbank geprüft.
|
bei jeder Anfrage zusätzlich gegen die Datenbank geprüft.
|
||||||
|
|
||||||
**MentionField** – das Textfeld mit zwei Zuständen (lesen / bearbeiten) für
|
**MentionField** – das Textfeld mit zwei Zuständen (lesen / bearbeiten) für
|
||||||
|
|||||||
+54
-54
@@ -1,54 +1,54 @@
|
|||||||
# ICON CRM Backend
|
# ICON CRM Backend
|
||||||
# Als .env kopieren und Werte setzen. .env gehoert nicht ins Repository.
|
# Als .env kopieren und Werte setzen. .env gehoert nicht ins Repository.
|
||||||
|
|
||||||
PORT=5007
|
PORT=5007
|
||||||
# Nur lokal binden - von aussen erreichbar ist die Anwendung ausschliesslich
|
# Nur lokal binden - von aussen erreichbar ist die Anwendung ausschliesslich
|
||||||
# ueber den Apache-Reverse-Proxy auf icrm.icon-experts.de.
|
# ueber den Apache-Reverse-Proxy auf icrm.icon-experts.de.
|
||||||
HOST=127.0.0.1
|
HOST=127.0.0.1
|
||||||
|
|
||||||
DB_HOST=localhost
|
DB_HOST=localhost
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_USER=iconcrm
|
DB_USER=iconcrm
|
||||||
DB_PASSWORD=changeme
|
DB_PASSWORD=changeme
|
||||||
DB_NAME=icon_CRM
|
DB_NAME=icon_CRM
|
||||||
|
|
||||||
# Signiert die JWT-Sitzungen. Langer Zufallswert, z. B.:
|
# Signiert die JWT-Sitzungen. Langer Zufallswert, z. B.:
|
||||||
# node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"
|
# node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"
|
||||||
JWT_SECRET=changeme-langer-zufallswert
|
JWT_SECRET=changeme-langer-zufallswert
|
||||||
JWT_EXPIRES_IN=12h
|
JWT_EXPIRES_IN=7d
|
||||||
|
|
||||||
# Wird beim ersten Start angelegt, solange noch kein Benutzer existiert.
|
# Wird beim ersten Start angelegt, solange noch kein Benutzer existiert.
|
||||||
# Ohne ADMIN_PASSWORD erzeugt das Backend eines und schreibt es einmalig ins Log.
|
# Ohne ADMIN_PASSWORD erzeugt das Backend eines und schreibt es einmalig ins Log.
|
||||||
ADMIN_USERNAME=Admin
|
ADMIN_USERNAME=Admin
|
||||||
ADMIN_NAME=Administrator
|
ADMIN_NAME=Administrator
|
||||||
ADMIN_EMAIL=admin@icon-experts.de
|
ADMIN_EMAIL=admin@icon-experts.de
|
||||||
ADMIN_PASSWORD=
|
ADMIN_PASSWORD=
|
||||||
|
|
||||||
# Erlaubte Herkunft fuer den lokalen Vite-Dev-Server.
|
# Erlaubte Herkunft fuer den lokalen Vite-Dev-Server.
|
||||||
CORS_ORIGINS=http://localhost:3101,http://127.0.0.1:3101
|
CORS_ORIGINS=http://localhost:3101,http://127.0.0.1:3101
|
||||||
|
|
||||||
# Ablage der hochgeladenen Lebenslaeufe. Leer = <server>/../uploads.
|
# Ablage der hochgeladenen Lebenslaeufe. Leer = <server>/../uploads.
|
||||||
UPLOAD_DIR=/var/www/icon_CRM/uploads
|
UPLOAD_DIR=/var/www/icon_CRM/uploads
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# KI (CV-Auslesung und Schreibhilfe fuer Ausschreibungen)
|
# KI (CV-Auslesung und Schreibhilfe fuer Ausschreibungen)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Der Schluessel bleibt auf dem Server - der Browser spricht nie direkt mit
|
# Der Schluessel bleibt auf dem Server - der Browser spricht nie direkt mit
|
||||||
# OpenAI. Fehlt er, laeuft das CRM normal weiter und blendet die KI-Knoepfe aus.
|
# OpenAI. Fehlt er, laeuft das CRM normal weiter und blendet die KI-Knoepfe aus.
|
||||||
#
|
#
|
||||||
# Hinweis zum Modell: gpt-5.6-luna akzeptiert KEIN eigenes "temperature";
|
# Hinweis zum Modell: gpt-5.6-luna akzeptiert KEIN eigenes "temperature";
|
||||||
# ai.js schickt deshalb nur den Standardwert.
|
# ai.js schickt deshalb nur den Standardwert.
|
||||||
OPENAI_API_KEY=
|
OPENAI_API_KEY=
|
||||||
OPENAI_MODEL=gpt-5.6-luna
|
OPENAI_MODEL=gpt-5.6-luna
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Lesender Zugriff auf die Kontakte des perinco CRM
|
# Lesender Zugriff auf die Kontakte des perinco CRM
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Das ICON CRM zeigt die perinco-Kontakte zusaetzlich an - gekennzeichnet und
|
# Das ICON CRM zeigt die perinco-Kontakte zusaetzlich an - gekennzeichnet und
|
||||||
# ausschliesslich lesend. Gespeichert wird nichts.
|
# ausschliesslich lesend. Gespeichert wird nichts.
|
||||||
#
|
#
|
||||||
# Der Token steht drueben in server/.env als ICON_API_TOKEN und muss
|
# Der Token steht drueben in server/.env als ICON_API_TOKEN und muss
|
||||||
# uebereinstimmen. Fehlt einer der beiden Werte, bleibt der Schalter in der
|
# uebereinstimmen. Fehlt einer der beiden Werte, bleibt der Schalter in der
|
||||||
# Oberflaeche aus und das CRM laeuft normal weiter.
|
# Oberflaeche aus und das CRM laeuft normal weiter.
|
||||||
PERINCO_API_URL=https://pcrm.perinco.de
|
PERINCO_API_URL=https://pcrm.perinco.de
|
||||||
PERINCO_API_TOKEN=
|
PERINCO_API_TOKEN=
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ function secret() {
|
|||||||
|
|
||||||
export function signToken(user) {
|
export function signToken(user) {
|
||||||
return jwt.sign({ sub: user.id, role: user.role }, secret(), {
|
return jwt.sign({ sub: user.id, role: user.role }, secret(), {
|
||||||
expiresIn: process.env.JWT_EXPIRES_IN || '12h',
|
expiresIn: process.env.JWT_EXPIRES_IN || '7d',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user