9.0 KiB
Development setup: from clone to first change
The goal of this page: a new developer clones the repo and has a working dev
site plus a change they can see in the browser, in one sitting. Reference
material lives elsewhere - naming rules in CONTRIBUTING.md, every config
variable in the CONFIG guide, plugin authoring in the PLUGIN docs - this is
just the on-ramp.
Most developers here are on Windows in VS Code - commands below are PowerShell first, with the bash equivalent in a comment where they differ. Install Git for Windows (it ships Git Bash, which VS Code and the git hooks use to run the shell-based naming check) and VS Code with the extensions this repo recommends (you'll be prompted - section 2c).
Two ways to run it. Docker (Docker Desktop on Windows) is the fastest to a working site. Manual (venv + Node) is the daily driver - frontend hot-reloads, backend restarts on save. Do Docker once to confirm the box is sane, then use manual for day-to-day work.
0. Prerequisites
| Need | Version | Check |
|---|---|---|
| Python | 3.12 (64-bit) | python --version |
| Node.js | 18+ | node --version |
| MySQL | 8.0 (or Docker, below) | mysql --version |
| Git | any recent | git --version |
1. Get the code
git clone https://github.com/ge-aero/shopdb-flask.git
cd shopdb-flask
Never work on main. Branch for your change:
git checkout -b feat/<short-description>
2a. Fast path - Docker (a working site in one command)
copy .env.example .env
# Edit .env: set SECRET_KEY, JWT_SECRET_KEY, and the MYSQL_* passwords.
# Generate a secret: python -c "import secrets;print(secrets.token_urlsafe(64))"
docker compose up -d --build # MySQL + the app (frontend built in-image)
# Schema + platform data (idempotent, safe to re-run):
docker compose exec api flask db upgrade
docker compose exec api flask plugin upgrade-all
docker compose exec api flask seed permissions
docker compose exec api flask seed settings
docker compose exec api flask seed reference-data
docker compose exec api flask seed admin --username admin --email you@example.com
The app is on the port the compose file maps (see docker-compose.yml). Good
for a smoke test; for active development use the manual path so the frontend
hot-reloads.
2b. Manual path - venv + Node (the daily driver)
Database
Either point at an existing MySQL 8, or bring one up with just the db service from compose:
docker compose up -d db # MySQL on 127.0.0.1:3306
Create the database + app user (skip if compose already did via env):
CREATE DATABASE shopdb_flask CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'shopdb'@'%' IDENTIFIED BY 'devpassword';
GRANT ALL PRIVILEGES ON shopdb_flask.* TO 'shopdb'@'%';
FLUSH PRIVILEGES;
Backend
python -m venv venv
venv\Scripts\Activate.ps1 # bash/mac: source venv/bin/activate
# If PowerShell blocks the activate script (execution policy), run once:
# Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
pip install -r requirements.txt
copy .env.example .env # bash/mac: cp .env.example .env
# Edit .env - set SECRET_KEY, JWT_SECRET_KEY, and
# DATABASE_URL=mysql+pymysql://shopdb:devpassword@127.0.0.1:3306/shopdb_flask?charset=utf8mb4
# CORS_ORIGINS=http://localhost:5173
$env:FLASK_APP = "shopdb" # bash/mac: export FLASK_APP=shopdb
flask db upgrade # core schema
flask plugin upgrade-all # per-plugin schema (ADR-008)
flask seed permissions
flask seed settings
flask seed reference-data
flask seed admin --username admin --email you@example.com # password printed once
Enable the plugins you want visible (they install on a fresh box; some ship disabled). To turn on everything for development:
PowerShell:
foreach ($p in "computers","employees","machines","measuringtools","network",
"notifications","printers","slides","usb","warranty",
"knowledgebase","geenforce","printedparts") {
flask plugin install $p; flask plugin enable $p
}
(bash/mac: a for p in ...; do flask plugin install "$p"; ...; done loop.)
Run the backend ON PORT 5001 - the frontend dev server proxies /api and
/static there (a bare flask run uses 5000 and nothing will load):
flask run --port 5001
Frontend (a second terminal)
cd frontend
npm install
npm run dev # http://localhost:5173
Open http://localhost:5173, log in as admin with the printed password.
Convenience: instead of two terminals you can run both under a process manager (pm2, honcho, foreman). Keep the backend on 5001.
2c. VS Code (turnkey)
The repo ships shared VS Code config in .vscode/ (personal settings.json
stays git-ignored):
- Recommended extensions - on first open VS Code offers to install them (Python + Pylance, Vue Volar, ESLint, Docker). Accept.
- Run the dev site - Command Palette > "Tasks: Run Task" > Dev site (backend + frontend) starts both servers in parallel (backend on 5001, frontend on 5173). Individual tasks exist too.
- Debug the backend - the Run panel's Flask API (:5001) config runs the app under the debugger (breakpoints in routes/services, full stepping); Pytest (current file) debugs the open test file.
- The CI gate - task Check: naming + tests + build runs the same three checks CI runs, before you commit.
Prerequisite: the venv and npm install from 2b must be done first (the
tasks call venv/ and frontend/node_modules).
3. The development loop
-
Make a change. Backend:
flask runauto-reloads. Frontend: Vite hot-reloads. -
Before committing, run the three gates. Easiest: in VS Code, Command Palette > "Tasks: Run Task" > Check: naming + tests + build. By hand in PowerShell:
venv\Scripts\python -m pytest tests/ -q # backend cd frontend; npx vitest run; npm run build; cd .. bash scripts/check-naming-and-style.sh # naming - runs via Git BashThere is NO auto-installed git hook - you run these yourself (or the VS Code task). On the internal server, CI runs all three on every push and fails the build on a bad name. GitHub Actions is not set up on the public mirror yet, so if you develop against GitHub these local checks (or the opt-in hook below) are your only gate - run them. The naming check is a shell script, so that one line needs Git Bash (installed with Git for Windows).
Want it automatic? The repo ships a hook; enable it once per clone:
git config core.hooksPath .githooksNow every
git commitruns the naming check first (Git for Windows executes the hook under its bundled bash) and blocks the commit if a name is wrong. Purely local convenience; CI is the real backstop. -
Commit in small, working steps. Subject: short, present tense, plain English; body says WHY. Read
CONTRIBUTING.mdbefore naming anything - the naming hook will reject snake_case DB columns, banned shorthand, and non-ASCII.
Seeing a change in the real app (not just tests) is the bar for "done" - drive the actual flow in the browser.
4. Your first change (suggested)
Add a field to an existing list page, or better, build a plugin end to end:
docs/PLUGIN-LAB-PRINTEDPARTS.md is a literal type-along that constructs the
3D-printed-parts plugin from scratch, with the finished code on branch
feat/printedparts-plugin (tags lab-stage-01..lab-stage-17) as the
answer key. It touches every hook the framework has.
5. Contributing back
git push -u origin feat/<short-description>
Open a Pull Request against main on GitHub. Describe what changed, any
plugin hooks implemented, and any contract additions (those need a version
bump + docs/PLUGIN-HOOKS.md update in the same PR). See the contributor
section of the plugin lab for the full review checklist.
Common setup problems
| Symptom | Cause / fix |
|---|---|
| Frontend loads but every API call fails / CORS error | backend not on 5001 (flask run --port 5001), or CORS_ORIGINS missing http://localhost:5173. |
| App refuses to boot in production config | a required .env var (SECRET_KEY, JWT_SECRET_KEY, DATABASE_URL, CORS_ORIGINS) missing or a dev default. |
flask db upgrade error 1071 (key too long) |
MySQL 5.6 without the innodb_large_prefix/Barracuda flags; use MySQL 8 for dev. |
| Nav missing Machines/PCs/... | plugins not installed/enabled (step 2b), or the backend not restarted after enabling. |
| "No time zone found with key America/New_York" | tzdata not installed - pip install -r requirements.txt includes it. |
| Naming hook rejects a commit | you used snake_case on a DB-mirrored field or a banned acronym - see CONTRIBUTING.md. |
| Plugin toggle throws an internal error | app cannot write instance/ (the plugin registry lives there) - fix directory permissions. |