PHP 7.4.33
Preview: uploadController.js Size: 3.54 KB
/var/www/receipt-app-backend-bitkit.dk/httpdocs/dist/controllers/uploadController.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.uploadAndParseBill = void 0;
const receiptAiService_1 = require("../services/receiptAiService");
const creditorMatchService_1 = require("../services/creditorMatchService");
const logger_1 = __importDefault(require("../utils/logger"));
const uploadService_1 = require("../services/uploadService");
const receiptVisionPrepareService_1 = require("../services/receiptVisionPrepareService");
const receiptVisionImageClamp_1 = require("../services/receiptVisionImageClamp");
const file_type_1 = __importDefault(require("file-type"));
const uploadAndParseBill = async (req, res) => {
    // @ts-ignore
    const user = req.user;
    if (!req.file) {
        logger_1.default.warn("Upload: No file uploaded", { body: req.body });
        return res.status(400).json({ error: "No file uploaded" });
    }
    try {
        // Use the upload service
        const receipt = await (0, uploadService_1.saveReceiptFile)(user.id, req.file);
        // Detect real MIME type if needed
        let mimeType = req.file.mimetype;
        if (mimeType === "application/octet-stream") {
            const detected = await file_type_1.default.fromBuffer(req.file.buffer);
            if (detected) {
                mimeType = detected.mime;
            }
        }
        const { buffer: visionBuffer, mimeType: visionMime } = await (0, receiptVisionPrepareService_1.prepareBufferForAiReceiptVision)(req.file.buffer, mimeType, req.file.originalname);
        const { buffer: clampedBuffer, mimeType: clampedMime } = await (0, receiptVisionImageClamp_1.clampImageForVisionApi)(visionBuffer, visionMime);
        const aiParsed = await (0, receiptAiService_1.parseReceiptImageWithAi)(clampedBuffer, clampedMime);
        if (!aiParsed || typeof aiParsed !== "object") {
            logger_1.default.error("Failed to parse receipt with AI", { aiParsed });
            return res.status(500).json({ error: "Failed to parse receipt with AI" });
        }
        logger_1.default.info("File parsed with AI", { aiParsed });
        const parsed = aiParsed;
        const currency = "currency" in parsed ? parsed.currency : null;
        let creditorMatch = null;
        const merchantRaw = parsed.merchant;
        if (typeof merchantRaw === "string" && merchantRaw.trim()) {
            try {
                creditorMatch = await (0, creditorMatchService_1.matchCreditorsForMerchant)(merchantRaw.trim());
            }
            catch (matchErr) {
                logger_1.default.warn("Creditor match skipped after parse error", {
                    error: matchErr,
                });
            }
        }
        /** Same value to send as `merchant` on POST /bills when auto-match is confident. */
        let merchant = null;
        if (creditorMatch &&
            creditorMatch.autoResolved &&
            creditorMatch.autoResolved.podioItemId != null) {
            merchant = Number(creditorMatch.autoResolved.podioItemId);
        }
        res.json({
            receiptId: receipt.id,
            merchant,
            aiParsed,
            extractedText: parsed.extractedText ?? null,
            currency,
            creditorMatch,
        });
    }
    catch (err) {
        logger_1.default.error("Failed to process uploaded file", {
            error: err,
        });
        res.status(500).json({ error: "Failed to process file" });
    }
};
exports.uploadAndParseBill = uploadAndParseBill;

Directory Contents

Dirs: 0 × Files: 9
Name Size Perms Modified Actions
12.50 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
9.26 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
1.98 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
8.71 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
10.86 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
3.43 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
5.17 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
1.96 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
3.54 KB lrw-r--r-- 2026-05-06 08:23:54
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).