Lowers the barrier for sister sites to build their own plugins. Generated output satisfies the framework contract out of the box. CLI command (shopdb/plugins/cli.py): - `flask plugin new <name> --description "..."` generates a plugin skeleton under plugins/<name>/. Validates the name against CONTRIBUTING.md rules (lowercase letters/digits only, no underscores or hyphens, not in the reserved list) and refuses to overwrite existing plugins unless --overwrite is passed. - Output prints the next steps (install, migrate, test). Scaffolder (shopdb/plugins/scaffolder.py): - validate_name: enforces the naming rules - pascal_case: lowercase-to-PascalCase for class names - scaffold_plugin: copies templates with string.Template substitution. Three placeholders: $name, $Name, $description. Files with `model.py` in the path get renamed to <name>.py. Templates (shopdb/plugins/templates/): - manifest.json.tmpl: name, version 0.1.0, description, core_version range >=0.1.0,<1.0.0 (broad enough to survive minor framework bumps) - plugin.py.tmpl: <Name>Plugin class extending BasePlugin with all required hooks implemented (meta from manifest, get_blueprint returning the bp, get_models returning the example model). Includes on_install hook that seeds the AssetType row. - models/__init__.py.tmpl + models/model.py.tmpl: Asset extension table keyed by assetid with one example field. TODO comment marks it as a placeholder. - api/__init__.py.tmpl + api/routes.py.tmpl: Blueprint with list and detail endpoints using the framework's pagination + response helpers. - schemas/__init__.py.tmpl: marshmallow schema stub. - tests/__init__.py.tmpl + tests/test_plugin.py.tmpl: smoke tests asserting plugin loads, get_blueprint returns Blueprint, get_models returns at least one model. - README.md.tmpl: one-pager for plugin authors with common edits and next-step references. Canary tests (tests/test_plugin_scaffold.py): - 14 tests asserting the scaffold output passes contract checks. - Validates name rules (lowercase, reserved, hyphens, digits, etc.) - Verifies all expected files generated, manifest fields present. - Loads the generated plugin via PluginLoader (spec_from_file_location bypasses the real `plugins` package shadowing). - Asserts subclasses BasePlugin, get_blueprint returns Blueprint, get_models returns model with __tablename__. - Module-scoped fixture; cleans up sys.modules + SQLAlchemy metadata on teardown to avoid cross-test contamination. Quickstart docs (docs/PLUGIN-QUICKSTART.md): - 30-minute walkthrough: scaffold -> edit model -> add routes -> install -> verify -> add hooks. Cross-links to PLUGIN-HOOKS.md and the ADRs. Includes common-errors table. Test count: 87 -> 101 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ShopDB Flask
A modern rewrite of the classic ASP/VBScript ShopDB application using Flask (Python) and Vue 3. This application manages shop floor machines, PCs, printers, applications, and related infrastructure for manufacturing environments.
Overview
ShopDB tracks and manages:
- Machines - CNC equipment, CMMs, inspection systems, etc.
- PCs - Shopfloor computers, engineering workstations
- Printers - Network printers with Zabbix integration
- Applications - Software deployed across the shop floor
- Knowledge Base - Documentation and troubleshooting guides
Tech Stack
Backend:
- Python 3.x with Flask
- SQLAlchemy ORM
- MySQL 5.6+ database
- JWT authentication
- Plugin architecture for extensibility
Frontend:
- Vue 3 with Composition API
- Vue Router for navigation
- Pinia for state management
- Vite build system
Project Structure
shopdb-flask/
├── shopdb/ # Flask application
│ ├── core/
│ │ ├── api/ # REST API endpoints
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Validation schemas
│ │ └── services/ # Business logic
│ ├── plugins/ # Plugin system
│ └── utils/ # Shared utilities
├── frontend/ # Vue 3 application
│ ├── src/
│ │ ├── api/ # API client
│ │ ├── components/ # Reusable components
│ │ ├── views/ # Page components
│ │ ├── router/ # Route definitions
│ │ └── stores/ # Pinia stores
│ └── public/ # Static assets
├── plugins/ # External plugins
├── database/ # Database schema exports
├── scripts/ # Import and utility scripts
└── tests/ # Test suite
Naming Conventions
To maintain consistency with the legacy ShopDB database and codebase, the following naming standards apply:
Database
- Table names: Lowercase, single word, no underscores or dashes
- Examples:
machines,pctypes,machinetypes,businessunits
- Examples:
- Column names: Lowercase, single word, no underscores or dashes
- Examples:
machineid,machinenumber,pctypeid,isactive,createddate
- Examples:
- Foreign keys: Referenced table name +
id- Examples:
locationid,vendorid,modelnumberid,pctypeid
- Examples:
- Boolean columns: Prefixed with
isorhas- Examples:
isactive,isshopfloor,isvnc,iswinrm,islicenced
- Examples:
Code
- Python variables: Follow database naming where applicable (lowercase, no underscores for model fields)
- JavaScript variables: camelCase for local variables, but match API field names from backend
- Vue components: PascalCase for component names
- CSS classes: Lowercase with dashes for multi-word classes
API
- Endpoints: Lowercase, plural nouns
- Examples:
/api/machines,/api/pctypes,/api/locations
- Examples:
- Query parameters: Lowercase, single word
- Examples:
?type=pc,?locationid=5,?isactive=true
- Examples:
Style Guidelines
- No emojis in code, comments, documentation, or UI
- Keep UI functional and professional
- Dark theme is the default
- Consistent table layouts across all list views
Setup
Prerequisites
- Python 3.8+
- Node.js 18+
- MySQL 5.6+
Backend Setup
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Edit .env with your database credentials
# Run development server
flask run
Frontend Setup
cd frontend
# Install dependencies
npm install
# Run development server
npm run dev
# Build for production
npm run build
Database
ShopDB Flask uses MySQL 5.6+ as the canonical database. SQLite is used only for the test suite (TestingConfig in shopdb/config.py points at an in-memory SQLite). Do not run dev or production against SQLite.
The database schema is exported in database/schema.sql. To initialize:
mysql -u root -p shopdb_flask < database/schema.sql
To import data from the legacy ShopDB MySQL database (one-time, see migrations/DATA_MIGRATION_GUIDE.md):
python scripts/import_from_mysql.py
Configuration
Environment variables (.env):
| Variable | Description |
|---|---|
DATABASE_URL |
MySQL connection string |
SECRET_KEY |
Flask secret key |
JWT_SECRET_KEY |
JWT signing key |
JWT_ACCESS_TOKEN_EXPIRES |
Access token TTL (seconds) |
LOG_LEVEL |
Logging verbosity |
API Documentation
The REST API follows standard conventions:
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/machines |
List machines (filterable by type) |
| GET | /api/machines/:id |
Get machine details |
| POST | /api/machines |
Create machine |
| PUT | /api/machines/:id |
Update machine |
| DELETE | /api/machines/:id |
Soft delete machine |
Query parameters for list endpoints:
page- Page number (default: 1)per_page- Items per page (default: 25)sort- Sort fieldorder- Sort direction (asc/desc)search- Search termtype- Filter by machine type (pc, printer, equipment)
Plugin System
ShopDB supports plugins for extending functionality. See CONTRIBUTING.md for plugin development guidelines.
Current plugins:
- printers - Extended printer management with Zabbix integration
Legacy Migration
This project replicates functionality from the classic ASP/VBScript ShopDB site. Key mappings:
| Legacy | Modern |
|---|---|
| ASP/VBScript | Flask/Python |
| Classic ADO | SQLAlchemy |
| Server-side HTML | Vue 3 SPA |
| Session auth | JWT tokens |
License
Internal use only.