EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
download-job.js
Go to the documentation of this file.
1// backend/routes/downloadJob.js
2const express = require("express");
3const axios = require("axios");
4
5const router = express.Router();
6
7const BUILDER_URL = process.env.BUILDER_URL || "http://127.0.0.1:3001";
8
9// Middleware:
10// All /api/* routes already use your JWT middleware globally.
11// We do not need custom authentication here.
12
13// ------------------------------------------------------------
14// POST /api/download-job
15// ------------------------------------------------------------
16// Create a build job for an installer
17// Requires: tenantId, os
18// Optional: customerId
19// ------------------------------------------------------------
20router.post("/download-job", async (req, res) => {
21 try {
22 const { tenantId, customerId, os } = req.body;
23 const { randomUUID } = require("crypto");
24 const Redis = require('ioredis');
25 if (!tenantId || !os) {
26 return res.status(400).json({ error: "Missing tenantId or os" });
27 }
28 // Generate UUID jobId
29 const jobId = randomUUID();
30 // Enqueue job in Redis
31 const redis = new Redis(require('../config/redis'));
32 await redis.lpush('builder:jobs', JSON.stringify({ jobId, tenantId, customerId, os, created: Date.now() }));
33 redis.quit();
34 return res.json({
35 jobId,
36 statusUrl: `/api/download-job/${jobId}/status`,
37 downloadUrl: `/api/download-job/${jobId}/download`
38 });
39 } catch (err) {
40 console.error("[Backend] POST /download-job error:", err.message);
41 return res.status(500).json({ error: "Failed to create build job" });
42 }
43});
44
45
46// ------------------------------------------------------------
47// GET /api/download-job/:jobId/status
48// ------------------------------------------------------------
49// Poll status from builder
50// ------------------------------------------------------------
51router.get("/download-job/:jobId/status", async (req, res) => {
52 const jobId = req.params.jobId;
53 try {
54 const Redis = require('ioredis');
55 const redis = new Redis(require('../config/redis'));
56 const jobKey = `builder:job:${jobId}`;
57 const jobData = await redis.hgetall(jobKey);
58 redis.quit();
59 if (!jobData || Object.keys(jobData).length === 0) {
60 return res.status(404).json({ error: "Job not found" });
61 }
62 // Optionally refresh TTL
63 try {
64 const { refreshBuilderKeyTTL } = require('../utils/builderKeys');
65 refreshBuilderKeyTTL(jobId).catch(console.error);
66 } catch (e) {}
67 return res.json(jobData);
68 } catch (err) {
69 console.error("[Backend] GET job-status error:", err.message);
70 return res.status(404).json({ error: "Job not found" });
71 }
72});
73
74
75// ------------------------------------------------------------
76// GET /api/download-job/:jobId/download
77// ------------------------------------------------------------
78// Streams the built installer file from builder through backend
79// ------------------------------------------------------------
80router.get("/download-job/:jobId/download", async (req, res) => {
81 const jobId = req.params.jobId;
82
83 try {
84 const builderResponse = await axios({
85 url: `${BUILDER_URL}/download/${jobId}`,
86 method: "GET",
87 responseType: "stream"
88 });
89
90 res.setHeader(
91 "Content-Disposition",
92 `attachment; filename=EverydayTechAgent_Installer.exe`
93 );
94
95 builderResponse.data.pipe(res);
96 } catch (err) {
97 console.error("[Backend] GET job download error:", err.message);
98 return res.status(404).json({ error: "Installer not found" });
99 }
100});
101
102module.exports = router;