/**
 * Audit API routes — Phase 7 of the secrets refactor.
 *
 *   GET /api/audit  — paginated, filterable by key/actor
 *
 * Owner-only. Append-only — no DELETE / PUT exposed (master-key
 * rotation in Phase 12 will add a tooling-only path; web users only
 * read).
 *
 * Schema matches `audit_log` in SqliteEncryptedStore.initSchema() —
 * each row carries actor_type + actor_user_id|actor_system_id plus
 * ts/action/key/success/ip/user_agent/detail_json. The route returns
 * rows newest-first with simple offset pagination; the volume is
 * bounded by audit retention (default 90d). Pagination uses
 * LIMIT/OFFSET; the audit table is small enough for this to be fine
 * in v1.
 *
 * After the scope-collapse refactor, audit rows no longer carry a
 * scope dimension. Legacy `scope` / `scope_id` query params are
 * silently ignored for forward-compat with older clients.
 */
import { isWorkspaceOwner } from '../../services/auth-service.js';
import { getSecretStore, hasSecretStore } from '../../core/secrets/index.js';
function requireOwner(req, authService) {
    if (!authService.hasUsers())
        return true;
    const user = req.user;
    if (!user)
        return true;
    return isWorkspaceOwner(user.role);
}
function parseTs(v) {
    if (!v)
        return undefined;
    const n = Number(v);
    if (Number.isFinite(n) && n > 0)
        return n;
    const d = Date.parse(v);
    return Number.isFinite(d) ? d : undefined;
}
export async function registerAuditApiRoutes(fastify, authService) {
    fastify.get('/api/audit', async (req, reply) => {
        if (!requireOwner(req, authService)) {
            return reply.status(403).send({ error: 'Workspace owner access required' });
        }
        if (!hasSecretStore()) {
            return reply.status(503).send({ error: 'Audit store not initialized' });
        }
        const q = req.query ?? {};
        const where = [];
        const params = [];
        if (q.key) {
            where.push('key = ?');
            params.push(q.key);
        }
        if (q.actor_user_id) {
            where.push('actor_user_id = ?');
            params.push(q.actor_user_id);
        }
        if (q.actor_type) {
            where.push('actor_type = ?');
            params.push(q.actor_type);
        }
        if (q.action) {
            where.push('action = ?');
            params.push(q.action);
        }
        const since = parseTs(q.since);
        const until = parseTs(q.until);
        if (since !== undefined) {
            where.push('ts >= ?');
            params.push(since);
        }
        if (until !== undefined) {
            where.push('ts <= ?');
            params.push(until);
        }
        const limit = Math.min(Math.max(parseInt(q.limit ?? '50', 10) || 50, 1), 500);
        const offset = Math.max(parseInt(q.offset ?? '0', 10) || 0, 0);
        const store = getSecretStore();
        const sql = `SELECT id, ts, actor_type, actor_user_id, actor_system_id, action,
              key, success, ip, user_agent, detail_json
         FROM audit_log
        ${where.length ? `WHERE ${where.join(' AND ')}` : ''}
        ORDER BY ts DESC
        LIMIT ? OFFSET ?`;
        const rows = store.db.prepare(sql).all(...params, limit, offset);
        const totalRow = store.db.prepare(`SELECT COUNT(*) AS n FROM audit_log ${where.length ? `WHERE ${where.join(' AND ')}` : ''}`).get(...params);
        return reply.send({
            total: totalRow.n,
            limit,
            offset,
            items: rows.map((r) => ({
                id: r.id,
                ts: r.ts,
                actor_type: r.actor_type,
                actor_user_id: r.actor_user_id,
                actor_system_id: r.actor_system_id,
                action: r.action,
                key: r.key,
                success: !!r.success,
                ip: r.ip,
                user_agent: r.user_agent,
                detail: r.detail_json ? safeJsonParse(r.detail_json) : null,
            })),
        });
    });
}
function safeJsonParse(s) {
    try {
        return JSON.parse(s);
    }
    catch {
        return s;
    }
}
//# sourceMappingURL=audit-api.js.map