Add development setup guide + shared VS Code config
New docs/DEVELOPMENT-SETUP.md: clone-to-first-change onboarding (Docker fast path, manual venv+Node daily driver, VS Code, the dev loop, first-change pointer at the plugin lab, troubleshooting). Ship .vscode/ launch/tasks/extensions so F5 debugs the backend on 5001 and a task runs both servers; personal settings.json stays ignored. Fix the README manual path - it ran the backend on the default 5000, but the frontend dev server proxies to 5001, so nothing loaded; also add the plugin upgrade-all step and a VS Code pointer.
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -28,7 +28,11 @@ env/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
.vscode/*
|
||||
# Share the team's launch/tasks/extensions; keep personal settings out.
|
||||
!.vscode/launch.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/extensions.json
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
9
.vscode/extensions.json
vendored
Normal file
9
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance",
|
||||
"Vue.volar",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"ms-azuretools.vscode-docker"
|
||||
]
|
||||
}
|
||||
30
.vscode/launch.json
vendored
Normal file
30
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Flask API (:5001)",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "flask",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": {
|
||||
"FLASK_APP": "shopdb",
|
||||
"FLASK_ENV": "development",
|
||||
"FLASK_DEBUG": "1"
|
||||
},
|
||||
"args": ["run", "--port", "5001", "--no-reload"],
|
||||
"jinja": true,
|
||||
"justMyCode": false,
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Pytest (current file)",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "pytest",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["${file}", "-v"],
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
43
.vscode/tasks.json
vendored
Normal file
43
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Backend: flask run (:5001)",
|
||||
"type": "shell",
|
||||
"command": "${workspaceFolder}/venv/bin/flask run --port 5001",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": { "FLASK_APP": "shopdb" }
|
||||
},
|
||||
"windows": {
|
||||
"command": "${workspaceFolder}\\venv\\Scripts\\flask.exe run --port 5001"
|
||||
},
|
||||
"isBackground": true,
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Frontend: npm run dev (:5173)",
|
||||
"type": "shell",
|
||||
"command": "npm run dev",
|
||||
"options": { "cwd": "${workspaceFolder}/frontend" },
|
||||
"isBackground": true,
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Dev site (backend + frontend)",
|
||||
"dependsOn": [
|
||||
"Backend: flask run (:5001)",
|
||||
"Frontend: npm run dev (:5173)"
|
||||
],
|
||||
"dependsOrder": "parallel",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Check: naming + tests + build",
|
||||
"type": "shell",
|
||||
"command": "bash scripts/check-naming-and-style.sh && venv/bin/python -m pytest tests/ -q && cd frontend && npx vitest run && npm run build",
|
||||
"options": { "cwd": "${workspaceFolder}" },
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -148,11 +148,13 @@ pip install -r requirements.txt
|
||||
cp .env.example .env
|
||||
# Edit .env with your database credentials and secrets.
|
||||
|
||||
export FLASK_APP=shopdb
|
||||
flask db upgrade
|
||||
flask plugin upgrade-all # per-plugin schema (ADR-008)
|
||||
flask seed permissions
|
||||
flask seed settings
|
||||
flask seed reference-data
|
||||
flask run
|
||||
flask run --port 5001 # MUST be 5001 - the frontend dev server proxies here
|
||||
|
||||
# Frontend (separate terminal)
|
||||
cd frontend
|
||||
@@ -162,7 +164,10 @@ npm run build # production build into frontend/dist (served by Flask)
|
||||
```
|
||||
|
||||
Complete first-run setup at `/setup`, or run `flask seed admin` for a headless
|
||||
admin account.
|
||||
admin account. The repo ships VS Code config in `.vscode/` (F5 debugs the
|
||||
backend; a "Dev site" task runs both servers). A fuller day-one walkthrough,
|
||||
including VS Code and troubleshooting, is the DEVELOPMENT-SETUP page in the
|
||||
project wiki.
|
||||
|
||||
To import a site's legacy data, use the HTTP import surface: an admin API
|
||||
token plus [docs/IMPORT-API.md](docs/IMPORT-API.md) drive the whole migration
|
||||
|
||||
213
docs/DEVELOPMENT-SETUP.md
Normal file
213
docs/DEVELOPMENT-SETUP.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# 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.
|
||||
|
||||
Two ways to run it. **Docker** is the fastest to a working site (one command
|
||||
brings up MySQL + the app). **Manual (venv + Node)** is what most people
|
||||
iterate with, because the frontend hot-reloads and the backend restarts on
|
||||
save. Do Docker first to confirm the box is sane, then switch to manual for
|
||||
day-to-day work - or go straight to manual if you already have a MySQL.
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ge-aero/shopdb-flask.git
|
||||
cd shopdb-flask
|
||||
```
|
||||
|
||||
Never work on `main`. Branch for your change:
|
||||
|
||||
```bash
|
||||
git checkout -b feat/<short-description>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2a. Fast path - Docker (a working site in one command)
|
||||
|
||||
```bash
|
||||
cp .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:
|
||||
|
||||
```bash
|
||||
docker compose up -d db # MySQL on 127.0.0.1:3306
|
||||
```
|
||||
|
||||
Create the database + app user (skip if compose already did via env):
|
||||
|
||||
```sql
|
||||
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
|
||||
|
||||
```bash
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Windows: venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
cp .env.example .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
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
for p in computers employees machines measuringtools network notifications \
|
||||
printers slides usb warranty knowledgebase geenforce printedparts; do
|
||||
flask plugin install "$p"; flask plugin enable "$p"
|
||||
done
|
||||
```
|
||||
|
||||
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):
|
||||
|
||||
```bash
|
||||
flask run --port 5001
|
||||
```
|
||||
|
||||
### Frontend (a second terminal)
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
1. Make a change. Backend: `flask run` auto-reloads. Frontend: Vite hot-reloads.
|
||||
2. Before committing, run the same three gates CI runs:
|
||||
```bash
|
||||
bash scripts/check-naming-and-style.sh # the LOCKED naming convention
|
||||
venv/bin/python -m pytest tests/ -q # backend
|
||||
cd frontend && npx vitest run && npm run build
|
||||
```
|
||||
3. Commit in small, working steps. Subject: short, present tense, plain
|
||||
English; body says WHY. Read `CONTRIBUTING.md` before 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
|
||||
|
||||
```bash
|
||||
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. |
|
||||
Reference in New Issue
Block a user