Files
Project-SDE-WP-Suite/ONBOARDING.md
n.siegfried d1f0901897 Add discipline strategy, WP sizing, Split-by-Discipline & dashboard
SOP config (Governance step) now sets project discipline policy:
- disciplines list, discipline strategy (single/multi/planner-choice),
  letter instance-suffix style, and a max-hours split threshold.

WP Creator becomes discipline-aware:
- discipline picker; selecting 2+ turns the flat scope into per-discipline
  scope sections, each with its own status (rolls up to least-advanced).
- "Split by Discipline" turns a multi-discipline WP into WP01A/B/C instances
  linked to a kept master (instanceOf/parentNumber/split/children).
- est-hours warning against the SOP split threshold.

New WP Dashboard (header button, home card, ?view=dashboard deep-link):
metrics, status/discipline breakdowns, a gating panel, and a filterable
board with view/edit/issue. Reads localStorage via an API-ready WPData
adapter; masters excluded from counts.

Backend: POST /api/wps/{id}/issue (enforces the constraint gate),
POST /api/wps/{id}/status, GET /api/wps/metrics; work_packages gains
parent_id + issued_at.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 13:29:41 -07:00

156 lines
9.5 KiB
Markdown

# Project Handoff & History
A curated record of where this project is, the decisions behind it, and what's
left — so a teammate (or a fresh Claude Code session) can pick up cleanly. This
is a summary of the working sessions, not a verbatim chat transcript.
_Last updated: 2026-06-15._
## TL;DR — current status
The **Work Package Suite** is an internal tool for Prime Controls construction
projects: configure a project **SOP**, then author **Work Packages** against it.
- **Front end:** static HTML/CSS/JS, no build step. Two tools surfaced from the
home page — *SOP Configuration* and *Work Package Creator* — both living in one
app ([work-package-suite.html](work-package-suite.html)) as two tabs. The
Creator is embedded via `<iframe>` ([wp-creation-index.html](wp-creation-index.html)).
- **Back end (NEW, Phase 1 done):** a Python/FastAPI API + PostgreSQL under
[`server/`](server/) for shared storage of SOPs, Work Packages, and comments.
- **Hosting target:** internal, behind the company firewall. **NGINX** serves the
static site and proxies `/api/` to the Python API. No outbound internet calls.
- **Next up (Phase 2, NOT started):** rewire the front end to read/write the API
instead of browser `localStorage`.
## Architecture
```
browser → NGINX ──serves──> static site (index.html, work-package-suite.html, …)
└─proxy /api/─> Python API (FastAPI, uvicorn/gunicorn :8000) → PostgreSQL
```
Today the front end still stores data in `localStorage`; Phase 2 moves it to the
API. The API is already built and testable on its own.
## Key decisions (and why)
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Tool structure | One app, two tabs (SOP + WP Creator) | Shared state; SOP flows straight into the Creator. Standalone SOP tool was deleted as a duplicate. |
| WP Creator integration | Embedded as an `<iframe>` | The real Creator is a separate, complex app; iframing avoids JS global collisions and reuses it as-is. |
| Discipline on WP types | Removed everywhere | Per request — WP types now carry Enabled / Special Rules / WO Complete Approval only. Also removed the derived Discipline field + trade-code in the Creator. |
| Hosting | Internal **NGINX**, behind firewall | Company requirement. Considered IIS (dropped) and SharePoint (can't host a multi-file app). |
| Database | **PostgreSQL** | Site admin is provisioning it; good JSON support for SOP/WP documents. Code uses SQLAlchemy, so it's portable. |
| Identity | **Name field only** | Trust the internal network; users type their name. No login. |
| Client data model | **Server-backed** (Phase 2 goal) | SOPs/WPs/comments shared across users; `localStorage` becomes a draft cache. |
| Comments transport | API → Postgres | Replaces an earlier Power Automate plan; comments now persist to SQL directly. |
## Timeline (by commit)
| Commit | What it delivered |
|--------|-------------------|
| `c583daa` | Initial import of the WP Suite files. |
| `2af4b58` | Consolidated to two tools (one app, two tabs); restored Rev 0 features — white header, single title, Step Comments in header, usage logs, sample data, APM in Team + Sign-offs, drag-and-drop sequencing, pre-loaded deletable sources, two-card home page, embedded WP Creator. |
| `d2dc6ff` | Removed discipline from WP types and the Creator; removed external Google-Fonts call (firewall hardening); added Export/Import + a central-feedback hook + `DEPLOYMENT.md`. |
| `7186d46` | First pass wiring feedback through an IIS reverse proxy to Power Automate. |
| `3d4402c` | Switched that reverse proxy from IIS to **NGINX**. |
| `a33b777` | **Phase 1 backend**: FastAPI + SQLAlchemy + PostgreSQL (`server/`); NGINX now proxies `/api/` to it; comments persist to SQL; docs rewritten. |
## Repo map
- [index.html](index.html) — home page (two tool cards; SOP card turns green/"Review" when complete).
- [work-package-suite.html](work-package-suite.html) / [work-package-suite-app.js](work-package-suite-app.js) / [work-package-suite-styles.css](work-package-suite-styles.css) — the SOP Configuration tool + WP tab host.
- [wp-creation-index.html](wp-creation-index.html) / [wp-creation-app.js](wp-creation-app.js) / [wp-creation-styles.css](wp-creation-styles.css) — the embedded Work Package Creator.
- [feedback-config.js](feedback-config.js) — `FEEDBACK_ENDPOINT` (`/api/feedback`) + `postFeedback()` helper.
- [`server/`](server/) — FastAPI API (`app.py`), ORM models (`models.py`), DB setup (`db.py`), `requirements.txt`, `.env.example`, and [server/README.md](server/README.md).
- [nginx-wp-suite.conf](nginx-wp-suite.conf) — NGINX site config (static + `/api/` proxy).
- [DEPLOYMENT.md](DEPLOYMENT.md) — end-to-end deploy guide.
## How to run / deploy
- **API + database:** see [server/README.md](server/README.md) (Postgres setup, dev `uvicorn`, prod `gunicorn` + systemd). API docs at `/api/docs`.
- **Front end + proxy:** see [DEPLOYMENT.md](DEPLOYMENT.md) and [nginx-wp-suite.conf](nginx-wp-suite.conf).
- Locally the API runs against a SQLite file with zero config, so it can be tried without Postgres.
## What's done vs. pending
**Done**
- Two-tool consolidation, all Rev 0 feature restorations, discipline removal.
- Firewall hardening (no external calls).
- Export/Import feedback on every surface.
- Phase 1 backend (API + schema) + NGINX proxy + deploy docs.
- **Discipline strategy, sizing, split & dashboard** (branch `feat/wp-discipline-split-dashboard`) — see below.
## Discipline strategy, WP sizing, Split-by-Discipline & Dashboard
Discipline came back — but as a *project policy* set in the SOP, not a fixed
field. The Governance step (SOP config, step 5) now also captures:
- **Disciplines** (default Mechanical / Electrical / Tech) — comma list.
- **Discipline strategy** (`governance.discMode`): `single` (one discipline per
WP), `multi` (one WP bundles disciplines, scope split per discipline), or
`choice` (planner decides per package — build big, split later).
- **Split threshold** (`governance.sizeHoursMax`) — the Creator warns when a
package's est. hours exceed it.
- `governance.instanceSuffix` = `letter` (instances get A/B/C suffixes).
In the **WP Creator** ([wp-creation-app.js](wp-creation-app.js)):
- A **Disciplines** picker (hidden unless the SOP defines disciplines). Pick 2+
and the single flat work-step list becomes **per-discipline scope sections**,
each with its own steps and its own status (e.g. *Issued — Electrical* while
*Mechanical* is still *In Progress*). Overall WP status rolls up to the
least-advanced discipline.
- **⎘ Split by Discipline** turns a multi-discipline package into one instance
per discipline: `WP01-…``WP01A` (Mech), `WP01B` (Elec), `WP01C` (Tech).
Each instance is a single-discipline WP linked to the master via `instanceOf`
/ `parentNumber`; the master is kept as a roll-up (`split:true`, `children:[]`).
- New per-WP fields on the saved object: `disciplines`, `scope` (`{discipline:
[steps]}`), `discStatus`, `instanceOf`, `instanceLabel`, `parentNumber`,
`split`, `children`.
The **Dashboard** (📊 in the Creator header; home card *Work Package Dashboard*;
deep-link `work-package-suite.html?view=dashboard` or `…?view=dashboard#…`):
metrics (total / release-ready / on-hold / overdue / est vs actual hrs),
breakdowns by status & discipline, a **gating panel** (what's blocking each
package), and a filterable board with **view / edit / issue** per package.
Masters are excluded from counts so split hours aren't double-counted.
Data source today is `localStorage` via the `WPData` adapter in
[wp-creation-app.js](wp-creation-app.js) — swap `list()`/`issue()`/`setStatus()`
to `fetch('/api/wps…')` in Phase 2 and the UI is unchanged.
**Backend** ([server/](server/)) gained the matching endpoints:
`POST /api/wps/{id}/issue` (refuses if constraints are open — the AWP gate),
`POST /api/wps/{id}/status`, and `GET /api/wps/metrics`. `work_packages` gained
`parent_id` and `issued_at` columns.
> **Migration caveat:** tables are still auto-created on startup, so the new
> `parent_id` / `issued_at` columns appear on a **fresh** DB only. Before there's
> real data this is fine; once there is, add Alembic (see open question #2) and
> migrate rather than relying on `create_all`.
**Pending — Phase 2: wire the front end to the API**
- SOP: on *SOP Complete*, `POST /api/sops`; on load, `GET /api/sops/latest` to hydrate the Creator (currently uses `localStorage` key `wp_suite_sop`).
- WP Creator: save packages via `POST /api/wps`; list/load via `GET /api/wps`
(currently `localStorage`). It reads the active SOP from `GET /api/sops/latest`.
- Comments already post to `/api/feedback` → the API; the *list* views could be
switched from `localStorage` to `GET /api/comments`.
- Keep `localStorage` as an offline draft cache / fallback.
## Open questions for whoever continues
1. **Projects:** the DB supports many SOPs, but the UI assumes one active SOP
("latest"). Do we need a project picker?
2. **Migrations:** tables are auto-created on startup. Before real data, decide
on Alembic for future schema changes.
3. **Power App view:** if still wanted, point it at the Postgres `comments` /
`work_packages` tables via the on-prem data gateway (no app change needed).
4. **Backups / retention** for the Postgres database (ask the site admin).
## Continuing with Claude Code
Open this repo in Claude Code and start with: *"Read ONBOARDING.md and DEPLOYMENT.md,
then help me with Phase 2 — wiring the front end to the API."* The commit messages
above are a reliable trail of what changed and why.