Add multi-project support: projects entity, picker home page, project context
Projects become the top-level container; SOPs and Work Packages belong to one. Backend: - New projects table + CRUD (/api/projects). - sops.project_id (FK, cascade) and work_packages.project_id added; list/latest/metrics endpoints accept a project_id filter. Front end (now under html/): - project-data.js: shared API-first ProjectData adapter with localStorage fallback + active-project helpers. - Home page: removed "About This Suite"; added a Project picker (create / use sample / select). Tool cards stay hidden until a project is active and carry &project=<id>; hero shows the active project. - Suite reads ?project, resolves it, shows it in the header, and prefills the SOP project fields; passes &project into the WP-creator iframe. - WP creator stamps projectId onto saved packages. SOP/WP localStorage is not yet namespaced per project (next step). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -130,6 +130,42 @@ to `fetch('/api/wps…')` in Phase 2 and the UI is unchanged.
|
||||
> real data this is fine; once there is, add Alembic (see open question #2) and
|
||||
> migrate rather than relying on `create_all`.
|
||||
|
||||
## Multi-project support
|
||||
|
||||
> **Note on layout:** the IT admin moved all static files into **`html/`** and
|
||||
> added a Docker/NGINX deployment (`Dockerfile`, `docker-compose.yml`, `nginx/`).
|
||||
> Front-end paths below are under `html/`. `server/` stayed at the repo root.
|
||||
|
||||
The suite is now multi-project. **Projects are the top-level container**; every
|
||||
SOP and Work Package belongs to one.
|
||||
|
||||
- **Backend:** new `projects` table + CRUD (`/api/projects`). `sops` gained
|
||||
`project_id` (FK, cascade) and `work_packages` gained `project_id`; list/latest/
|
||||
metrics endpoints accept a `project_id` filter.
|
||||
- **Project layer:** [html/project-data.js](html/project-data.js) — a shared,
|
||||
**API-first** `ProjectData` adapter (`list/get/save/remove` hit `/api/projects`)
|
||||
that **falls back to a localStorage mirror** (`wp_projects`) when the API is
|
||||
unreachable, plus active-project helpers (`getActive`/`setActive`, stored in
|
||||
`wp_active_project` / `wp_active_project_obj`).
|
||||
- **Home page** ([html/index.html](html/index.html)): "About This Suite" removed;
|
||||
a **Project** picker added. With no projects it offers *Create Project* / *Use
|
||||
Sample Project*; otherwise a dropdown to select. The tool cards stay hidden
|
||||
until a project is active and then carry `&project=<id>`; the hero shows the
|
||||
active project.
|
||||
- **Suite** ([html/work-package-suite-app.js](html/work-package-suite-app.js)):
|
||||
reads `?project=<id>`, resolves it via `ProjectData`, shows it in the header,
|
||||
and **prefills the SOP project fields** (step 1) from the project record when
|
||||
empty. Passes `&project` into the WP-creator iframe.
|
||||
- **WP creator:** stamps `projectId` onto every saved package (for API sync).
|
||||
|
||||
**Not yet done (the next fork):** SOP/WP *localStorage* is still global, not
|
||||
namespaced per project — selecting a different project locally still shows the
|
||||
same `wp_suite_sop` / `wp_iwp_v1` data. The intended end state is per-project
|
||||
data via the API (`GET /api/sops/latest?project_id=…`, `GET /api/wps?project_id=…`).
|
||||
Decide whether to (a) namespace the local keys by project id with a migration of
|
||||
existing un-namespaced data into a "default" project, or (b) jump straight to the
|
||||
API for SOP/WP reads. See the open question below.
|
||||
|
||||
**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`
|
||||
|
||||
Reference in New Issue
Block a user