feat: CRM Clinicas SaaS - MVP completo
- Auth: Login/Register con creacion de clinica - Dashboard: KPIs reales, graficas recharts - Pacientes: CRUD completo con busqueda - Agenda: FullCalendar, drag-and-drop, vista recepcion - Expediente: Notas SOAP, signos vitales, CIE-10 - Facturacion: Facturas con IVA, campos CFDI SAT - Inventario: Productos, stock, movimientos, alertas - Configuracion: Clinica, equipo, catalogo servicios - Supabase self-hosted: 18 tablas con RLS multi-tenant - Docker + Nginx para produccion Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
160
.claude/helpers/perf-worker.sh
Executable file
160
.claude/helpers/perf-worker.sh
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/bin/bash
|
||||
# Claude Flow V3 - Performance Benchmark Worker
|
||||
# Runs periodic benchmarks and updates metrics using agentic-flow agents
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
METRICS_DIR="$PROJECT_ROOT/.claude-flow/metrics"
|
||||
PERF_FILE="$METRICS_DIR/performance.json"
|
||||
LAST_RUN_FILE="$METRICS_DIR/.perf-last-run"
|
||||
|
||||
mkdir -p "$METRICS_DIR"
|
||||
|
||||
# Check if we should run (throttle to once per 5 minutes)
|
||||
should_run() {
|
||||
if [ ! -f "$LAST_RUN_FILE" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local last_run=$(cat "$LAST_RUN_FILE" 2>/dev/null || echo "0")
|
||||
local now=$(date +%s)
|
||||
local diff=$((now - last_run))
|
||||
|
||||
# Run every 5 minutes (300 seconds)
|
||||
[ "$diff" -ge 300 ]
|
||||
}
|
||||
|
||||
# Simple search benchmark (measures grep/search speed)
|
||||
benchmark_search() {
|
||||
local start=$(date +%s%3N)
|
||||
|
||||
# Search through v3 codebase
|
||||
find "$PROJECT_ROOT/v3" -name "*.ts" -type f 2>/dev/null | \
|
||||
xargs grep -l "function\|class\|interface" 2>/dev/null | \
|
||||
wc -l > /dev/null
|
||||
|
||||
local end=$(date +%s%3N)
|
||||
local duration=$((end - start))
|
||||
|
||||
# Baseline is ~100ms, calculate improvement
|
||||
local baseline=100
|
||||
if [ "$duration" -gt 0 ]; then
|
||||
local improvement=$(echo "scale=2; $baseline / $duration" | bc 2>/dev/null || echo "1.0")
|
||||
echo "${improvement}x"
|
||||
else
|
||||
echo "1.0x"
|
||||
fi
|
||||
}
|
||||
|
||||
# Memory efficiency check
|
||||
benchmark_memory() {
|
||||
local node_mem=$(ps aux 2>/dev/null | grep -E "(node|agentic)" | grep -v grep | awk '{sum += $6} END {print int(sum/1024)}')
|
||||
local baseline_mem=4000 # 4GB baseline
|
||||
|
||||
if [ -n "$node_mem" ] && [ "$node_mem" -gt 0 ]; then
|
||||
local reduction=$(echo "scale=0; 100 - ($node_mem * 100 / $baseline_mem)" | bc 2>/dev/null || echo "0")
|
||||
if [ "$reduction" -lt 0 ]; then reduction=0; fi
|
||||
echo "${reduction}%"
|
||||
else
|
||||
echo "0%"
|
||||
fi
|
||||
}
|
||||
|
||||
# Startup time check
|
||||
benchmark_startup() {
|
||||
local start=$(date +%s%3N)
|
||||
|
||||
# Quick check of agentic-flow responsiveness
|
||||
timeout 5 npx agentic-flow@alpha --version >/dev/null 2>&1 || true
|
||||
|
||||
local end=$(date +%s%3N)
|
||||
local duration=$((end - start))
|
||||
|
||||
echo "${duration}ms"
|
||||
}
|
||||
|
||||
# Run benchmarks and update metrics
|
||||
run_benchmarks() {
|
||||
echo "[$(date +%H:%M:%S)] Running performance benchmarks..."
|
||||
|
||||
local search_speed=$(benchmark_search)
|
||||
local memory_reduction=$(benchmark_memory)
|
||||
local startup_time=$(benchmark_startup)
|
||||
|
||||
# Calculate overall speedup (simplified)
|
||||
local speedup_num=$(echo "$search_speed" | tr -d 'x')
|
||||
if [ -z "$speedup_num" ] || [ "$speedup_num" = "1.0" ]; then
|
||||
speedup_num="1.0"
|
||||
fi
|
||||
|
||||
# Update performance.json
|
||||
if [ -f "$PERF_FILE" ] && command -v jq &>/dev/null; then
|
||||
jq --arg search "$search_speed" \
|
||||
--arg memory "$memory_reduction" \
|
||||
--arg startup "$startup_time" \
|
||||
--arg speedup "${speedup_num}x" \
|
||||
--arg updated "$(date -Iseconds)" \
|
||||
'.search.improvement = $search |
|
||||
.memory.reduction = $memory |
|
||||
.startupTime.current = $startup |
|
||||
.flashAttention.speedup = $speedup |
|
||||
."last-updated" = $updated' \
|
||||
"$PERF_FILE" > "$PERF_FILE.tmp" && mv "$PERF_FILE.tmp" "$PERF_FILE"
|
||||
|
||||
echo "[$(date +%H:%M:%S)] ✓ Metrics updated: search=$search_speed memory=$memory_reduction startup=$startup_time"
|
||||
else
|
||||
echo "[$(date +%H:%M:%S)] ⚠ Could not update metrics (missing jq or file)"
|
||||
fi
|
||||
|
||||
# Record last run time
|
||||
date +%s > "$LAST_RUN_FILE"
|
||||
}
|
||||
|
||||
# Spawn agentic-flow performance agent for deep analysis
|
||||
run_deep_benchmark() {
|
||||
echo "[$(date +%H:%M:%S)] Spawning performance-benchmarker agent..."
|
||||
|
||||
npx agentic-flow@alpha --agent perf-analyzer --task "Analyze current system performance and update metrics" 2>/dev/null &
|
||||
local pid=$!
|
||||
|
||||
# Don't wait, let it run in background
|
||||
echo "[$(date +%H:%M:%S)] Agent spawned (PID: $pid)"
|
||||
}
|
||||
|
||||
# Main dispatcher
|
||||
case "${1:-check}" in
|
||||
"run"|"benchmark")
|
||||
run_benchmarks
|
||||
;;
|
||||
"deep")
|
||||
run_deep_benchmark
|
||||
;;
|
||||
"check")
|
||||
if should_run; then
|
||||
run_benchmarks
|
||||
else
|
||||
echo "[$(date +%H:%M:%S)] Skipping benchmark (throttled)"
|
||||
fi
|
||||
;;
|
||||
"force")
|
||||
rm -f "$LAST_RUN_FILE"
|
||||
run_benchmarks
|
||||
;;
|
||||
"status")
|
||||
if [ -f "$PERF_FILE" ]; then
|
||||
jq -r '"Search: \(.search.improvement // "1x") | Memory: \(.memory.reduction // "0%") | Startup: \(.startupTime.current // "N/A")"' "$PERF_FILE" 2>/dev/null
|
||||
else
|
||||
echo "No metrics available"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: perf-worker.sh [run|deep|check|force|status]"
|
||||
echo " run - Run quick benchmarks"
|
||||
echo " deep - Spawn agentic-flow agent for deep analysis"
|
||||
echo " check - Run if throttle allows (default)"
|
||||
echo " force - Force run ignoring throttle"
|
||||
echo " status - Show current metrics"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user