Store SOPs and Work Packages in the DB (shared across users)
Reintegrates C-West8's "storing data in DB instead of client only"
(commit e5102446 on shared-data) on top of the BIM / per-package work.
localStorage becomes a per-browser cache; the server is authoritative.
- project-data.js: pullProject() hydrates the apps' existing localStorage
keys from the API on load; pushSOP()/pushWP()/removeWP() write through
on save/delete. WPs store the whole flat object in `data`, so BIM
fields, kind, and projectLinks round-trip intact.
- index.html: home pulls the project before showing SOP status; feedback
loads from /api/comments (server-authoritative, local fallback).
- work-package-suite-app.js: pull-then-restore on boot; completeSOP
pushes the SOP to the server.
- wp-creation-app.js: save/duplicate/issue/setStatus push; delete/clear
remove; boot pulls from the server first, then boots off the cache.
- server/app.py: /api/sops and /api/wps take full=true to return the
data JSON for one-request hydration (list stays lean by default).
Co-Authored-By: C-West8 <125926137+C-West8@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -407,13 +407,15 @@ def upsert_sop(body: SopIn, user: models.User = Depends(auth.get_current_user),
|
||||
|
||||
|
||||
@app.get("/api/sops")
|
||||
def list_sops(project_id: Optional[str] = Query(None), user: models.User = Depends(auth.get_current_user), db: Session = Depends(get_db)):
|
||||
def list_sops(project_id: Optional[str] = Query(None), full: bool = Query(False), user: models.User = Depends(auth.get_current_user), db: Session = Depends(get_db)):
|
||||
stmt = select(models.Sop)
|
||||
if project_id:
|
||||
stmt = stmt.where(models.Sop.project_id == project_id)
|
||||
stmt = scope_to_access(stmt, models.Sop.project_id, db, user)
|
||||
rows = db.scalars(stmt.order_by(models.Sop.updated_at.desc())).all()
|
||||
return [s.summary() for s in rows]
|
||||
# full=true includes the data JSON (the whole SOP document) for hydration;
|
||||
# the default summary view stays lean for listing.
|
||||
return [(s.to_dict() if full else s.summary()) for s in rows]
|
||||
|
||||
|
||||
@app.get("/api/sops/latest")
|
||||
@@ -480,6 +482,7 @@ def list_wps(
|
||||
sop_id: Optional[str] = Query(None),
|
||||
parent_id: Optional[str] = Query(None),
|
||||
status: Optional[str] = Query(None),
|
||||
full: bool = Query(False),
|
||||
user: models.User = Depends(auth.get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
@@ -494,7 +497,9 @@ def list_wps(
|
||||
stmt = stmt.where(models.WorkPackage.status == status)
|
||||
stmt = scope_to_access(stmt, models.WorkPackage.project_id, db, user)
|
||||
rows = db.scalars(stmt.order_by(models.WorkPackage.updated_at.desc())).all()
|
||||
return [w.summary() for w in rows]
|
||||
# full=true includes the data JSON (full package document) so the creator can
|
||||
# rehydrate everything in one request; default stays lean for listing.
|
||||
return [(w.to_dict() if full else w.summary()) for w in rows]
|
||||
|
||||
|
||||
@app.get("/api/wps/metrics")
|
||||
|
||||
Reference in New Issue
Block a user