@bonginkan/maria 4.3.10 → 4.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6913,7 +6913,7 @@ function startRateLimitCleanup() {
6913
6913
  });
6914
6914
  }, 10 * 60 * 1e3);
6915
6915
  }
6916
- async function getFirestorePlan(uid) {
6916
+ async function getFirestorePlan(uid2) {
6917
6917
  try {
6918
6918
  const admin = await import('firebase-admin');
6919
6919
  if (!admin.apps?.length) {
@@ -6924,7 +6924,7 @@ async function getFirestorePlan(uid) {
6924
6924
  }
6925
6925
  const { getFirestore } = await import('firebase-admin/firestore');
6926
6926
  const db = getFirestore();
6927
- const doc = await db.doc(`projects/default/users/${uid}`).get();
6927
+ const doc = await db.doc(`projects/default/users/${uid2}`).get();
6928
6928
  const plan = doc.exists && doc.data()?.plan || "FREE";
6929
6929
  return String(plan).toUpperCase();
6930
6930
  } catch {
@@ -8529,6 +8529,7 @@ var IMSFacade = class {
8529
8529
  var IMSFacade_default = IMSFacade;
8530
8530
 
8531
8531
  // src/server/express-server.ts
8532
+ var jobIndex = /* @__PURE__ */ new Map();
8532
8533
  var app = express__default.default();
8533
8534
  var port = process.env.PORT || 8080;
8534
8535
  app.use(helmet__default.default());
@@ -8546,7 +8547,7 @@ app.get("/health", (req, res) => {
8546
8547
  app.get("/api/status", (req, res) => {
8547
8548
  res.json({
8548
8549
  status: "healthy",
8549
- version: "4.3.10",
8550
+ version: "4.3.9",
8550
8551
  uptime: process.uptime(),
8551
8552
  memory: process.memoryUsage(),
8552
8553
  platform: process.platform,
@@ -8557,7 +8558,7 @@ app.get("/api/status", (req, res) => {
8557
8558
  app.get("/", (req, res) => {
8558
8559
  res.json({
8559
8560
  name: "MARIA CODE API",
8560
- version: "4.3.10",
8561
+ version: "4.3.9",
8561
8562
  status: "running",
8562
8563
  environment: process.env.NODE_ENV || "development",
8563
8564
  endpoints: {
@@ -8607,7 +8608,7 @@ app.get("/api/user/profile", async (req, res) => {
8607
8608
  if (!decoded) {
8608
8609
  return res.status(401).json({ error: "invalid_token" });
8609
8610
  }
8610
- const uid = decoded.uid || decoded.sub || "unknown";
8611
+ const uid2 = decoded.uid || decoded.sub || "unknown";
8611
8612
  const email = decoded.email || "";
8612
8613
  const displayName = decoded.name || decoded.displayName || (email ? String(email).split("@")[0] : "User");
8613
8614
  let provider = decoded.firebase?.sign_in_provider;
@@ -8618,7 +8619,7 @@ app.get("/api/user/profile", async (req, res) => {
8618
8619
  }
8619
8620
  const plan = "FREE";
8620
8621
  const response2 = {
8621
- id: uid,
8622
+ id: uid2,
8622
8623
  email,
8623
8624
  name: displayName,
8624
8625
  provider: provider || "unknown",
@@ -8702,6 +8703,9 @@ app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8702
8703
  await loadProviderKeys();
8703
8704
  const auth = req.headers.authorization;
8704
8705
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8706
+ const idToken = auth.substring("Bearer ".length).trim();
8707
+ const decoded = await decodeFirebaseToken(idToken).catch(() => null);
8708
+ const uid2 = decoded?.uid || decoded?.sub || "current";
8705
8709
  const { prompt, model, size = "1024x1024", format = "png", count = 1, seed } = req.body || {};
8706
8710
  if (!prompt) return res.status(400).json({ error: "bad_request", message: "prompt required" });
8707
8711
  const m2 = /^(\d{2,4})x(\d{2,4})$/.exec(String(size));
@@ -8723,9 +8727,18 @@ app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8723
8727
  trace: Math.random().toString(36).slice(2, 8).toUpperCase()
8724
8728
  };
8725
8729
  const saved = await saveArtifacts({ root: process.cwd(), kind: "image" }, buffers.map((b) => ({ bytes: b, ext: `.${format}` })), manifest);
8730
+ jobIndex.set(String(manifest.trace), {
8731
+ id: String(manifest.trace),
8732
+ status: "completed",
8733
+ kind: "image",
8734
+ manifestPath: saved.manifestPath,
8735
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8736
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8737
+ uid: uid2
8738
+ });
8726
8739
  const idemKey = req.headers["idempotency-key"] || void 0;
8727
- await recordConsumption("current", { requests: 1, image: Math.max(1, buffers.length) }, idemKey);
8728
- return res.json({ success: true, data: { url: saved.manifestPath } });
8740
+ await recordConsumption(uid2, { requests: 1, image: Math.max(1, buffers.length) }, idemKey);
8741
+ return res.json({ success: true, data: { url: saved.manifestPath, jobId: manifest.trace } });
8729
8742
  } catch (error) {
8730
8743
  console.error("[Image API] Error:", error);
8731
8744
  return res.status(500).json({
@@ -8770,8 +8783,17 @@ app.post("/api/v1/video", rateLimitMiddleware, async (req, res) => {
8770
8783
  saved = await saveArtifacts({ root: process.cwd(), kind: "video" }, items, manifest);
8771
8784
  }
8772
8785
  const idemKey = req.headers["idempotency-key"] || void 0;
8773
- await recordConsumption("current", { requests: 1, video: 1 }, idemKey);
8774
- return res.json({ success: true, data: { url: saved.manifestPath } });
8786
+ await recordConsumption(uid, { requests: 1, video: 1 }, idemKey);
8787
+ jobIndex.set(String(manifest.trace), {
8788
+ id: String(manifest.trace),
8789
+ status: "completed",
8790
+ kind: "video",
8791
+ manifestPath: saved.manifestPath,
8792
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8793
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8794
+ uid
8795
+ });
8796
+ return res.json({ success: true, data: { url: saved.manifestPath, jobId: manifest.trace } });
8775
8797
  } catch (error) {
8776
8798
  console.error("[Video API] Error:", error);
8777
8799
  return res.status(500).json({
@@ -8780,6 +8802,40 @@ app.post("/api/v1/video", rateLimitMiddleware, async (req, res) => {
8780
8802
  });
8781
8803
  }
8782
8804
  });
8805
+ app.get("/api/v1/jobs/:id", async (req, res) => {
8806
+ try {
8807
+ const auth = req.headers.authorization;
8808
+ if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8809
+ const idToken = auth.substring("Bearer ".length).trim();
8810
+ const decoded = await decodeFirebaseToken(idToken).catch(() => null);
8811
+ const uid2 = decoded?.uid || decoded?.sub || "current";
8812
+ const id = String(req.params.id || "").trim();
8813
+ if (!id) return res.status(400).json({ error: "bad_request", message: "id required" });
8814
+ const info = jobIndex.get(id);
8815
+ if (!info || info.uid && info.uid !== uid2) return res.status(404).json({ error: "not_found", message: "job not found" });
8816
+ let manifest;
8817
+ if (info.manifestPath) {
8818
+ try {
8819
+ const full = path__namespace.default.resolve(process.cwd(), info.manifestPath);
8820
+ const txt = await fsp__namespace.default.readFile(full, "utf8");
8821
+ manifest = JSON.parse(txt);
8822
+ } catch {
8823
+ }
8824
+ }
8825
+ return res.json({
8826
+ id: info.id,
8827
+ status: info.status,
8828
+ kind: info.kind,
8829
+ manifestPath: info.manifestPath,
8830
+ manifest,
8831
+ createdAt: info.createdAt,
8832
+ updatedAt: info.updatedAt
8833
+ });
8834
+ } catch (error) {
8835
+ console.error("[Jobs API] Error:", error);
8836
+ return res.status(500).json({ error: "internal_error", message: "failed to fetch job" });
8837
+ }
8838
+ });
8783
8839
  app.post("/api/v1/code", rateLimitMiddleware, async (req, res) => {
8784
8840
  try {
8785
8841
  const { prompt, language = "typescript", model = "gpt-4" } = req.body;
@@ -8935,14 +8991,14 @@ function calcNextReset() {
8935
8991
  d.setUTCHours(0, 0, 0, 0);
8936
8992
  return d.toISOString();
8937
8993
  }
8938
- async function recordConsumption(uid, consumption, idempotencyKey) {
8994
+ async function recordConsumption(uid2, consumption, idempotencyKey) {
8939
8995
  const db = await getFirestoreSafe();
8940
8996
  if (!db) return;
8941
- const docPath = `projects/default/usage/${uid}`;
8997
+ const docPath = `projects/default/usage/${uid2}`;
8942
8998
  const usageRef = db.doc(docPath);
8943
8999
  const nowISO = (/* @__PURE__ */ new Date()).toISOString();
8944
9000
  if (idempotencyKey) {
8945
- const idemRef = db.doc(`projects/default/usage/${uid}/consumptions/${idempotencyKey}`);
9001
+ const idemRef = db.doc(`projects/default/usage/${uid2}/consumptions/${idempotencyKey}`);
8946
9002
  const idemSnap = await idemRef.get();
8947
9003
  if (idemSnap.exists) return;
8948
9004
  await idemRef.set({ createdAt: nowISO, consumption });
@@ -8976,8 +9032,8 @@ app.get("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
8976
9032
  const auth = req.headers.authorization;
8977
9033
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8978
9034
  const db = await getFirestoreSafe();
8979
- const uid = "current";
8980
- const docPath = `projects/default/usage/${uid}`;
9035
+ const uid2 = "current";
9036
+ const docPath = `projects/default/usage/${uid2}`;
8981
9037
  let data = null;
8982
9038
  if (db) {
8983
9039
  const snap = await db.doc(docPath).get();
@@ -8996,7 +9052,7 @@ app.get("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
8996
9052
  };
8997
9053
  await db.doc(docPath).set(data);
8998
9054
  }
8999
- const historySnap = await db.collection(`projects/default/usage/${uid}/consumptions`).orderBy("createdAt", "desc").limit(20).get();
9055
+ const historySnap = await db.collection(`projects/default/usage/${uid2}/consumptions`).orderBy("createdAt", "desc").limit(20).get();
9000
9056
  const history = historySnap.docs.map((d) => ({ id: d.id, ...d.data() }));
9001
9057
  data.history = history;
9002
9058
  } else {
@@ -9024,11 +9080,11 @@ app.post("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
9024
9080
  const { consumption } = req.body || {};
9025
9081
  const idemKey = req.headers["idempotency-key"] || void 0;
9026
9082
  const db = await getFirestoreSafe();
9027
- const uid = "current";
9028
- const docPath = `projects/default/usage/${uid}`;
9083
+ const uid2 = "current";
9084
+ const docPath = `projects/default/usage/${uid2}`;
9029
9085
  let data = null;
9030
9086
  if (db) {
9031
- await recordConsumption(uid, consumption || {}, idemKey);
9087
+ await recordConsumption(uid2, consumption || {}, idemKey);
9032
9088
  const snap = await db.doc(docPath).get();
9033
9089
  data = snap.exists ? snap.data() : { ok: true };
9034
9090
  } else {
@@ -6913,7 +6913,7 @@ function startRateLimitCleanup() {
6913
6913
  });
6914
6914
  }, 10 * 60 * 1e3);
6915
6915
  }
6916
- async function getFirestorePlan(uid) {
6916
+ async function getFirestorePlan(uid2) {
6917
6917
  try {
6918
6918
  const admin = await import('firebase-admin');
6919
6919
  if (!admin.apps?.length) {
@@ -6924,7 +6924,7 @@ async function getFirestorePlan(uid) {
6924
6924
  }
6925
6925
  const { getFirestore } = await import('firebase-admin/firestore');
6926
6926
  const db = getFirestore();
6927
- const doc = await db.doc(`projects/default/users/${uid}`).get();
6927
+ const doc = await db.doc(`projects/default/users/${uid2}`).get();
6928
6928
  const plan = doc.exists && doc.data()?.plan || "FREE";
6929
6929
  return String(plan).toUpperCase();
6930
6930
  } catch {
@@ -8529,6 +8529,7 @@ var IMSFacade = class {
8529
8529
  var IMSFacade_default = IMSFacade;
8530
8530
 
8531
8531
  // src/server/express-server.ts
8532
+ var jobIndex = /* @__PURE__ */ new Map();
8532
8533
  var app = express__default.default();
8533
8534
  var port = process.env.PORT || 8080;
8534
8535
  app.use(helmet__default.default());
@@ -8546,7 +8547,7 @@ app.get("/health", (req, res) => {
8546
8547
  app.get("/api/status", (req, res) => {
8547
8548
  res.json({
8548
8549
  status: "healthy",
8549
- version: "4.3.10",
8550
+ version: "4.3.9",
8550
8551
  uptime: process.uptime(),
8551
8552
  memory: process.memoryUsage(),
8552
8553
  platform: process.platform,
@@ -8557,7 +8558,7 @@ app.get("/api/status", (req, res) => {
8557
8558
  app.get("/", (req, res) => {
8558
8559
  res.json({
8559
8560
  name: "MARIA CODE API",
8560
- version: "4.3.10",
8561
+ version: "4.3.9",
8561
8562
  status: "running",
8562
8563
  environment: process.env.NODE_ENV || "development",
8563
8564
  endpoints: {
@@ -8607,7 +8608,7 @@ app.get("/api/user/profile", async (req, res) => {
8607
8608
  if (!decoded) {
8608
8609
  return res.status(401).json({ error: "invalid_token" });
8609
8610
  }
8610
- const uid = decoded.uid || decoded.sub || "unknown";
8611
+ const uid2 = decoded.uid || decoded.sub || "unknown";
8611
8612
  const email = decoded.email || "";
8612
8613
  const displayName = decoded.name || decoded.displayName || (email ? String(email).split("@")[0] : "User");
8613
8614
  let provider = decoded.firebase?.sign_in_provider;
@@ -8618,7 +8619,7 @@ app.get("/api/user/profile", async (req, res) => {
8618
8619
  }
8619
8620
  const plan = "FREE";
8620
8621
  const response2 = {
8621
- id: uid,
8622
+ id: uid2,
8622
8623
  email,
8623
8624
  name: displayName,
8624
8625
  provider: provider || "unknown",
@@ -8702,6 +8703,9 @@ app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8702
8703
  await loadProviderKeys();
8703
8704
  const auth = req.headers.authorization;
8704
8705
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8706
+ const idToken = auth.substring("Bearer ".length).trim();
8707
+ const decoded = await decodeFirebaseToken(idToken).catch(() => null);
8708
+ const uid2 = decoded?.uid || decoded?.sub || "current";
8705
8709
  const { prompt, model, size = "1024x1024", format = "png", count = 1, seed } = req.body || {};
8706
8710
  if (!prompt) return res.status(400).json({ error: "bad_request", message: "prompt required" });
8707
8711
  const m2 = /^(\d{2,4})x(\d{2,4})$/.exec(String(size));
@@ -8723,9 +8727,18 @@ app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8723
8727
  trace: Math.random().toString(36).slice(2, 8).toUpperCase()
8724
8728
  };
8725
8729
  const saved = await saveArtifacts({ root: process.cwd(), kind: "image" }, buffers.map((b) => ({ bytes: b, ext: `.${format}` })), manifest);
8730
+ jobIndex.set(String(manifest.trace), {
8731
+ id: String(manifest.trace),
8732
+ status: "completed",
8733
+ kind: "image",
8734
+ manifestPath: saved.manifestPath,
8735
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8736
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8737
+ uid: uid2
8738
+ });
8726
8739
  const idemKey = req.headers["idempotency-key"] || void 0;
8727
- await recordConsumption("current", { requests: 1, image: Math.max(1, buffers.length) }, idemKey);
8728
- return res.json({ success: true, data: { url: saved.manifestPath } });
8740
+ await recordConsumption(uid2, { requests: 1, image: Math.max(1, buffers.length) }, idemKey);
8741
+ return res.json({ success: true, data: { url: saved.manifestPath, jobId: manifest.trace } });
8729
8742
  } catch (error) {
8730
8743
  console.error("[Image API] Error:", error);
8731
8744
  return res.status(500).json({
@@ -8770,8 +8783,17 @@ app.post("/api/v1/video", rateLimitMiddleware, async (req, res) => {
8770
8783
  saved = await saveArtifacts({ root: process.cwd(), kind: "video" }, items, manifest);
8771
8784
  }
8772
8785
  const idemKey = req.headers["idempotency-key"] || void 0;
8773
- await recordConsumption("current", { requests: 1, video: 1 }, idemKey);
8774
- return res.json({ success: true, data: { url: saved.manifestPath } });
8786
+ await recordConsumption(uid, { requests: 1, video: 1 }, idemKey);
8787
+ jobIndex.set(String(manifest.trace), {
8788
+ id: String(manifest.trace),
8789
+ status: "completed",
8790
+ kind: "video",
8791
+ manifestPath: saved.manifestPath,
8792
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8793
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8794
+ uid
8795
+ });
8796
+ return res.json({ success: true, data: { url: saved.manifestPath, jobId: manifest.trace } });
8775
8797
  } catch (error) {
8776
8798
  console.error("[Video API] Error:", error);
8777
8799
  return res.status(500).json({
@@ -8780,6 +8802,40 @@ app.post("/api/v1/video", rateLimitMiddleware, async (req, res) => {
8780
8802
  });
8781
8803
  }
8782
8804
  });
8805
+ app.get("/api/v1/jobs/:id", async (req, res) => {
8806
+ try {
8807
+ const auth = req.headers.authorization;
8808
+ if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8809
+ const idToken = auth.substring("Bearer ".length).trim();
8810
+ const decoded = await decodeFirebaseToken(idToken).catch(() => null);
8811
+ const uid2 = decoded?.uid || decoded?.sub || "current";
8812
+ const id = String(req.params.id || "").trim();
8813
+ if (!id) return res.status(400).json({ error: "bad_request", message: "id required" });
8814
+ const info = jobIndex.get(id);
8815
+ if (!info || info.uid && info.uid !== uid2) return res.status(404).json({ error: "not_found", message: "job not found" });
8816
+ let manifest;
8817
+ if (info.manifestPath) {
8818
+ try {
8819
+ const full = path__namespace.default.resolve(process.cwd(), info.manifestPath);
8820
+ const txt = await fsp__namespace.default.readFile(full, "utf8");
8821
+ manifest = JSON.parse(txt);
8822
+ } catch {
8823
+ }
8824
+ }
8825
+ return res.json({
8826
+ id: info.id,
8827
+ status: info.status,
8828
+ kind: info.kind,
8829
+ manifestPath: info.manifestPath,
8830
+ manifest,
8831
+ createdAt: info.createdAt,
8832
+ updatedAt: info.updatedAt
8833
+ });
8834
+ } catch (error) {
8835
+ console.error("[Jobs API] Error:", error);
8836
+ return res.status(500).json({ error: "internal_error", message: "failed to fetch job" });
8837
+ }
8838
+ });
8783
8839
  app.post("/api/v1/code", rateLimitMiddleware, async (req, res) => {
8784
8840
  try {
8785
8841
  const { prompt, language = "typescript", model = "gpt-4" } = req.body;
@@ -8935,14 +8991,14 @@ function calcNextReset() {
8935
8991
  d.setUTCHours(0, 0, 0, 0);
8936
8992
  return d.toISOString();
8937
8993
  }
8938
- async function recordConsumption(uid, consumption, idempotencyKey) {
8994
+ async function recordConsumption(uid2, consumption, idempotencyKey) {
8939
8995
  const db = await getFirestoreSafe();
8940
8996
  if (!db) return;
8941
- const docPath = `projects/default/usage/${uid}`;
8997
+ const docPath = `projects/default/usage/${uid2}`;
8942
8998
  const usageRef = db.doc(docPath);
8943
8999
  const nowISO = (/* @__PURE__ */ new Date()).toISOString();
8944
9000
  if (idempotencyKey) {
8945
- const idemRef = db.doc(`projects/default/usage/${uid}/consumptions/${idempotencyKey}`);
9001
+ const idemRef = db.doc(`projects/default/usage/${uid2}/consumptions/${idempotencyKey}`);
8946
9002
  const idemSnap = await idemRef.get();
8947
9003
  if (idemSnap.exists) return;
8948
9004
  await idemRef.set({ createdAt: nowISO, consumption });
@@ -8976,8 +9032,8 @@ app.get("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
8976
9032
  const auth = req.headers.authorization;
8977
9033
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8978
9034
  const db = await getFirestoreSafe();
8979
- const uid = "current";
8980
- const docPath = `projects/default/usage/${uid}`;
9035
+ const uid2 = "current";
9036
+ const docPath = `projects/default/usage/${uid2}`;
8981
9037
  let data = null;
8982
9038
  if (db) {
8983
9039
  const snap = await db.doc(docPath).get();
@@ -8996,7 +9052,7 @@ app.get("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
8996
9052
  };
8997
9053
  await db.doc(docPath).set(data);
8998
9054
  }
8999
- const historySnap = await db.collection(`projects/default/usage/${uid}/consumptions`).orderBy("createdAt", "desc").limit(20).get();
9055
+ const historySnap = await db.collection(`projects/default/usage/${uid2}/consumptions`).orderBy("createdAt", "desc").limit(20).get();
9000
9056
  const history = historySnap.docs.map((d) => ({ id: d.id, ...d.data() }));
9001
9057
  data.history = history;
9002
9058
  } else {
@@ -9024,11 +9080,11 @@ app.post("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
9024
9080
  const { consumption } = req.body || {};
9025
9081
  const idemKey = req.headers["idempotency-key"] || void 0;
9026
9082
  const db = await getFirestoreSafe();
9027
- const uid = "current";
9028
- const docPath = `projects/default/usage/${uid}`;
9083
+ const uid2 = "current";
9084
+ const docPath = `projects/default/usage/${uid2}`;
9029
9085
  let data = null;
9030
9086
  if (db) {
9031
- await recordConsumption(uid, consumption || {}, idemKey);
9087
+ await recordConsumption(uid2, consumption || {}, idemKey);
9032
9088
  const snap = await db.doc(docPath).get();
9033
9089
  data = snap.exists ? snap.data() : { ok: true };
9034
9090
  } else {
@@ -6913,7 +6913,7 @@ function startRateLimitCleanup() {
6913
6913
  });
6914
6914
  }, 10 * 60 * 1e3);
6915
6915
  }
6916
- async function getFirestorePlan(uid) {
6916
+ async function getFirestorePlan(uid2) {
6917
6917
  try {
6918
6918
  const admin = await import('firebase-admin');
6919
6919
  if (!admin.apps?.length) {
@@ -6924,7 +6924,7 @@ async function getFirestorePlan(uid) {
6924
6924
  }
6925
6925
  const { getFirestore } = await import('firebase-admin/firestore');
6926
6926
  const db = getFirestore();
6927
- const doc = await db.doc(`projects/default/users/${uid}`).get();
6927
+ const doc = await db.doc(`projects/default/users/${uid2}`).get();
6928
6928
  const plan = doc.exists && doc.data()?.plan || "FREE";
6929
6929
  return String(plan).toUpperCase();
6930
6930
  } catch {
@@ -8529,6 +8529,7 @@ var IMSFacade = class {
8529
8529
  var IMSFacade_default = IMSFacade;
8530
8530
 
8531
8531
  // src/server/express-server.ts
8532
+ var jobIndex = /* @__PURE__ */ new Map();
8532
8533
  var app = express__default.default();
8533
8534
  var port = process.env.PORT || 8080;
8534
8535
  app.use(helmet__default.default());
@@ -8546,7 +8547,7 @@ app.get("/health", (req, res) => {
8546
8547
  app.get("/api/status", (req, res) => {
8547
8548
  res.json({
8548
8549
  status: "healthy",
8549
- version: "4.3.10",
8550
+ version: "4.3.9",
8550
8551
  uptime: process.uptime(),
8551
8552
  memory: process.memoryUsage(),
8552
8553
  platform: process.platform,
@@ -8557,7 +8558,7 @@ app.get("/api/status", (req, res) => {
8557
8558
  app.get("/", (req, res) => {
8558
8559
  res.json({
8559
8560
  name: "MARIA CODE API",
8560
- version: "4.3.10",
8561
+ version: "4.3.9",
8561
8562
  status: "running",
8562
8563
  environment: process.env.NODE_ENV || "development",
8563
8564
  endpoints: {
@@ -8607,7 +8608,7 @@ app.get("/api/user/profile", async (req, res) => {
8607
8608
  if (!decoded) {
8608
8609
  return res.status(401).json({ error: "invalid_token" });
8609
8610
  }
8610
- const uid = decoded.uid || decoded.sub || "unknown";
8611
+ const uid2 = decoded.uid || decoded.sub || "unknown";
8611
8612
  const email = decoded.email || "";
8612
8613
  const displayName = decoded.name || decoded.displayName || (email ? String(email).split("@")[0] : "User");
8613
8614
  let provider = decoded.firebase?.sign_in_provider;
@@ -8618,7 +8619,7 @@ app.get("/api/user/profile", async (req, res) => {
8618
8619
  }
8619
8620
  const plan = "FREE";
8620
8621
  const response2 = {
8621
- id: uid,
8622
+ id: uid2,
8622
8623
  email,
8623
8624
  name: displayName,
8624
8625
  provider: provider || "unknown",
@@ -8702,6 +8703,9 @@ app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8702
8703
  await loadProviderKeys();
8703
8704
  const auth = req.headers.authorization;
8704
8705
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8706
+ const idToken = auth.substring("Bearer ".length).trim();
8707
+ const decoded = await decodeFirebaseToken(idToken).catch(() => null);
8708
+ const uid2 = decoded?.uid || decoded?.sub || "current";
8705
8709
  const { prompt, model, size = "1024x1024", format = "png", count = 1, seed } = req.body || {};
8706
8710
  if (!prompt) return res.status(400).json({ error: "bad_request", message: "prompt required" });
8707
8711
  const m2 = /^(\d{2,4})x(\d{2,4})$/.exec(String(size));
@@ -8723,9 +8727,18 @@ app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8723
8727
  trace: Math.random().toString(36).slice(2, 8).toUpperCase()
8724
8728
  };
8725
8729
  const saved = await saveArtifacts({ root: process.cwd(), kind: "image" }, buffers.map((b) => ({ bytes: b, ext: `.${format}` })), manifest);
8730
+ jobIndex.set(String(manifest.trace), {
8731
+ id: String(manifest.trace),
8732
+ status: "completed",
8733
+ kind: "image",
8734
+ manifestPath: saved.manifestPath,
8735
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8736
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8737
+ uid: uid2
8738
+ });
8726
8739
  const idemKey = req.headers["idempotency-key"] || void 0;
8727
- await recordConsumption("current", { requests: 1, image: Math.max(1, buffers.length) }, idemKey);
8728
- return res.json({ success: true, data: { url: saved.manifestPath } });
8740
+ await recordConsumption(uid2, { requests: 1, image: Math.max(1, buffers.length) }, idemKey);
8741
+ return res.json({ success: true, data: { url: saved.manifestPath, jobId: manifest.trace } });
8729
8742
  } catch (error) {
8730
8743
  console.error("[Image API] Error:", error);
8731
8744
  return res.status(500).json({
@@ -8770,8 +8783,17 @@ app.post("/api/v1/video", rateLimitMiddleware, async (req, res) => {
8770
8783
  saved = await saveArtifacts({ root: process.cwd(), kind: "video" }, items, manifest);
8771
8784
  }
8772
8785
  const idemKey = req.headers["idempotency-key"] || void 0;
8773
- await recordConsumption("current", { requests: 1, video: 1 }, idemKey);
8774
- return res.json({ success: true, data: { url: saved.manifestPath } });
8786
+ await recordConsumption(uid, { requests: 1, video: 1 }, idemKey);
8787
+ jobIndex.set(String(manifest.trace), {
8788
+ id: String(manifest.trace),
8789
+ status: "completed",
8790
+ kind: "video",
8791
+ manifestPath: saved.manifestPath,
8792
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
8793
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
8794
+ uid
8795
+ });
8796
+ return res.json({ success: true, data: { url: saved.manifestPath, jobId: manifest.trace } });
8775
8797
  } catch (error) {
8776
8798
  console.error("[Video API] Error:", error);
8777
8799
  return res.status(500).json({
@@ -8780,6 +8802,40 @@ app.post("/api/v1/video", rateLimitMiddleware, async (req, res) => {
8780
8802
  });
8781
8803
  }
8782
8804
  });
8805
+ app.get("/api/v1/jobs/:id", async (req, res) => {
8806
+ try {
8807
+ const auth = req.headers.authorization;
8808
+ if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8809
+ const idToken = auth.substring("Bearer ".length).trim();
8810
+ const decoded = await decodeFirebaseToken(idToken).catch(() => null);
8811
+ const uid2 = decoded?.uid || decoded?.sub || "current";
8812
+ const id = String(req.params.id || "").trim();
8813
+ if (!id) return res.status(400).json({ error: "bad_request", message: "id required" });
8814
+ const info = jobIndex.get(id);
8815
+ if (!info || info.uid && info.uid !== uid2) return res.status(404).json({ error: "not_found", message: "job not found" });
8816
+ let manifest;
8817
+ if (info.manifestPath) {
8818
+ try {
8819
+ const full = path__namespace.default.resolve(process.cwd(), info.manifestPath);
8820
+ const txt = await fsp__namespace.default.readFile(full, "utf8");
8821
+ manifest = JSON.parse(txt);
8822
+ } catch {
8823
+ }
8824
+ }
8825
+ return res.json({
8826
+ id: info.id,
8827
+ status: info.status,
8828
+ kind: info.kind,
8829
+ manifestPath: info.manifestPath,
8830
+ manifest,
8831
+ createdAt: info.createdAt,
8832
+ updatedAt: info.updatedAt
8833
+ });
8834
+ } catch (error) {
8835
+ console.error("[Jobs API] Error:", error);
8836
+ return res.status(500).json({ error: "internal_error", message: "failed to fetch job" });
8837
+ }
8838
+ });
8783
8839
  app.post("/api/v1/code", rateLimitMiddleware, async (req, res) => {
8784
8840
  try {
8785
8841
  const { prompt, language = "typescript", model = "gpt-4" } = req.body;
@@ -8935,14 +8991,14 @@ function calcNextReset() {
8935
8991
  d.setUTCHours(0, 0, 0, 0);
8936
8992
  return d.toISOString();
8937
8993
  }
8938
- async function recordConsumption(uid, consumption, idempotencyKey) {
8994
+ async function recordConsumption(uid2, consumption, idempotencyKey) {
8939
8995
  const db = await getFirestoreSafe();
8940
8996
  if (!db) return;
8941
- const docPath = `projects/default/usage/${uid}`;
8997
+ const docPath = `projects/default/usage/${uid2}`;
8942
8998
  const usageRef = db.doc(docPath);
8943
8999
  const nowISO = (/* @__PURE__ */ new Date()).toISOString();
8944
9000
  if (idempotencyKey) {
8945
- const idemRef = db.doc(`projects/default/usage/${uid}/consumptions/${idempotencyKey}`);
9001
+ const idemRef = db.doc(`projects/default/usage/${uid2}/consumptions/${idempotencyKey}`);
8946
9002
  const idemSnap = await idemRef.get();
8947
9003
  if (idemSnap.exists) return;
8948
9004
  await idemRef.set({ createdAt: nowISO, consumption });
@@ -8976,8 +9032,8 @@ app.get("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
8976
9032
  const auth = req.headers.authorization;
8977
9033
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8978
9034
  const db = await getFirestoreSafe();
8979
- const uid = "current";
8980
- const docPath = `projects/default/usage/${uid}`;
9035
+ const uid2 = "current";
9036
+ const docPath = `projects/default/usage/${uid2}`;
8981
9037
  let data = null;
8982
9038
  if (db) {
8983
9039
  const snap = await db.doc(docPath).get();
@@ -8996,7 +9052,7 @@ app.get("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
8996
9052
  };
8997
9053
  await db.doc(docPath).set(data);
8998
9054
  }
8999
- const historySnap = await db.collection(`projects/default/usage/${uid}/consumptions`).orderBy("createdAt", "desc").limit(20).get();
9055
+ const historySnap = await db.collection(`projects/default/usage/${uid2}/consumptions`).orderBy("createdAt", "desc").limit(20).get();
9000
9056
  const history = historySnap.docs.map((d) => ({ id: d.id, ...d.data() }));
9001
9057
  data.history = history;
9002
9058
  } else {
@@ -9024,11 +9080,11 @@ app.post("/api/v1/usage", rateLimitMiddleware, async (req, res) => {
9024
9080
  const { consumption } = req.body || {};
9025
9081
  const idemKey = req.headers["idempotency-key"] || void 0;
9026
9082
  const db = await getFirestoreSafe();
9027
- const uid = "current";
9028
- const docPath = `projects/default/usage/${uid}`;
9083
+ const uid2 = "current";
9084
+ const docPath = `projects/default/usage/${uid2}`;
9029
9085
  let data = null;
9030
9086
  if (db) {
9031
- await recordConsumption(uid, consumption || {}, idemKey);
9087
+ await recordConsumption(uid2, consumption || {}, idemKey);
9032
9088
  const snap = await db.doc(docPath).get();
9033
9089
  data = snap.exists ? snap.data() : { ok: true };
9034
9090
  } else {