Establishes the framework's foundation as a multi-site adoptable platform. ADRs (migrations/adr/): - ADR-001 (ACCEPTED): Asset is the platform contract; Machine retires. Three relationship types (partof, controls, connectedto) with free-text label, position-resolution chain (asset > related > location), hierarchical locations, sibling-bay propagation. - ADR-002 (ACCEPTED): Plugin contract semver via __contract_version__. - ADR-003 (ACCEPTED): Hybrid plugin distribution (in-tree bundled + filesystem-based external). - ADR-004 (ACCEPTED): Per-site instances, not multi-tenant. - ADR-005 (ACCEPTED): Equipment plugin (manufacturing) split from measuringtools plugin (metrology). Subtype-table pattern for protocol data (FOCAS, CLM, MTConnect). - ADR-006 (ACCEPTED): Plugin collector contract via get_collector_schema hook with API-key auth and identity-based upsert. Naming convention v1 (CONTRIBUTING.md): - DB tables/columns: lowercase concatenated, no underscores or dashes - DB-mirrored Python/JS variables match column names exactly; pure code follows host-language convention (PEP 8 / camelCase) - Closed acronym allowlist (universal + shop-floor domain), banned shorthand list with suffix exception (printers_bp etc allowed) - Plain ASCII everywhere: chat, docs, comments, string literals Style enforcement (scripts/check-naming-and-style.sh): - Pre-commit-runnable check script: non-ASCII, banned shorthand, snake_case DB names, snake_case API params in frontend - Fixes 14 violations across 11 files (Unicode arrows, snake_case params, ctx -> canvasContext, res -> response, req -> request_obj) Project state (CLAUDE.md, README.md, frontend/CLAUDE.md): - De-staled CLAUDE.md to reflect actual current state - README unifies DB story (MySQL canonical, SQLite test-only) - frontend/CLAUDE.md points at root convention Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
201 lines
6.0 KiB
Markdown
201 lines
6.0 KiB
Markdown
# 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`
|
|
- **Column names:** Lowercase, single word, no underscores or dashes
|
|
- Examples: `machineid`, `machinenumber`, `pctypeid`, `isactive`, `createddate`
|
|
- **Foreign keys:** Referenced table name + `id`
|
|
- Examples: `locationid`, `vendorid`, `modelnumberid`, `pctypeid`
|
|
- **Boolean columns:** Prefixed with `is` or `has`
|
|
- Examples: `isactive`, `isshopfloor`, `isvnc`, `iswinrm`, `islicenced`
|
|
|
|
### 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`
|
|
- **Query parameters:** Lowercase, single word
|
|
- Examples: `?type=pc`, `?locationid=5`, `?isactive=true`
|
|
|
|
## 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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`):
|
|
|
|
```bash
|
|
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 field
|
|
- `order` - Sort direction (asc/desc)
|
|
- `search` - Search term
|
|
- `type` - 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.
|