Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

WorkshopOS

Tool inventory, drawer/toolbox organization, and 3D-printable magnetic label generation for home and pro workshops. Ground-zero rebuild of Workshop-Designer, new schema/API/UI, with the parametric label/magnet-pocket geometry engine ported over as working, validated code.

Milestone 1 scope: auth, organizations/shops/toolboxes/drawers/tools CRUD, the 5 profile/preset types (printer, magnet, material, drawer, label style), plan limit enforcement, and the geometry package ported and importable (not yet wired to a route). See ARCHITECTURE.md for the full system design and /home/terry/.claude/plans/sleepy-wandering-nest.md for the original build plan this repo implements.

Stack

  • Frontend: React + TypeScript + Vite, Tailwind + shadcn/ui, dark-mode-default
  • Backend: Python 3.12, FastAPI, SQLAlchemy 2 (async), Alembic, asyncpg, Pydantic v2
  • Jobs: Redis + Dramatiq (geometry generation runs off the request thread — see ARCHITECTURE.md)
  • Geometry: workshop_geometry — trimesh + shapely + matplotlib + manifold3d, ported verbatim from Workshop-Designer/geometry
  • DB: PostgreSQL 16
  • Deploy: Docker Compose, Caddy + Cloudflared reverse proxy (applied separately, not part of this repo)

Local development

Prerequisites

  • Docker + Docker Compose
  • (Optional, for running backend/geometry tests outside containers) Python 3.12

Run the full stack

cp .env.example .env
# edit .env: set real POSTGRES_PASSWORD and JWT_SECRET before anything but local testing

docker compose up --build

This brings up 6 containers: workshopos-postgres, workshopos-redis, workshopos-migrate (runs alembic upgrade head then exits 0), workshopos-api, workshopos-worker, workshopos-frontend.

The app is served at http://localhost:${APP_PORT:-3027}. The frontend's nginx proxies /api/ and /health to the API container; the API itself listens on :8000 internally.

Bring it down

docker compose down

Postgres/Redis data persist in named volumes (workshopos-postgres-data, workshopos-redis-data) across restarts; docker compose down -v wipes them.

Lifecycle scripts

Standard install.sh / start.sh / stop.sh / restart.sh / update.sh scripts are generated by this homelab's scriptupdate.sh and follow the same conventions as sibling apps (e.g. cardforge-v2).

Backend development (outside Docker)

cd backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt -e ../geometry

# Point at a real Postgres instance (docker run a throwaway one, or use the
# compose postgres service published locally).
export DATABASE_URL=postgresql+asyncpg://workshopos:workshopos@localhost:5432/workshopos
export JWT_SECRET=dev-secret

alembic upgrade head
uvicorn app.main:app --reload

Tests

cd backend
pytest              # needs a live Postgres reachable at $DATABASE_URL (see conftest.py)
pytest ../geometry   # pure-Python, no DB required

Auth model

POST /auth/register creates an Organization (with a unique slug and the free Plan), a User, and an owner Membership in one transaction, and returns a JWT. Every other route that touches organization-scoped data is nested under /organizations/{organization_id}/... and depends on get_current_membership, which requires a real Membership row tying the authenticated user to that organization_id — the API never trusts a client-supplied org id on its own. See ARCHITECTURE.md for why this matters (it fixes a real vulnerability in the prior codebase).

Plans / limits

Two plans are seeded by the initial migration:

plan max_shops max_toolboxes max_drawers max_users
free 1 1 5 1
pro unlimited unlimited unlimited unlimited

Creating past a limit returns 402 Payment Required. Billing/license-key infrastructure beyond the Plan table itself is out of scope for this milestone.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages