feat(P2.2): owner falls back to requester + auto-declare uploaded custom lib

- compile.py: owner_id = project owner ELSE the requester (so an unsaved
  compile resolves the libs the user just uploaded, which are their own);
  threaded requester_id into _run_compile from both call sites.
- LibraryManagerModal: on a custom .zip upload, auto-add the lib to the active
  board's velxio.json + show the Project tab, so the compile resolves it via the
  owner per-user path (the upload now lands in the per-user store, not the
  shared dir, so it must be declared to be found).
This commit is contained in:
David Montero 2026-06-07 17:20:12 +02:00
parent 6d5f6b01a4
commit cc40bda3eb
2 changed files with 25 additions and 4 deletions

View File

@ -205,6 +205,7 @@ async def _run_compile(
request: CompileRequest,
files: list[dict[str, str]],
progress_callback: Any = None,
requester_id: str | None = None,
) -> CompileResponse:
"""Do the actual compile (ESP-IDF for esp32:*, arduino-cli otherwise).
@ -234,10 +235,13 @@ async def _run_compile(
project_libs = await get_project_libraries(request.project_id)
if project_libs:
allowed_libraries = set(project_libs)
# P2.2 — the OWNER of the project (not the requester) owns any per-user
# custom libraries the manifest references, so resolve the owner so the
# scope materializer can find them. None for unsaved/anon compiles.
# P2.2 — resolve whose per-user custom libraries the manifest may
# reference: the project OWNER for a saved project (so a shared/embed
# compile finds that owner's libs), else the REQUESTER for an unsaved
# compile (the libs they just uploaded are their own). None for anon.
owner_id = await get_project_owner(request.project_id)
if owner_id is None:
owner_id = requester_id
result = await espidf_compiler.compile(
files, request.board_fqbn,
progress_callback=progress_callback,
@ -368,6 +372,7 @@ async def _compile_job(
COMPILE_JOBS[job_id]["state"] = "running"
response = await _run_compile(
request, files, progress_callback=on_progress_line,
requester_id=user_id,
)
COMPILE_JOBS[job_id] = {
"state": "done",
@ -440,7 +445,7 @@ async def compile_sketch(
files = _resolve_files(request)
started = time.monotonic()
try:
response = await _run_compile(request, files)
response = await _run_compile(request, files, requester_id=user_id)
except Exception as e:
await record_compile(
user_id=user_id,

View File

@ -256,6 +256,22 @@ export const LibraryManagerModal: React.FC<LibraryManagerModalProps> = ({ isOpen
return () => window.removeEventListener('velxio-open-library-manager', toProject);
}, []);
// P2.2 — a custom .zip upload lands in the user's PER-USER store (not the
// shared dir), so auto-declare it on the active board (velxio.json) and show
// the Project tab; the compile then resolves it via the owner per-user path.
useEffect(() => {
const onUploaded = (e: Event) => {
const name = (e as CustomEvent).detail?.library;
if (name) {
addToManifest(name);
setActiveTab('project');
}
fetchInstalled();
};
window.addEventListener('velxio-custom-library-installed', onUploaded);
return () => window.removeEventListener('velxio-custom-library-installed', onUploaded);
}, [addToManifest, fetchInstalled]);
// Keep the raw velxio.json draft in sync with the manifest while not editing.
useEffect(() => {
setJsonDraft(JSON.stringify({ libraries: manifestLibs ?? [] }, null, 2));