53 lines
1.8 KiB
JavaScript
53 lines
1.8 KiB
JavaScript
// GET /relay/balance — peek at the current install's credit balance +
|
|
// tier WITHOUT charging anything. Recap clients call this to populate
|
|
// the "N credits remaining · Tier: X" banner before the user runs any
|
|
// transcribe/analyze, so the display is accurate on first load instead
|
|
// of saying "balance unknown — no relay calls yet".
|
|
//
|
|
// Same auth surface as the metered endpoints:
|
|
// X-Recap-Install-Id (required)
|
|
// Authorization (optional Bearer LIC1-... — absent = Core)
|
|
//
|
|
// Returns the standard envelope shape with result=null and
|
|
// credit_charged=0. The license-resolution path is identical to
|
|
// /relay/transcribe and /relay/analyze, so the cached online check
|
|
// against keysat happens here too — but no row mutation, no job-id
|
|
// reservation, no upstream backend call.
|
|
|
|
import express from "express";
|
|
import { resolveLicense } from "../keysat-client.js";
|
|
import { getOrCreateRow } from "../credits.js";
|
|
import { envelope, errorEnvelope } from "./envelope.js";
|
|
|
|
export function balanceRouter() {
|
|
const router = express.Router();
|
|
|
|
router.get("/balance", async (req, res) => {
|
|
const installId = req.header("X-Recap-Install-Id");
|
|
const auth = req.header("Authorization");
|
|
if (!installId) {
|
|
const e = await errorEnvelope({
|
|
error: "missing X-Recap-Install-Id header",
|
|
statusHint: 400,
|
|
});
|
|
return res.status(400).json(e.body);
|
|
}
|
|
const license = await resolveLicense(auth);
|
|
const tier = license.tier;
|
|
// Touch the row so tier_snapshot reflects the most recently seen
|
|
// license tier — same as the metered endpoints do — but commit
|
|
// nothing.
|
|
const row = await getOrCreateRow(installId);
|
|
row.tier_snapshot = tier;
|
|
const body = await envelope({
|
|
result: null,
|
|
installId,
|
|
tier,
|
|
creditCharged: 0,
|
|
});
|
|
res.json(body);
|
|
});
|
|
|
|
return router;
|
|
}
|