From a32329abb28697809e371b82c02fc4a20f770b93 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 2 May 2026 11:29:32 -0400 Subject: [PATCH] =?UTF-8?q?Remove=20placement=20worker=20=E2=80=94=20build?= =?UTF-8?q?S3Key=20already=20embeds=20prefix--filename=20for=20AMPP=20work?= =?UTF-8?q?flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 5 ++--- server.js | 37 ++----------------------------------- 2 files changed, 4 insertions(+), 38 deletions(-) diff --git a/public/index.html b/public/index.html index 31fdb64..8a2e14b 100644 --- a/public/index.html +++ b/public/index.html @@ -1225,7 +1225,6 @@ async function uploadFilePresigned(item, idx) { setFileStatus(idx, 'uploading', 'Getting URL\u2026'); const pre = await api('POST', '/api/presigned', { filename: item.name, prefix: selectedPrefix, contentType: mime, size: item.file.size, - amppFolderName: selectedPrefix, }); if (!pre.success) throw new Error(pre.error || 'Failed to get presigned URL'); return new Promise((resolve, reject) => { @@ -1240,7 +1239,7 @@ async function uploadFilePresigned(item, idx) { }); xhr.addEventListener('load', async () => { if (xhr.status >= 200 && xhr.status < 300) { - try { await api('POST', '/api/presigned/complete', { key: pre.key, size: item.file.size, filename: item.name, amppFolderName: selectedPrefix }); } catch(_) {} + try { await api('POST', '/api/presigned/complete', { key: pre.key, size: item.file.size, filename: item.name }); } catch(_) {} resolve({ key: pre.key }); } else { reject(new Error(`S3 returned ${xhr.status}: ${xhr.statusText}`)); @@ -1315,7 +1314,7 @@ async function uploadFilePresigned(item, idx) { setFileStatus(idx, 'uploading', '100%'); // Notify server for quota tracking + queue AMPP placement - try { await api('POST', '/api/presigned/complete', { key, size: item.file.size, filename: item.name, amppFolderName: selectedPrefix }); } catch(_) {} + try { await api('POST', '/api/presigned/complete', { key, size: item.file.size, filename: item.name }); } catch(_) {} return { key }; } diff --git a/server.js b/server.js index f2a7b30..5110e03 100644 --- a/server.js +++ b/server.js @@ -11,8 +11,6 @@ const fs = require("fs"); const https = require("https"); const http = require("http"); const archiver = require("archiver"); -const { placeAsset, placeAssetInFolderById, listAmppFolders } = require("./lib/ampp-folder-placer"); -const AmppPlacementWorker = require("./lib/ampp-placement-worker"); require("events").defaultMaxListeners = 50; @@ -79,7 +77,6 @@ function loadData() { // Migrate existing data to include new fields if missing function migrateData(data) { if (!data.shareLinks) data.shareLinks = []; - if (!data.pendingPlacements) data.pendingPlacements = []; for (const u of data.users) { if (u.quotaMB === undefined) u.quotaMB = 0; if (!u.allowedFolders) u.allowedFolders = []; @@ -140,19 +137,6 @@ function initS3() { initS3(); -// ==================== AMPP PLACEMENT WORKER ==================== -const placementWorker = new AmppPlacementWorker({ - getAmppBase: getAmppBase, - getAmppToken: getAmppToken, - db, - saveData, -}); -// Worker starts after first AMPP config check (deferred to avoid startup errors -// when AMPP is not yet configured). -function maybeStartWorker() { - if (getAmppApiKey() && !placementWorker._timer) placementWorker.start(30_000); -} -setTimeout(maybeStartWorker, 5000); // give server time to fully init // Upload with timeout function withTimeout(promise, ms, label) { @@ -589,7 +573,7 @@ app.post("/api/upload", requireAuth, upload.array("files", 50), async (req, res) // Server only generates the signed URL and tracks quota/permissions. app.post("/api/presigned", requireAuth, async (req, res) => { if (!s3Client) return res.status(503).json({ success: false, error: "S3 not configured" }); - const { filename, prefix, contentType, size, amppFolderId, amppFolderName } = req.body; + const { filename, prefix, contentType, size } = req.body; if (!filename) return res.status(400).json({ success: false, error: "filename required" }); if (isBlockedFile(filename)) return res.status(400).json({ success: false, error: `Blocked file type: ${filename}` }); @@ -618,24 +602,12 @@ app.post("/api/presigned", requireAuth, async (req, res) => { // Called by client after a successful direct-to-S3 upload to update quota + record AMPP placement app.post("/api/presigned/complete", requireAuth, (req, res) => { - const { key, size, amppFolderId, amppFolderName, filename } = req.body; + const { key, size } = req.body; const user = db.users.find(u => u.username === req.sessionData.user); if (user && size) { user.uploadedBytes = (user.uploadedBytes || 0) + size; saveData(db); } - // Record AMPP placement if a folder was selected - if ((amppFolderId || amppFolderName) && filename) { - if (!db.pendingPlacements) db.pendingPlacements = []; - db.pendingPlacements.push({ - id: require("crypto").randomBytes(8).toString("hex"), - filename, s3Key: key, amppFolderId, amppFolderName: amppFolderName || amppFolderId, - status: "waiting", createdAt: new Date().toISOString(), - }); - saveData(db); - maybeStartWorker(); - console.log(`[presigned] Queued AMPP placement: ${filename} → folder ${amppFolderName}`); - } console.log(`[presigned] Completed: ${key} (${size} bytes) by ${req.sessionData.user}`); res.json({ success: true }); }); @@ -850,11 +822,6 @@ app.get("/api/ampp/folders/list", requireAuth, async (req, res) => { } }); -// ---- Pending Placements Status ---- -app.get("/api/ampp/placements", requireAuth, (req, res) => { - const placements = (db.pendingPlacements || []); - res.json({ success: true, placements }); -}); // ---- AMPP Folder Placement ---- // POST /api/ampp/place — place an already-ingested AMPP asset into virtual folders.