mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
chore: remove dead code, add test infrastructure, update docs
- Delete 3 dead files: use-batch-processor.ts, use-i18n.ts, smart-crop.ts (AI package) - Remove dead getJobProgress function and unused runPythonScript wrapper - Remove 6 unused imports across API and web apps - Remove unused shared types (ImageFormat, AppConfig, ApiError, HealthResponse, JobProgress) and constants (SUPPORTED_INPUT_FORMATS/OUTPUT_FORMATS, DEFAULT_OUTPUT_FORMAT) - Remove unused store method (setOriginalBlobUrl) and clean AI package re-exports - Add test infrastructure: vitest config, unit/integration/e2e tests, fixtures, screenshots - Add Docker test infrastructure: Dockerfile.test, docker-compose.test.yml - Add download_models.py for pre-baking AI model weights in Docker - Add filename sanitization utility (apps/api/src/lib/filename.ts) - Update .gitignore to exclude coverage/, *.tsbuildinfo, .superpowers/, test artifacts - Update .dockerignore to exclude test/coverage/IDE artifacts from builds - Update docs: remove smart crop from AI docs (uses Sharp directly), update bridge docs
This commit is contained in:
+11
-8
@@ -67,16 +67,14 @@ RUN /opt/venv/bin/pip install --no-cache-dir --upgrade pip && \
|
||||
(/opt/venv/bin/pip install --no-cache-dir lama-cleaner || echo "WARNING: lama-cleaner not installed - object eraser will be unavailable") && \
|
||||
rm /tmp/requirements.txt
|
||||
|
||||
# Remove build tools no longer needed in production
|
||||
RUN apt-get purge -y --auto-remove build-essential python3-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Pre-download ALL AI model weights into the image (no first-use download delays)
|
||||
# This makes the Docker image fully self-contained — works offline
|
||||
RUN /opt/venv/bin/python3 -c "\
|
||||
from rembg import new_session; \
|
||||
print('Downloading BiRefNet-Lite model (SOTA, fast)...'); \
|
||||
new_session('birefnet-general-lite'); \
|
||||
print('Downloading u2net model (fallback)...'); \
|
||||
new_session('u2net'); \
|
||||
print('Background removal models ready') \
|
||||
" 2>/dev/null || echo "WARNING: Could not pre-download rembg models"
|
||||
COPY docker/download_models.py /tmp/download_models.py
|
||||
RUN /opt/venv/bin/python3 /tmp/download_models.py && rm /tmp/download_models.py
|
||||
|
||||
RUN /opt/venv/bin/python3 -c "\
|
||||
try: \
|
||||
@@ -138,6 +136,11 @@ ENV PORT=1349 \
|
||||
MAX_MEGAPIXELS=100 \
|
||||
RATE_LIMIT_PER_MIN=100
|
||||
|
||||
# Run as non-root user for security
|
||||
RUN groupadd -r stirling && useradd -r -g stirling -d /app -s /sbin/nologin stirling
|
||||
RUN chown -R stirling:stirling /app /data /tmp/workspace /opt/venv
|
||||
USER stirling
|
||||
|
||||
EXPOSE 1349
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# ============================================
|
||||
# Stirling Image - Test Dockerfile
|
||||
# Runs the full test suite (unit + integration)
|
||||
# ============================================
|
||||
|
||||
FROM node:22-bookworm
|
||||
|
||||
RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy workspace config first (for layer caching)
|
||||
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json turbo.json tsconfig.base.json vitest.config.ts ./
|
||||
|
||||
# Copy all package.json files
|
||||
COPY apps/web/package.json apps/web/tsconfig.json apps/web/vite.config.ts ./apps/web/
|
||||
COPY apps/api/package.json apps/api/tsconfig.json ./apps/api/
|
||||
COPY packages/shared/package.json packages/shared/tsconfig.json ./packages/shared/
|
||||
COPY packages/image-engine/package.json packages/image-engine/tsconfig.json ./packages/image-engine/
|
||||
COPY packages/ai/package.json packages/ai/tsconfig.json ./packages/ai/
|
||||
|
||||
# Install ALL dependencies (including devDependencies for testing)
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Environment for tests
|
||||
ENV NODE_ENV=test \
|
||||
AUTH_ENABLED=true \
|
||||
DEFAULT_USERNAME=admin \
|
||||
DEFAULT_PASSWORD=admin \
|
||||
DB_PATH=/tmp/test-stirling.db \
|
||||
WORKSPACE_PATH=/tmp/test-workspace \
|
||||
MAX_MEGAPIXELS=100 \
|
||||
MAX_UPLOAD_SIZE_MB=100 \
|
||||
MAX_BATCH_SIZE=200 \
|
||||
CONCURRENT_JOBS=3 \
|
||||
RATE_LIMIT_PER_MIN=1000 \
|
||||
FILE_MAX_AGE_HOURS=1 \
|
||||
CLEANUP_INTERVAL_MINUTES=60
|
||||
|
||||
# Run unit + integration tests with coverage
|
||||
CMD ["pnpm", "test:all"]
|
||||
@@ -0,0 +1,48 @@
|
||||
###############################################################################
|
||||
# Test infrastructure - run with:
|
||||
# docker compose -f docker/docker-compose.test.yml up --build --abort-on-container-exit
|
||||
###############################################################################
|
||||
services:
|
||||
# ── Unit + Integration tests ─────────────────────────────────────────────
|
||||
test-unit:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.test
|
||||
container_name: stirling-test-unit
|
||||
command: ["pnpm", "test:ci"]
|
||||
environment:
|
||||
- NODE_ENV=test
|
||||
- AUTH_ENABLED=true
|
||||
- DEFAULT_USERNAME=admin
|
||||
- DEFAULT_PASSWORD=admin
|
||||
- DB_PATH=/tmp/test-stirling.db
|
||||
- WORKSPACE_PATH=/tmp/test-workspace
|
||||
- MAX_MEGAPIXELS=100
|
||||
- RATE_LIMIT_PER_MIN=1000
|
||||
tmpfs:
|
||||
- /tmp/test-workspace
|
||||
- /tmp
|
||||
|
||||
# ── E2E tests (Playwright against full app) ─────────────────────────────
|
||||
test-e2e:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.test
|
||||
container_name: stirling-test-e2e
|
||||
command: ["sh", "-c", "npx playwright install --with-deps chromium && pnpm test:e2e"]
|
||||
environment:
|
||||
- NODE_ENV=test
|
||||
- AUTH_ENABLED=true
|
||||
- DEFAULT_USERNAME=admin
|
||||
- DEFAULT_PASSWORD=admin
|
||||
- DB_PATH=/tmp/test-stirling.db
|
||||
- WORKSPACE_PATH=/tmp/test-workspace
|
||||
- MAX_MEGAPIXELS=100
|
||||
- RATE_LIMIT_PER_MIN=1000
|
||||
- CI=true
|
||||
tmpfs:
|
||||
- /tmp/test-workspace
|
||||
- /tmp
|
||||
depends_on:
|
||||
test-unit:
|
||||
condition: service_completed_successfully
|
||||
@@ -0,0 +1,27 @@
|
||||
"""Pre-download all rembg models offered in the UI."""
|
||||
import sys
|
||||
|
||||
MODELS = [
|
||||
"u2net",
|
||||
"isnet-general-use",
|
||||
"bria-rmbg",
|
||||
"birefnet-general-lite",
|
||||
"birefnet-portrait",
|
||||
"birefnet-general",
|
||||
]
|
||||
|
||||
try:
|
||||
from rembg import new_session
|
||||
except ImportError:
|
||||
print("WARNING: rembg not installed, skipping model pre-download")
|
||||
sys.exit(0)
|
||||
|
||||
for model in MODELS:
|
||||
print(f"Downloading {model}...")
|
||||
try:
|
||||
new_session(model)
|
||||
print(f" {model} ready")
|
||||
except Exception as e:
|
||||
print(f" WARNING: {model} failed: {e}")
|
||||
|
||||
print("Model pre-download complete")
|
||||
Reference in New Issue
Block a user