スキル一覧に戻る
festion

model-catalog

by festion

Audits local Git repos with GitOps logic

0🍴 0📅 2026年1月22日
GitHubで見るManusで実行

SKILL.md


name: model-catalog description: Use when working with 3D model files (STL), print tracking, slicer profiles, or managing the model-catalog homelab service at model-catalog.internal.lakehouse.wtf

Model Catalog

Overview

A homelab FastAPI service for cataloging 3D models, tracking print history, managing slicer profiles, and storing print photos. Deployed as LXC 210 with Vue.js frontend and REST API.

When to Use

Use this skill when:

  • Uploading or searching for 3D model files (.stl)
  • Tracking print jobs, success rates, or failures
  • Managing PrusaSlicer profiles
  • Querying print statistics
  • Working with the model-catalog service deployment
  • Integrating with PrusaLink/Prusa Connect

Quick Reference

Service Information

ComponentDetails
URLhttps://model-catalog.internal.lakehouse.wtf
ContainerLXC 210 on proxmox3 (192.168.1.211:8000)
FrontendVue 3 + TypeScript (served at /)
API Docs/docs (Swagger UI)
DatabaseSQLite at /var/lib/model-catalog/catalog.db
StorageNFS /mnt/models from TrueNAS

API Endpoints

EndpointMethodPurpose
/api/healthGETHealth check
/api/modelsGET, POSTList/upload models
/api/models/{id}GET, DELETEGet/delete model
/api/models/{id}/fileGETDownload STL file
/api/printsGET, POSTList/create print jobs
/api/prints/{id}GET, PATCHGet/update print
/api/prints/{id}/completePOSTMark print successful
/api/prints/{id}/cancelPOSTCancel print
/api/profilesGET, POSTList/create slicer profiles
/api/profiles/{id}/iniGETDownload profile INI
/api/tagsGET, POSTList/create tags
/api/statsGETOverall statistics
/api/printer/statusGETPrinter status (via PrusaLink)

CLI Commands

The mc CLI is available in the container:

# List models
mc list
mc list --tag "functional-prints"

# Search models
mc search "benchy"

# Add model
mc add /path/to/model.stl --name "Test Print" --tags "test,calibration"

# Show details
mc show <model-id>

# Export model
mc export <model-id> /path/to/output.stl

# Delete model
mc delete <model-id>

# Tag operations
mc tag add <model-id> "new-tag"
mc tag remove <model-id> "old-tag"

Common Workflows

Uploading a Model

Via API:

curl -X POST https://model-catalog.internal.lakehouse.wtf/api/models \
  -F "file=@model.stl" \
  -F "name=My Model" \
  -F "description=Test print" \
  -F "tags=functional,test"

Via CLI (on container):

ssh root@192.168.1.211
mc add /mnt/models/myfile.stl --name "My Model" --tags "functional,test"

Tracking a Print Job

# Start print
curl -X POST https://model-catalog.internal.lakehouse.wtf/api/prints \
  -H "Content-Type: application/json" \
  -d '{
    "model_id": "uuid-here",
    "profile_id": "profile-uuid",
    "notes": "First test print"
  }'

# Complete print (success)
curl -X POST https://model-catalog.internal.lakehouse.wtf/api/prints/{print-id}/complete \
  -H "Content-Type: application/json" \
  -d '{"result": "success", "notes": "Perfect print"}'

# Mark failed
curl -X POST https://model-catalog.internal.lakehouse.wtf/api/prints/{print-id}/complete \
  -H "Content-Type: application/json" \
  -d '{"result": "failure", "notes": "Layer shifting at 50%"}'

Managing Slicer Profiles

# Import PrusaSlicer profile
curl -X POST https://model-catalog.internal.lakehouse.wtf/api/profiles/import \
  -F "file=@profile.ini" \
  -F "name=PLA Standard"

# List profiles
curl https://model-catalog.internal.lakehouse.wtf/api/profiles

# Download profile INI
curl https://model-catalog.internal.lakehouse.wtf/api/profiles/{id}/ini -o profile.ini

File Locations (Production)

LXC 210 (192.168.1.211):
  /var/lib/model-catalog/catalog.db    # SQLite database
  /opt/model-catalog/                  # Application code
  /etc/model-catalog/env               # Configuration
  /mnt/models/                         # NFS mount (TrueNAS)
    ├── models/{id}/original.stl.zst  # Compressed STL files
    ├── gcode/{id}.gcode.zst           # Generated G-code (temp)
    ├── photos/{id}/finished.jpg       # Print photos
    └── profiles/{id}.ini              # Slicer profiles

TrueNAS:
  /mnt/truenas_nvme/active_projects/model-catalog/  # NFS backing store

Service Management

Check service status:

ssh root@192.168.1.126 "pct exec 210 -- systemctl status model-catalog"

Restart service:

ssh root@192.168.1.126 "pct exec 210 -- systemctl restart model-catalog"

View logs:

ssh root@192.168.1.126 "pct exec 210 -- journalctl -u model-catalog -f"

Update deployment:

# Package updated code
cd /home/dev/workspace/model-catalog
tar czf /tmp/update.tar.gz --exclude='.git' app/ frontend/dist/

# Deploy to container
scp /tmp/update.tar.gz root@192.168.1.126:/tmp/
ssh root@192.168.1.126 "
  pct push 210 /tmp/update.tar.gz /tmp/update.tar.gz
  pct exec 210 -- bash -c 'cd /opt/model-catalog && tar xzf /tmp/update.tar.gz'
  pct exec 210 -- chown -R model-catalog:model-catalog /opt/model-catalog
  pct exec 210 -- systemctl restart model-catalog
"

Architecture

┌─────────────────────────────────────────────────────────────┐
│                         Browser                              │
│  https://model-catalog.internal.lakehouse.wtf               │
└──────────────────┬──────────────────────────────────────────┘
                   │ DNS → 192.168.1.101 (Traefik VIP)
                   ▼
┌─────────────────────────────────────────────────────────────┐
│                    Traefik HA (VIP)                          │
│  Primary: 192.168.1.110 | Secondary: 192.168.1.103          │
└──────────────────┬──────────────────────────────────────────┘
                   │ Proxy → 192.168.1.211:8000
                   ▼
┌─────────────────────────────────────────────────────────────┐
│            LXC 210 (model-catalog) - 192.168.1.211          │
│                                                              │
│  ┌────────────────┐  ┌──────────────────┐                  │
│  │ FastAPI (8000) │  │ Vue.js Frontend  │                  │
│  │   - API        │  │   - /            │                  │
│  │   - /api/*     │  │   - /assets/*    │                  │
│  └────────┬───────┘  └──────────────────┘                  │
│           │                                                  │
│           ▼                                                  │
│  ┌────────────────────────────────────┐                    │
│  │ SQLite (/var/lib/model-catalog/)  │                    │
│  └────────────────────────────────────┘                    │
└─────────────────┬───────────────────────────────────────────┘
                  │ NFS mount → /mnt/models
                  ▼
┌─────────────────────────────────────────────────────────────┐
│                         TrueNAS                              │
│  /mnt/truenas_nvme/active_projects/model-catalog/           │
│    - STL files (zstd compressed)                            │
│    - G-code (temporary, deleted after success)              │
│    - Print photos (JPG from PrusaConnect)                   │
│    - Slicer profiles (INI)                                  │
└─────────────────────────────────────────────────────────────┘

Environment Variables

Set in /etc/model-catalog/env:

VariableDefaultDescription
MC_DATABASE_PATH/var/lib/model-catalog/catalog.dbSQLite database path
MC_STORAGE_PATH/mnt/modelsNFS mount point for files
MC_COMPRESSION_LEVEL3Zstd compression (1-22)
MC_DEBUGfalseEnable debug logging
MC_PRUSASLICER_PATH/usr/bin/prusa-slicerPrusaSlicer CLI path

Integration Examples

From Claude Code

Check if model exists:

curl -s https://model-catalog.internal.lakehouse.wtf/api/models?search=benchy | jq '.items[0]'

Upload from local file:

curl -X POST https://model-catalog.internal.lakehouse.wtf/api/models \
  -F "file=@/path/to/model.stl" \
  -F "name=$(basename model.stl .stl)" \
  -F "tags=claude-generated"

Get print statistics:

curl -s https://model-catalog.internal.lakehouse.wtf/api/stats | jq

From Automation Scripts

Track automated print:

import httpx

async with httpx.AsyncClient() as client:
    # Create print job
    response = await client.post(
        "https://model-catalog.internal.lakehouse.wtf/api/prints",
        json={
            "model_id": model_uuid,
            "profile_id": profile_uuid,
            "notes": "Automated nightly print"
        }
    )
    print_id = response.json()["id"]

    # Mark complete when done
    await client.post(
        f"https://model-catalog.internal.lakehouse.wtf/api/prints/{print_id}/complete",
        json={"result": "success"}
    )

Common Issues

Frontend Returns 404

Problem: Root path returns {"detail":"Not Found"}

Solution: Frontend not configured to serve from /. Check:

# Verify frontend files deployed
ssh root@192.168.1.126 "pct exec 210 -- ls -la /opt/model-catalog/frontend/dist/"

# Check if main.py has static file mounting
ssh root@192.168.1.126 "pct exec 210 -- grep -A 5 'StaticFiles' /opt/model-catalog/app/main.py"

Service Won't Start

Problem: systemctl status model-catalog shows failed

Solution: Check logs:

ssh root@192.168.1.126 "pct exec 210 -- journalctl -u model-catalog -n 50"

Common causes:

  • NFS mount not available (/mnt/models missing)
  • Database path not writable
  • Python dependencies missing

Traefik Returns 503

Problem: Traefik route configured but backend unreachable

Solution:

# Check backend is responding
curl http://192.168.1.211:8000/api/health

# Verify Traefik route points to correct IP
ssh root@192.168.1.110 "grep -A 5 'model-catalog:' /etc/traefik/dynamic/model-catalog.yml"

Development

Local development (in workspace):

cd /home/dev/workspace/model-catalog

# Run backend
uvicorn app.main:app --reload --port 8000

# Run frontend dev server (separate terminal)
cd frontend
npm run dev

# Run tests
pytest
pytest --cov=app

Testing API locally:

# Health check
curl http://localhost:8000/api/health

# Interactive docs
open http://localhost:8000/docs
  • Project: /home/dev/workspace/model-catalog/
  • Design Doc: /home/dev/workspace/model-catalog/docs/DESIGN.md
  • Deployment: /home/dev/workspace/model-catalog/docs/DEPLOYMENT.md
  • Acceptance Criteria: /home/dev/workspace/model-catalog/docs/ACCEPTANCE.md
  • Issue Tracking: bd list (beads in /home/dev/workspace/model-catalog/.beads/)

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です