feat/parameters #1

Merged
JoeKung merged 5 commits from feat/parameters into main 2026-01-29 17:23:39 +01:00
69 changed files with 4240 additions and 0 deletions
Showing only changes of commit 6715d1f75e - Show all commits

137
.gitea/workflows/cicd.yaml Normal file
View File

@@ -0,0 +1,137 @@
name: Build, Test and Deploy
on:
push:
branches:
- main
- int
- dev
jobs:
test-backend:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install -r backend/requirements.txt
pip install pytest httpx
- name: Run Backend Tests
run: |
export PYTHONPATH=$PYTHONPATH:$(pwd)/backend
pytest backend/tests
build-and-push:
needs: test-backend
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set Environment Variables
run: |
if [[ "${{ gitea.ref }}" == "refs/heads/main" ]]; then
echo "TAG=prod" >> $GITHUB_ENV
elif [[ "${{ gitea.ref }}" == "refs/heads/int" ]]; then
echo "TAG=int" >> $GITHUB_ENV
else
echo "TAG=dev" >> $GITHUB_ENV
fi
- name: Login to Gitea Registry
uses: docker/login-action@v2
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.GITEA_USER }}
password: ${{ secrets.GITEA_TOKEN }}
- name: Build and Push Backend
uses: docker/build-push-action@v4
with:
context: ./backend
push: true
tags: ${{ secrets.REGISTRY_URL }}/${{ gitea.repository_owner }}/print-calculator-backend:${{ env.TAG }}
- name: Build and Push Frontend
uses: docker/build-push-action@v4
with:
context: ./frontend
push: true
tags: ${{ secrets.REGISTRY_URL }}/${{ gitea.repository_owner }}/print-calculator-frontend:${{ env.TAG }}
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set Deployment Vars
run: |
if [[ "${{ gitea.ref }}" == "refs/heads/main" ]]; then
echo "ENV=prod" >> $GITHUB_ENV
echo "TAG=prod" >> $GITHUB_ENV
elif [[ "${{ gitea.ref }}" == "refs/heads/int" ]]; then
echo "ENV=int" >> $GITHUB_ENV
echo "TAG=int" >> $GITHUB_ENV
else
echo "ENV=dev" >> $GITHUB_ENV
echo "TAG=dev" >> $GITHUB_ENV
fi
- name: Create Remote Directory
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: mkdir -p /mnt/user/appdata/print-calculator/${{ env.ENV }}/
- name: Copy Compose File to Server
uses: appleboy/scp-action@v0.1.4
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "docker-compose.deploy.yml"
target: "/mnt/user/appdata/print-calculator/${{ env.ENV }}/"
- name: Copy Env File to Server
uses: appleboy/scp-action@v0.1.4
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "deploy/envs/${{ env.ENV }}.env"
target: "/mnt/user/appdata/print-calculator/${{ env.ENV }}/.env"
- name: Execute Remote Deployment
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /mnt/user/appdata/print-calculator/${{ env.ENV }}/
# Rename the copied env file to strictly '.env' so docker compose picks it up automatically
mv ${{ env.ENV }}.env .env
# Login to registry
echo ${{ secrets.GITEA_TOKEN }} | docker login ${{ secrets.REGISTRY_URL }} -u ${{ secrets.GITEA_USER }} --password-stdin
# Pull new images
# We force reading from .env just to be safe, though default behavior does it too.
docker compose --env-file .env -f docker-compose.deploy.yml pull
# Start/Update services
# TAG is inside .env now, so we don't even need to pass it explicitly!
docker compose --env-file .env -f docker-compose.deploy.yml up -d --remove-orphans

38
GEMINI.md Normal file
View File

@@ -0,0 +1,38 @@
# GEMINI Project Context
Questo file serve a dare contesto all'AI (Antigravity/Gemini) sulla struttura e logica del progetto.
## Project Overview
**Nome**: Print Calculator
**Scopo**: Calcolare costi e tempi di stampa 3D da file STL.
**Stack**:
- **Backend**: Python (FastAPI), libreria `trimesh` per analisi geometrica.
- **Frontend**: Angular 19 (TypeScript).
## Architecture
### Backend (`/backend`)
- **`main.py`**: Entrypoint dell'applicazione FastAPI.
- Definisce l'API `POST /calculate/stl`.
- Gestisce l'upload del file, invoca lo slicer e restituisce il preventivo.
- Configura CORS per permettere chiamate dal frontend.
- **`slicer.py`**: Wrappa l'eseguibile di **OrcaSlicer** per effettuare lo slicing reale del modello.
- Gestisce i profili di stampa (Macchina, Processo, Filamento).
- Crea configurazioni on-the-fly per supportare mesh di grandi dimensioni.
- **`calculator.py`**: Analizza il G-Code generato.
- `GCodeParser`: Estrae tempo di stampa e materiale usato dai metadati del G-Code.
- `QuoteCalculator`: Applica i costi (orari, energia, materiale) per generare il prezzo finale.
### Frontend (`/frontend`)
- Applicazione Angular standard.
- Usa Angular Material.
- Service per upload STL e visualizzazione preventivo.
## Key Concepts
- **Real Slicing**: Il backend esegue un vero slicing usando OrcaSlicer in modalità headless. Questo garantisce stime di tempo e materiale estremamente precise, identiche a quelle che si otterrebbero preparando il file per la stampa.
- **G-Code Parsing**: Invece di stimare geometricamente, l'applicazione legge direttamene i commenti generati dallo slicer nel G-Code (es. `estimated printing time`, `filament used`).
## Development Notes
- Per eseguire il backend serve `uvicorn`.
- Il frontend richiede `npm install` al primo avvio.
- Le configurazioni di stampa (layer height, wall thickness, infill) sono attualmente hardcoded o con valori di default nel backend, ma potrebbero essere esposte come parametri API in futuro.

BIN
backend/.DS_Store vendored Normal file

Binary file not shown.

BIN
backend/obj_3_Hinge.stl Normal file

Binary file not shown.

3986
backend/output/plate_1.gcode Normal file

File diff suppressed because it is too large Load Diff

BIN
backend/profiles/.DS_Store vendored Normal file

Binary file not shown.

BIN
backend/profiles/profiles/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
backend/profiles/profiles/BBL/.DS_Store vendored Normal file

Binary file not shown.

BIN
backend/profiles/profiles/BIQU/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
backend/profiles/profiles/Qidi/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
backend/profiles/profiles/iQ/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

15
deploy/envs/dev.env Normal file
View File

@@ -0,0 +1,15 @@
REGISTRY_URL=git.joekung.ch
REPO_OWNER=JoeKung
ENV=dev
TAG=dev
# Ports
BACKEND_PORT=18002
FRONTEND_PORT=18082
# Application Config
FILAMENT_COST_PER_KG=22.0
MACHINE_COST_PER_HOUR=2.50
ENERGY_COST_PER_KWH=0.30
PRINTER_POWER_WATTS=150
MARKUP_PERCENT=20

15
deploy/envs/int.env Normal file
View File

@@ -0,0 +1,15 @@
REGISTRY_URL=git.joekung.ch
REPO_OWNER=JoeKung
ENV=int
TAG=int
# Ports
BACKEND_PORT=18001
FRONTEND_PORT=18081
# Application Config
FILAMENT_COST_PER_KG=22.0
MACHINE_COST_PER_HOUR=2.50
ENERGY_COST_PER_KWH=0.30
PRINTER_POWER_WATTS=150
MARKUP_PERCENT=20

15
deploy/envs/prod.env Normal file
View File

@@ -0,0 +1,15 @@
REGISTRY_URL=git.joekung.ch
REPO_OWNER=JoeKung
ENV=prod
TAG=prod
# Ports
BACKEND_PORT=8000
FRONTEND_PORT=80
# Application Config
FILAMENT_COST_PER_KG=22.0
MACHINE_COST_PER_HOUR=2.50
ENERGY_COST_PER_KWH=0.30
PRINTER_POWER_WATTS=150
MARKUP_PERCENT=20

34
docker-compose.deploy.yml Normal file
View File

@@ -0,0 +1,34 @@
version: '3.8'
services:
backend:
# L'immagine usa il tag specificato nel file .env o passato da riga di comando
image: ${REGISTRY_URL}/${REPO_OWNER}/print-calculator-backend:${TAG}
container_name: print-calculator-backend-${ENV}
ports:
- "${BACKEND_PORT}:8000"
environment:
- FILAMENT_COST_PER_KG=${FILAMENT_COST_PER_KG}
- MACHINE_COST_PER_HOUR=${MACHINE_COST_PER_HOUR}
- ENERGY_COST_PER_KWH=${ENERGY_COST_PER_KWH}
- PRINTER_POWER_WATTS=${PRINTER_POWER_WATTS}
- MARKUP_PERCENT=${MARKUP_PERCENT}
- TEMP_DIR=/app/temp
- PROFILES_DIR=/app/profiles
restart: unless-stopped
volumes:
- backend_profiles_${ENV}:/app/profiles
frontend:
image: ${REGISTRY_URL}/${REPO_OWNER}/print-calculator-frontend:${TAG}
container_name: print-calculator-frontend-${ENV}
ports:
- "${FRONTEND_PORT}:80"
depends_on:
- backend
restart: unless-stopped
volumes:
backend_profiles_prod:
backend_profiles_int:
backend_profiles_dev: