🔧 fix: enhance watch mode to reload browser on build completion
This commit is contained in:
175
.agents/skills/live-mongodb/SKILL.md
Normal file
175
.agents/skills/live-mongodb/SKILL.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
---
|
||||||
|
name: live-mongodb
|
||||||
|
description: Connect to the live (production) MongoDB via chisel tunnel and perform read/write operations. Use this skill when you need to inspect or update live data directly in the production database.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Live MongoDB Access via Chisel Tunnel
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Die Produktions-MongoDB läuft auf dem Server aus `PRODUCTION_SERVER` in `.env`. Der Zugang erfolgt über einen **Chisel-Tunnel**, der den Remote-MongoDB-Port auf localhost mapped. Damit kann man dann entweder über `mongosh`, `mongodump`/`mongorestore`, oder den **MongoDB MCP Server** auf die Live-Daten zugreifen.
|
||||||
|
|
||||||
|
## Umgebungsvariablen (aus .env)
|
||||||
|
|
||||||
|
| Variable | Beschreibung |
|
||||||
|
| ------------------------ | ----------------------------------------------- |
|
||||||
|
| `PRODUCTION_SERVER` | Produktionsserver (z.B. `dock4.basehosts.de`) |
|
||||||
|
| `PRODUCTION_TIBI_PREFIX` | DB-Prefix auf Produktion (z.B. `wmbasic`) |
|
||||||
|
| `TIBI_NAMESPACE` | Projekt-Namespace |
|
||||||
|
| **Live DB Name** | = `${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}` |
|
||||||
|
| Chisel-Port (Remote) | `10987` — Chisel-Server auf dem Produktionshost |
|
||||||
|
|
||||||
|
## Schritt 1: Chisel-Tunnel starten
|
||||||
|
|
||||||
|
Das Chisel-Passwort muss vom User bereitgestellt werden. Tunnel starten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Passwort vom User erfragen oder aus Umgebung nehmen
|
||||||
|
read -s -p "Chisel-Passwort: " CHISEL_PASSWORD
|
||||||
|
|
||||||
|
# Tunnel starten (mappt remote mongo:27017 → localhost:27017)
|
||||||
|
chisel client --auth "coder:${CHISEL_PASSWORD}" \
|
||||||
|
http://${PRODUCTION_SERVER}:10987 \
|
||||||
|
27017:mongo:27017 &
|
||||||
|
|
||||||
|
# Kurz warten, bis der Tunnel steht
|
||||||
|
sleep 3
|
||||||
|
```
|
||||||
|
|
||||||
|
**WICHTIG:** Der lokale Docker-Mongo-Container muss gestoppt sein oder auf einem anderen Port laufen, da der Tunnel Port 27017 lokal belegt. Falls der lokale Container läuft:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lokales MongoDB stoppen (belegt sonst Port 27017)
|
||||||
|
docker compose -f docker-compose-local.yml stop mongo
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternativ kann der Tunnel auf einen anderen lokalen Port gemappt werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chisel client --auth "coder:${CHISEL_PASSWORD}" \
|
||||||
|
http://${PRODUCTION_SERVER}:10987 \
|
||||||
|
37017:mongo:27017 &
|
||||||
|
# → erreichbar unter mongodb://localhost:37017/${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Schritt 2: Verbinden
|
||||||
|
|
||||||
|
### Option A: mongosh (interaktiv)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mongosh "mongodb://localhost:27017/${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: MongoDB MCP Server (für Copilot)
|
||||||
|
|
||||||
|
Den MongoDB MCP über die Umgebungsvariable `MDB_MCP_CONNECTION_STRING` auf die Live-DB umleiten.
|
||||||
|
|
||||||
|
**Temporär für eine Session** – in `.vscode/mcp.json` eine zweite Server-Config eintragen:
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
{
|
||||||
|
"servers": {
|
||||||
|
"mongodb-live": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "mongodb-mcp-server@latest"],
|
||||||
|
"type": "stdio",
|
||||||
|
"env": {
|
||||||
|
"MDB_MCP_CONNECTION_STRING": "mongodb://localhost:27017/${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}",
|
||||||
|
"MDB_MCP_READ_ONLY": "false",
|
||||||
|
"MDB_MCP_TELEMETRY": "disabled",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Achtung:** `MDB_MCP_READ_ONLY=false` erlaubt Schreiboperationen! Nach getaner Arbeit den Server wieder entfernen oder auf `true` setzen.
|
||||||
|
|
||||||
|
### Option C: Einmalige Kommandos via Terminal
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DB_NAME="${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}"
|
||||||
|
|
||||||
|
# Dokument suchen
|
||||||
|
mongosh "mongodb://localhost:27017/$DB_NAME" \
|
||||||
|
--eval 'db.content.findOne({path: "/"})'
|
||||||
|
|
||||||
|
# Feld updaten
|
||||||
|
mongosh "mongodb://localhost:27017/$DB_NAME" \
|
||||||
|
--eval 'db.content.updateOne({path: "/"}, {$set: {"title": "Neuer Titel"}})'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Schritt 3: Tunnel beenden
|
||||||
|
|
||||||
|
```bash
|
||||||
|
killall chisel
|
||||||
|
```
|
||||||
|
|
||||||
|
Falls der lokale Mongo-Container vorher gestoppt wurde, wieder starten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose-local.yml start mongo
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sicherheitsregeln
|
||||||
|
|
||||||
|
1. **Immer zuerst lesen, dann schreiben.** Vor jedem Update das betroffene Dokument mit `find`/`findOne` inspizieren.
|
||||||
|
2. **Backup vor Bulk-Updates.** Bei Massenänderungen vorher ein `mongodump` machen:
|
||||||
|
```bash
|
||||||
|
mongodump --uri="mongodb://localhost:27017" \
|
||||||
|
--db=${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE} \
|
||||||
|
--collection=<collection> \
|
||||||
|
--gzip --archive=backup-<collection>-$(date +%Y%m%d-%H%M%S).gz
|
||||||
|
```
|
||||||
|
3. **User muss Chisel-Passwort liefern.** Das Passwort niemals hardcoden oder in Dateien speichern.
|
||||||
|
4. **Updates immer bestätigen lassen.** Vor jeder Schreiboperation dem User die geplante Query zeigen und explizit nach Bestätigung fragen.
|
||||||
|
5. **Nach getaner Arbeit Tunnel schließen** und ggf. `mongodb-live` MCP-Server aus der Config entfernen.
|
||||||
|
6. **Kein Drop/Delete von Collections** ohne explizite User-Anweisung.
|
||||||
|
7. **SSR-Cache leeren nach Datenänderungen.** Wenn Daten in Collections geändert werden, die auf der Website gerendert werden (z.B. `content`, `navigation`), muss der SSR-Cache invalidiert werden, damit die Änderungen sichtbar werden. Dazu die `ssr`-Collection leeren:
|
||||||
|
```bash
|
||||||
|
mongosh "mongodb://localhost:27017/$DB_NAME" \
|
||||||
|
--eval 'db.ssr.deleteMany({})'
|
||||||
|
```
|
||||||
|
Siehe auch den Skill `tibi-ssr-caching` für Details zur Cache-Invalidierung über die API.
|
||||||
|
|
||||||
|
## Wichtige Collections
|
||||||
|
|
||||||
|
| Collection | Beschreibung |
|
||||||
|
| ------------ | ------------------------------- |
|
||||||
|
| `content` | CMS-Inhaltsseiten (Pagebuilder) |
|
||||||
|
| `navigation` | Navigationsstruktur |
|
||||||
|
| `medialib` | Medien-Bibliothek |
|
||||||
|
| `ssr` | SSR-Cache |
|
||||||
|
|
||||||
|
> Weitere Collections je nach Projekt — siehe `api/collections/` für die aktuelle Liste.
|
||||||
|
|
||||||
|
## Typische Anwendungsfälle
|
||||||
|
|
||||||
|
### Content-Eintrag inspizieren
|
||||||
|
|
||||||
|
```js
|
||||||
|
db.content.findOne({ path: "/" })
|
||||||
|
```
|
||||||
|
|
||||||
|
### Navigation aktualisieren
|
||||||
|
|
||||||
|
```js
|
||||||
|
db.navigation.updateOne({ type: "header", language: "de" }, { $set: { "items.0.label": "Neues Label" } })
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dokument-Struktur inspizieren
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Schema einer Collection anschauen
|
||||||
|
db.content.findOne()
|
||||||
|
|
||||||
|
// Alle Felder eines Dokuments auflisten
|
||||||
|
Object.keys(db.content.findOne())
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fehlerbehebung
|
||||||
|
|
||||||
|
- **"Connection refused" auf Port 27017:** Chisel-Tunnel läuft nicht oder lokaler Mongo blockiert den Port. Prüfen mit `ss -tlnp | grep 27017`.
|
||||||
|
- **"Authentication failed":** Chisel-Passwort falsch. User erneut fragen.
|
||||||
|
- **Langsame Queries:** Produktions-DB kann große Collections haben. Immer mit Filtern arbeiten, nie `find({})` ohne Limit.
|
||||||
|
- **Rate Limiting:** Kein Thema bei direktem DB-Zugang (nur bei API-Calls relevant).
|
||||||
@@ -56,7 +56,11 @@ switch (process.argv?.length > 2 ? process.argv[2] : "build") {
|
|||||||
bs.init(config.browserSync)
|
bs.init(config.browserSync)
|
||||||
case "watch":
|
case "watch":
|
||||||
// config.options.incremental = true
|
// config.options.incremental = true
|
||||||
build(true)
|
build(true).then(() => {
|
||||||
|
if (bs) {
|
||||||
|
bs.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
const watcher = watch(config.watch.path)
|
const watcher = watch(config.watch.path)
|
||||||
log("watching files...")
|
log("watching files...")
|
||||||
watcher.on("change", function (path) {
|
watcher.on("change", function (path) {
|
||||||
|
|||||||
Reference in New Issue
Block a user