feat: Add client extraction, amount cross-validation, and workflow fixes
OCR improvements: - Extract client data (name, CUI, address) from B2B receipts - Cross-validate amounts using payment methods and TVA entries - OCR-tolerant patterns for "TOTAL LEI" with common OCR errors - Better BON FISCAL vs CHITANTA detection Backend workflow fixes: - Fix SQLAlchemy deleted instance error in resubmit/submit workflow - Add session.refresh() after deleting accounting entries - Add unapprove endpoint (APPROVED → PENDING_REVIEW) - Add direction filter for receipt listing Frontend improvements: - Fix Vue v-else-if chain broken by Menu component - Unified OCR Preview layout with values table - Receipt list filter by direction (plati/incasari) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,10 @@ BLUE='\033[0;34m'
|
||||
MAGENTA='\033[0;35m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Get script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
print_message() { echo -e "${BLUE}[DATA-ENTRY-PROD]${NC} $1"; }
|
||||
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||||
@@ -25,39 +29,191 @@ check_port() {
|
||||
lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Individual service functions
|
||||
stop_frontend() {
|
||||
if check_port 3010; then
|
||||
print_message "Stopping frontend..."
|
||||
lsof -ti:3010 | xargs kill -TERM 2>/dev/null || true
|
||||
sleep 1
|
||||
lsof -ti:3010 | xargs kill -KILL 2>/dev/null || true
|
||||
pkill -f "vite.*3010" 2>/dev/null || true
|
||||
print_success "Frontend stopped"
|
||||
else
|
||||
print_warning "Frontend not running"
|
||||
fi
|
||||
}
|
||||
|
||||
stop_backend() {
|
||||
if check_port 8003; then
|
||||
print_message "Stopping backend..."
|
||||
lsof -ti:8003 | xargs kill -TERM 2>/dev/null || true
|
||||
sleep 1
|
||||
lsof -ti:8003 | xargs kill -KILL 2>/dev/null || true
|
||||
pkill -f "uvicorn.*8003" 2>/dev/null || true
|
||||
print_success "Backend stopped"
|
||||
else
|
||||
print_warning "Backend not running"
|
||||
fi
|
||||
}
|
||||
|
||||
start_frontend() {
|
||||
if check_port 3010; then
|
||||
print_warning "Frontend already running on port 3010"
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_message "Starting Frontend (Vue.js)..."
|
||||
cd "$SCRIPT_DIR/data-entry-app/frontend/"
|
||||
|
||||
if [ ! -d "node_modules" ] || [ -f "node_modules/.bin/vite.cmd" ]; then
|
||||
print_message "Installing frontend dependencies..."
|
||||
rm -rf node_modules package-lock.json 2>/dev/null
|
||||
npm install
|
||||
fi
|
||||
|
||||
# Clear Vite cache for clean start
|
||||
rm -rf node_modules/.vite 2>/dev/null || true
|
||||
|
||||
npm run dev -- --port 3010 > /tmp/data_entry_frontend.log 2>&1 &
|
||||
|
||||
for i in {1..15}; do
|
||||
if check_port 3010; then
|
||||
print_success "Frontend started on http://localhost:3010"
|
||||
cd "$SCRIPT_DIR"
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
print_error "Frontend failed to start"
|
||||
cat /tmp/data_entry_frontend.log
|
||||
cd "$SCRIPT_DIR"
|
||||
return 1
|
||||
}
|
||||
|
||||
start_backend() {
|
||||
if check_port 8003; then
|
||||
print_warning "Backend already running on port 8003"
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_message "Starting Backend (FastAPI)..."
|
||||
cd "$SCRIPT_DIR/data-entry-app/backend/"
|
||||
|
||||
if [ ! -d "venv" ]; then
|
||||
print_message "Creating virtual environment..."
|
||||
python3 -m venv venv
|
||||
fi
|
||||
|
||||
source venv/bin/activate
|
||||
|
||||
if ! python -c "import fastapi, uvicorn, sqlmodel" 2>/dev/null; then
|
||||
print_message "Installing backend dependencies..."
|
||||
pip install --upgrade pip > /dev/null 2>&1
|
||||
pip install -r requirements.txt
|
||||
fi
|
||||
|
||||
mkdir -p data/uploads
|
||||
|
||||
print_message "Running migrations..."
|
||||
alembic upgrade head 2>/dev/null || print_warning "Migrations may already be applied"
|
||||
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8003 --reload > /tmp/data_entry_backend.log 2>&1 &
|
||||
|
||||
for i in {1..20}; do
|
||||
if check_port 8003; then
|
||||
print_success "Backend started on http://localhost:8003"
|
||||
cd "$SCRIPT_DIR"
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
print_error "Backend failed to start"
|
||||
cat /tmp/data_entry_backend.log
|
||||
cd "$SCRIPT_DIR"
|
||||
return 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
print_message "Stopping services..."
|
||||
[[ -n $BACKEND_PID ]] && kill $BACKEND_PID 2>/dev/null || true
|
||||
[[ -n $FRONTEND_PID ]] && kill $FRONTEND_PID 2>/dev/null || true
|
||||
stop_frontend
|
||||
stop_backend
|
||||
./ssh_tunnel.sh stop 2>/dev/null || true
|
||||
print_success "All services stopped."
|
||||
exit 0
|
||||
}
|
||||
|
||||
stop_services() {
|
||||
print_message "Stopping all Data Entry PRODUCTION services..."
|
||||
local target=${1:-all}
|
||||
|
||||
if check_port 8003; then
|
||||
lsof -ti:8003 | xargs kill -TERM 2>/dev/null || true
|
||||
sleep 2
|
||||
lsof -ti:8003 | xargs kill -KILL 2>/dev/null || true
|
||||
print_success "Backend stopped"
|
||||
fi
|
||||
case $target in
|
||||
frontend|fe|f)
|
||||
stop_frontend
|
||||
;;
|
||||
backend|be|b)
|
||||
stop_backend
|
||||
;;
|
||||
all|"")
|
||||
print_message "Stopping all Data Entry PRODUCTION services..."
|
||||
stop_frontend
|
||||
stop_backend
|
||||
./ssh_tunnel.sh stop 2>/dev/null || true
|
||||
print_success "All Data Entry PRODUCTION services stopped!"
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown target: $target (use: frontend, backend, all)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if check_port 3010; then
|
||||
lsof -ti:3010 | xargs kill -TERM 2>/dev/null || true
|
||||
sleep 2
|
||||
lsof -ti:3010 | xargs kill -KILL 2>/dev/null || true
|
||||
print_success "Frontend stopped"
|
||||
fi
|
||||
start_services() {
|
||||
local target=${1:-all}
|
||||
|
||||
./ssh_tunnel.sh stop 2>/dev/null || true
|
||||
case $target in
|
||||
frontend|fe|f)
|
||||
start_frontend
|
||||
;;
|
||||
backend|be|b)
|
||||
# Ensure .env is correct
|
||||
cp "$SCRIPT_DIR/data-entry-app/backend/.env.prod" "$SCRIPT_DIR/data-entry-app/backend/.env" 2>/dev/null || true
|
||||
start_backend
|
||||
;;
|
||||
all|"")
|
||||
start_all
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown target: $target (use: frontend, backend, all)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
pkill -f "uvicorn.*data-entry" 2>/dev/null || true
|
||||
pkill -f "vite.*3010" 2>/dev/null || true
|
||||
restart_services() {
|
||||
local target=${1:-all}
|
||||
|
||||
print_success "All Data Entry PRODUCTION services stopped!"
|
||||
exit 0
|
||||
case $target in
|
||||
frontend|fe|f)
|
||||
stop_frontend
|
||||
sleep 1
|
||||
start_frontend
|
||||
;;
|
||||
backend|be|b)
|
||||
stop_backend
|
||||
sleep 1
|
||||
start_backend
|
||||
;;
|
||||
all|"")
|
||||
stop_services all
|
||||
sleep 2
|
||||
start_all
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown target: $target (use: frontend, backend, all)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_status() {
|
||||
@@ -97,9 +253,21 @@ show_usage() {
|
||||
echo -e "${MAGENTA}Data Entry App - PRODUCTION Starter${NC}"
|
||||
echo
|
||||
echo "Usage:"
|
||||
echo " ./start-data-entry-dev.sh Start all services"
|
||||
echo " ./start-data-entry-dev.sh stop Stop all services"
|
||||
echo " ./start-data-entry-dev.sh status Show status"
|
||||
echo " ./start-data-entry-dev.sh Start all services"
|
||||
echo " ./start-data-entry-dev.sh stop [target] Stop services"
|
||||
echo " ./start-data-entry-dev.sh start [target] Start services"
|
||||
echo " ./start-data-entry-dev.sh restart [target] Restart services"
|
||||
echo " ./start-data-entry-dev.sh status Show status"
|
||||
echo
|
||||
echo "Targets:"
|
||||
echo " frontend, fe, f Frontend only (Vue.js on port 3010)"
|
||||
echo " backend, be, b Backend only (FastAPI on port 8003)"
|
||||
echo " all (default) All services"
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " ./start-data-entry-dev.sh restart frontend Restart only frontend"
|
||||
echo " ./start-data-entry-dev.sh stop backend Stop only backend"
|
||||
echo " ./start-data-entry-dev.sh start fe Start frontend (short)"
|
||||
echo
|
||||
echo "Environment:"
|
||||
echo " Oracle Server: 10.0.20.36 (PRODUCTION)"
|
||||
@@ -109,116 +277,95 @@ show_usage() {
|
||||
echo
|
||||
}
|
||||
|
||||
start_all() {
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
echo -e "${MAGENTA}═══════════════════════════════════════════${NC}"
|
||||
echo -e "${MAGENTA} Data Entry App - PRODUCTION Environment${NC}"
|
||||
echo -e "${MAGENTA} Oracle: 10.0.20.36 | DB: receipts_prod.db${NC}"
|
||||
echo -e "${MAGENTA}═══════════════════════════════════════════${NC}"
|
||||
echo
|
||||
|
||||
# Step 1: Stop any TEST tunnel and start PRODUCTION tunnel
|
||||
print_message "1. Setting up SSH Tunnel (PRODUCTION)..."
|
||||
./ssh-tunnel-test.sh stop 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
if ./ssh_tunnel.sh start; then
|
||||
print_success "SSH Tunnel to PRODUCTION (10.0.20.36) started"
|
||||
else
|
||||
print_error "Failed to start SSH tunnel"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
|
||||
# Step 2: Copy PRODUCTION .env
|
||||
print_message "2. Loading PRODUCTION environment..."
|
||||
cp data-entry-app/backend/.env.prod data-entry-app/backend/.env
|
||||
print_success "Loaded .env.prod (receipts_prod.db)"
|
||||
|
||||
# Step 3: Start Frontend
|
||||
print_message "3. Starting Frontend..."
|
||||
start_frontend
|
||||
|
||||
# Step 4: Start Backend
|
||||
print_message "4. Starting Backend..."
|
||||
start_backend
|
||||
|
||||
# Summary
|
||||
echo
|
||||
echo -e "${GREEN}═══════════════════════════════════════════${NC}"
|
||||
echo -e "${GREEN} Data Entry PRODUCTION Environment Ready!${NC}"
|
||||
echo -e "${GREEN}═══════════════════════════════════════════${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}Services:${NC}"
|
||||
echo " • SSH Tunnel: 10.0.20.36 (PRODUCTION)"
|
||||
echo " • Backend: http://localhost:8003"
|
||||
echo " • Frontend: http://localhost:3010"
|
||||
echo " • API Docs: http://localhost:8003/docs"
|
||||
echo
|
||||
echo -e "${BLUE}Database:${NC}"
|
||||
echo " • SQLite: data/receipts_prod.db"
|
||||
echo " • Test Company: ROMFAST (company_id=114)"
|
||||
echo
|
||||
echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}"
|
||||
echo
|
||||
|
||||
wait
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
case $1 in
|
||||
stop) stop_services ;;
|
||||
status) show_status; exit 0 ;;
|
||||
help|--help|-h) show_usage; exit 0 ;;
|
||||
"") ;; # Continue to start
|
||||
*) print_error "Unknown: $1"; show_usage; exit 1 ;;
|
||||
stop)
|
||||
stop_services "$2"
|
||||
exit 0
|
||||
;;
|
||||
start)
|
||||
if [ -z "$2" ] || [ "$2" = "all" ]; then
|
||||
start_all
|
||||
else
|
||||
start_services "$2"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
restart)
|
||||
restart_services "$2"
|
||||
exit 0
|
||||
;;
|
||||
status)
|
||||
show_status
|
||||
exit 0
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
"")
|
||||
start_all
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown command: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
echo -e "${MAGENTA}═══════════════════════════════════════════${NC}"
|
||||
echo -e "${MAGENTA} Data Entry App - PRODUCTION Environment${NC}"
|
||||
echo -e "${MAGENTA} Oracle: 10.0.20.36 | DB: receipts_prod.db${NC}"
|
||||
echo -e "${MAGENTA}═══════════════════════════════════════════${NC}"
|
||||
echo
|
||||
|
||||
# Step 1: Stop any TEST tunnel and start PRODUCTION tunnel
|
||||
print_message "1. Setting up SSH Tunnel (PRODUCTION)..."
|
||||
./ssh-tunnel-test.sh stop 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
if ./ssh_tunnel.sh start; then
|
||||
print_success "SSH Tunnel to PRODUCTION (10.0.20.36) started"
|
||||
else
|
||||
print_error "Failed to start SSH tunnel"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
|
||||
# Step 2: Copy PRODUCTION .env
|
||||
print_message "2. Loading PRODUCTION environment..."
|
||||
cp data-entry-app/backend/.env.prod data-entry-app/backend/.env
|
||||
print_success "Loaded .env.prod (receipts_prod.db)"
|
||||
|
||||
# Step 3: Start Frontend
|
||||
print_message "3. Starting Frontend (Vue.js)..."
|
||||
|
||||
cd data-entry-app/frontend/
|
||||
|
||||
if [ ! -d "node_modules" ] || [ -f "node_modules/.bin/vite.cmd" ]; then
|
||||
print_message "Installing frontend dependencies..."
|
||||
rm -rf node_modules package-lock.json 2>/dev/null
|
||||
npm install
|
||||
fi
|
||||
|
||||
npm run dev -- --port 3010 > /tmp/data_entry_frontend.log 2>&1 &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
for i in {1..15}; do
|
||||
if check_port 3010; then
|
||||
print_success "Frontend started on http://localhost:3010"
|
||||
break
|
||||
fi
|
||||
[ $i -eq 15 ] && { print_error "Frontend failed"; cat /tmp/data_entry_frontend.log; cleanup; }
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Step 4: Start Backend
|
||||
print_message "4. Starting Backend (FastAPI)..."
|
||||
|
||||
cd ../backend/
|
||||
|
||||
if [ ! -d "venv" ]; then
|
||||
print_message "Creating virtual environment..."
|
||||
python3 -m venv venv
|
||||
fi
|
||||
|
||||
source venv/bin/activate
|
||||
|
||||
if ! python -c "import fastapi, uvicorn, sqlmodel" 2>/dev/null; then
|
||||
print_message "Installing backend dependencies..."
|
||||
pip install --upgrade pip > /dev/null 2>&1
|
||||
pip install -r requirements.txt
|
||||
fi
|
||||
|
||||
mkdir -p data/uploads
|
||||
|
||||
print_message "Running migrations..."
|
||||
alembic upgrade head 2>/dev/null || print_warning "Migrations may already be applied"
|
||||
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8003 --reload > /tmp/data_entry_backend.log 2>&1 &
|
||||
BACKEND_PID=$!
|
||||
|
||||
for i in {1..20}; do
|
||||
if check_port 8003; then
|
||||
print_success "Backend started on http://localhost:8003"
|
||||
break
|
||||
fi
|
||||
[ $i -eq 20 ] && { print_error "Backend failed"; cat /tmp/data_entry_backend.log; cleanup; }
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Summary
|
||||
echo
|
||||
echo -e "${GREEN}═══════════════════════════════════════════${NC}"
|
||||
echo -e "${GREEN} Data Entry PRODUCTION Environment Ready!${NC}"
|
||||
echo -e "${GREEN}═══════════════════════════════════════════${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}Services:${NC}"
|
||||
echo " • SSH Tunnel: 10.0.20.36 (PRODUCTION)"
|
||||
echo " • Backend: http://localhost:8003"
|
||||
echo " • Frontend: http://localhost:3010"
|
||||
echo " • API Docs: http://localhost:8003/docs"
|
||||
echo
|
||||
echo -e "${BLUE}Database:${NC}"
|
||||
echo " • SQLite: data/receipts_prod.db"
|
||||
echo " • Test Company: ROMFAST (company_id=114)"
|
||||
echo
|
||||
echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}"
|
||||
echo
|
||||
|
||||
wait
|
||||
|
||||
Reference in New Issue
Block a user