didi-website-erp-crm/erp_crm/OPERATIONS.md

309 lines
7.7 KiB
Markdown

# Operare ERP/CRM DiDi
Ghid pentru administrare zilnica: backup, restart, log-uri, troubleshooting.
## Comenzi uzuale
### Status containere
```bash
docker compose ps
docker stats --no-stream # CPU/RAM realtime
```
### Restart serviciu
```bash
# Doar ERPNext (cel mai des)
docker compose restart erpnext
# Toate
docker compose restart
# Restart cu rebuild image
docker compose up -d --build erpnext
```
### Log-uri
```bash
# Container ERPNext (gunicorn + nginx)
docker compose logs -f erpnext
# Worker job-uri background
docker compose logs -f queue-short
docker compose logs -f queue-long
docker compose logs -f scheduler
# Fisier de log Frappe (in container)
docker exec didi-erpnext tail -f /home/frappe/frappe-bench/sites/didi-erp/logs/web.log
docker exec didi-erpnext tail -f /home/frappe/logs/database.log
```
### Bench (CLI Frappe)
```bash
# Cache + cache static
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp clear-cache'
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp clear-website-cache'
# Migrate (dupa update Frappe sau didi_custom)
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp migrate'
# Rebuild assets (CSS/JS)
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench build --force'
# Reset Administrator password
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp set-admin-password admin'
# Console Python interactiv
docker exec -it didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp console'
```
## Backup
### Backup automat zilnic (recomandare cron)
Adauga in crontab (`crontab -e`):
```cron
# Backup zilnic la 02:00, retentie 14 zile
0 2 * * * ~/erp_crm/bin/backup.sh
```
Continut `bin/backup.sh` (creeaza-l):
```bash
#!/bin/bash
set -e
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=/var/backups/didi-erp
mkdir -p $BACKUP_DIR
# DB dump
docker exec didi-mariadb mariadb-dump -uroot -p<parola-root-db> --all-databases \
| gzip > $BACKUP_DIR/db-$DATE.sql.gz
# Files (uploaded attachments)
docker run --rm \
-v didi-data-layer_erpnext-sites:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/sites-$DATE.tar.gz /data
# Retention: keep last 14 days
find $BACKUP_DIR -mtime +14 -delete
echo "Backup OK: $DATE"
```
### Backup manual (Frappe-managed)
ERPNext are propriu mecanism de backup:
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp backup --with-files
'
# Fisierele apar in: sites/didi-erp/private/backups/
```
Copy local:
```bash
docker cp didi-erpnext:/home/frappe/frappe-bench/sites/didi-erp/private/backups/ ./backups-$(date +%Y%m%d)
```
## Restore din backup
```bash
# 1. Copiaza fisierele in container
docker cp ./backups-20260525 didi-erpnext:/tmp/restore
# 2. Restore
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp restore /tmp/restore/db-XXXXXX.sql.gz \
--with-public-files /tmp/restore/files-XXXXXX.tar \
--with-private-files /tmp/restore/private-files-XXXXXX.tar \
--mariadb-root-password <parola-root-db>
'
```
## Update / upgrade
### Update didi_custom (app-ul nostru)
Dupa ce modifici cod in `didi_custom/`:
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp migrate
'
```
Daca ai modificat doctype:
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp execute "frappe.model.sync.sync_for" --kwargs "{\"app\":\"didi_custom\"}"
'
```
### Upgrade ERPNext (major version)
NU recomandat fara o copie test. Procedura:
1. Backup complet
2. Edit `docker-compose.yml`: `ERPNEXT_VERSION=v16` (cand apare)
3. `docker compose pull`
4. `docker compose up -d`
5. `bench --site didi-erp migrate`
6. Test extensiv
## Monitorizare
### Health checks
```bash
# HTTP
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080
# DB
docker exec didi-mariadb mariadb -uroot -p<parola-root-db> -e "SELECT 1"
# Redis
docker exec didi-redis-cache redis-cli ping
docker exec didi-redis-queue redis-cli ping
# Background workers (verifica heartbeat)
docker exec didi-redis-queue redis-cli KEYS 'rq:worker:*'
```
### Email queue
```bash
docker exec didi-mariadb mariadb -u_xxx -pxxx didi_db -e "
SELECT status, COUNT(*) FROM \`tabEmail Queue\` GROUP BY status;
"
# Flush manual
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp execute frappe.email.queue.flush'
# Trimitere imediata (bypass queue)
docker exec didi-erpnext bash -c 'cd /home/frappe/frappe-bench && bench --site didi-erp send-email --send-now'
```
## Troubleshooting
### Site nu raspunde / 500
```bash
# 1. Log-uri
docker compose logs --tail 100 erpnext
# 2. Restart curat
docker exec didi-redis-cache redis-cli FLUSHALL
docker exec didi-redis-queue redis-cli FLUSHALL
docker compose restart erpnext
# 3. Daca tot nu merge, verifica DB conexiune
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench && bench --site didi-erp doctor
'
```
### Workers nu proceseaza job-uri
```bash
# Status workers
docker exec didi-redis-queue redis-cli LRANGE "rq:queue:short" 0 -1 | head
docker exec didi-redis-queue redis-cli LRANGE "rq:queue:long" 0 -1 | head
# Restart workers
docker compose restart queue-short queue-long queue-default
```
### "Module Selling not found" sau alte module standard
`installed_apps` din DB e dezsincronizat. Fix:
```bash
DB=$(docker exec didi-erpnext cat /home/frappe/frappe-bench/sites/didi-erp/site_config.json | python3 -c "import sys,json; print(json.load(sys.stdin)['db_name'])")
docker exec didi-mariadb mariadb -uroot -p<parola-root-db> $DB -e "
UPDATE tabDefaultValue SET defvalue='[\"frappe\",\"erpnext\",\"didi_custom\"]' WHERE defkey='installed_apps';
"
docker exec didi-redis-cache redis-cli FLUSHALL
docker compose restart erpnext
```
### PDF nu se genereaza ("HostNotFoundError")
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp set-config -g host_name "http://didi-erpnext:8080"
'
docker compose restart erpnext
```
### Workspace cu titlu romanesc nu se gaseste
URL-urile Frappe sunt slug-ificate. Diacriticele se pierd. Pune titlul fara diacritice in DB:
```sql
UPDATE tabWorkspace SET title='Plati' WHERE name='Plati';
```
## Scenarii de operare
### Adaugare user admin nou
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp add-user nume.user@clossers.com \
--first-name Nume \
--last-name User \
--password parolaTemp123 \
--add-system-manager
'
```
### Schimbare email From-name (SendGrid)
```bash
# Update Email Account
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp execute "frappe.db.set_value" --kwargs "{\"doctype\":\"Email Account\", \"docname\":\"DiDi Outgoing\", \"fieldname\":\"email_id\", \"value\":\"office@clossers.com\"}"
'
docker compose restart erpnext
```
### Sterge factura emisa (anulare)
ERPNext nu permite delete pe `docstatus=1`. Trebuie cancel + delete:
```bash
docker exec didi-erpnext bash -c '
cd /home/frappe/frappe-bench &&
bench --site didi-erp execute "frappe.client.cancel" --kwargs "{\"doctype\":\"Sales Invoice\", \"name\":\"DIDI-INV-2026-00001\"}"
'
```
Apoi din UI sterge documentul anulat.
## SLA si severitati (conform contract)
| Severitate | Definitie | Timp raspuns | Timp rezolvare |
|------------|-----------|--------------|----------------|
| Critica | Sistemul nu functioneaza / plati nefunctionale | 4 ore | 24 ore |
| Majora | Functionalitate importanta afectata | 8 ore | 3 zile lucratoare |
| Minora | Probleme cosmetice / minore | 24 ore | 10 zile lucratoare |
Canal tichete: office@clossers.com (sau sistem helpdesk dedicat la productie).
Program suport: zile lucratoare 09:00 - 18:00.