Seite: /<slug>[/v<N>][/lauf|/buch|/lesen][/<Abschnitt>], Zurück-Taste je Abschnitt. API: /api/themen/<slug>/v<N>/… mit Version als Pflichtteil des Pfads; /api/topics entfällt. Slugs stehen in thema.json und werden beim Start nachgetragen. Unbekannte API-Pfade liefern 404 statt der Seite. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
62 lines
2.6 KiB
Makefile
62 lines
2.6 KiB
Makefile
.PHONY: install build run dev auth prod stop logs push pull loeschen
|
||
|
||
PY := .venv/bin/python
|
||
COMPOSE = docker compose
|
||
SERVER ?= root@178.104.67.87
|
||
URL ?= https://buchwerk.marha.de
|
||
REMOTE ?= /var/www/buchwerk
|
||
# Themen zwischen lokal und Server abgleichen; TOPIC=<Name> beschränkt auf ein Thema.
|
||
# Ausgeschlossen: Arbeitsdateien der Agenten (arbeit/) und Logs. Ohne --delete: nichts wird entfernt.
|
||
SYNC_QUELLE = storage/$(if $(TOPIC),$(TOPIC)/,)
|
||
SYNC_AUS = --exclude 'arbeit/' --exclude '*.log' --exclude '*.tmp'
|
||
|
||
install:
|
||
python3 -m venv .venv
|
||
.venv/bin/pip install -r backend/requirements.txt
|
||
cd frontend && npm install
|
||
|
||
build:
|
||
cd frontend && npm run build
|
||
|
||
run:
|
||
$(PY) -m uvicorn backend.main:app --port 8020
|
||
|
||
dev:
|
||
$(PY) -m uvicorn backend.main:app --reload --port 8020 & cd frontend && npm run dev
|
||
|
||
auth:
|
||
@mkdir -p .claude-data storage
|
||
@chown -R 1000:1000 .claude-data storage 2>/dev/null || sudo chown -R 1000:1000 .claude-data storage
|
||
@grep -q "^CLAUDE_CODE_OAUTH_TOKEN=.\+" .env 2>/dev/null || grep -q "^ANTHROPIC_API_KEY=.\+" .env 2>/dev/null \
|
||
|| echo "WARNUNG: weder CLAUDE_CODE_OAUTH_TOKEN noch ANTHROPIC_API_KEY in .env – Agenten können nicht starten (Token: claude setup-token)."
|
||
|
||
prod: auth
|
||
$(COMPOSE) up -d --build
|
||
@echo "buchwerk läuft: https://buchwerk.marha.de"
|
||
|
||
stop:
|
||
$(COMPOSE) down
|
||
|
||
logs:
|
||
$(COMPOSE) logs -f --tail=200
|
||
|
||
push:
|
||
@[ -z "$(TOPIC)" ] || [ -d "storage/$(TOPIC)" ] || { echo "storage/$(TOPIC) fehlt"; exit 1; }
|
||
rsync -az --progress --mkpath --chown=1000:1000 $(SYNC_AUS) "$(SYNC_QUELLE)" "$(SERVER):$(REMOTE)/$(SYNC_QUELLE)"
|
||
@echo "Hochgeladen: $(SYNC_QUELLE) → $(SERVER):$(REMOTE)"
|
||
|
||
pull:
|
||
rsync -az --progress --mkpath $(SYNC_AUS) "$(SERVER):$(REMOTE)/$(SYNC_QUELLE)" "$(SYNC_QUELLE)"
|
||
@echo "Geholt: $(SERVER):$(REMOTE)/$(SYNC_QUELLE) → $(SYNC_QUELLE)"
|
||
|
||
# Fertige Bücher lassen sich in der Oberfläche nicht löschen. Nur hier, mit Rückfrage:
|
||
# make loeschen TOPIC="Godot 4" – ganzes Thema mit allen Versionen (Server über die API, dann lokal)
|
||
# make loeschen TOPIC="Godot 4" V=2 – nur Version 2
|
||
loeschen:
|
||
@[ -n "$(TOPIC)" ] || { echo "TOPIC=<Name> angeben (optional V=<Nr>)"; exit 1; }
|
||
@printf '%s auf dem Server und lokal unwiderruflich löschen? [j/N] ' "$(if $(V),Version $(V) von „$(TOPIC)“,Thema „$(TOPIC)“ mit allen Versionen)"; read a; [ "$$a" = "j" ]
|
||
@slug=$$(curl -fsS "$(URL)/api/themen" | python3 -c 'import json,sys; n=sys.argv[1]; print(next(t["slug"] for t in json.load(sys.stdin) if t["name"]==n))' "$(TOPIC)") && \
|
||
curl -fsS -X DELETE "$(URL)/api/themen/$$slug$(if $(V),/v$(V),)" && echo
|
||
rm -rf "storage/$(TOPIC)$(if $(V),/v$(V),)"
|
||
@echo "Gelöscht: $(TOPIC)$(if $(V), v$(V),)"
|