{
  "slug": "invoices-adapters",
  "spec_file": "docs/specs/2026-05-30-invoices-adapters.md",
  "findings": [
    {
      "id": "invoices-adapters-001",
      "severity": "P1",
      "type": "missing",
      "summary": "TAX_ISSUED does not enqueue invoice.push on issue-tax",
      "spec_ref": "Push Lifecycle",
      "code_ref": "apps/zync-api/src/routes/invoices/index.ts:457",
      "evidence": "issue-tax handler calls issueTaxInvoice only; no QUEUE.send({type:'invoice.push'}) unlike credit-notes.ts:105.",
      "repro": "Configure adapter; issue tax invoice — no push job enqueued."
    },
    {
      "id": "invoices-adapters-002",
      "severity": "P1",
      "type": "missing",
      "summary": "No queue consumer processes invoice.push messages",
      "spec_ref": "Push Lifecycle — Queue consumer",
      "code_ref": "NONE",
      "evidence": "Grep invoice.push across apps/zync-api/src finds only credit-notes enqueue; no queue handler case for invoice.push or invoice.payment_sync.",
      "repro": "Enqueue invoice.push — message never consumed."
    },
    {
      "id": "invoices-adapters-003",
      "severity": "P1",
      "type": "missing",
      "summary": "Settings API /api/settings/integrations/invoicing not implemented",
      "spec_ref": "API Endpoints / Invoice Automation Settings",
      "code_ref": "apps/zync-api/src/routes/index.ts:327",
      "evidence": "Adapter routes mounted at /api/invoice-adapters; grep settings/integrations/invoicing in apps/zync-api returns no API routes.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-004",
      "severity": "P1",
      "type": "missing",
      "summary": "InvoiceAutomationSettings JSONB persistence absent",
      "spec_ref": "Invoice Automation Settings",
      "code_ref": "NONE",
      "evidence": "Grep InvoiceAutomationSettings in repo finds only docs; no tenant_settings read/write for autoSyncOnTaxIssue, taskStatusTrigger, etc.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-005",
      "severity": "P1",
      "type": "broken",
      "summary": "Successful adapter push never writes invoices.external_id",
      "spec_ref": "Push Lifecycle step 3d",
      "code_ref": "apps/zync-api/src/routes/invoice-adapters/router.ts:244",
      "evidence": "push handler logs externalId to integration_sync_logs only; no UPDATE invoices SET external_id/external_provider.",
      "repro": "POST /api/invoice-adapters/:provider/push/:id succeeds; invoice row external_id stays null."
    },
    {
      "id": "invoices-adapters-006",
      "severity": "P1",
      "type": "missing",
      "summary": "Reconcile cron pulls pending invoices, not getStatus paid sync",
      "spec_ref": "Reconciliation Cron",
      "code_ref": "apps/zync-api/src/routes/invoice-adapters/cron.ts:91",
      "evidence": "Cron calls getPendingInvoices + pushInvoice; spec requires adapter.getStatus on TAX_ISSUED>24h and flip to PAID + invoice.paid webhook.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-007",
      "severity": "P1",
      "type": "missing",
      "summary": "Adapter interface lacks createCreditNote and recordPayment",
      "spec_ref": "Adapter Interface",
      "code_ref": "apps/zync-api/src/integrations/invoice-adapters/index.ts:24",
      "evidence": "InvoiceAdapter only exposes testConnection + pushInvoice; no createCreditNote, recordPayment, or getStatus per spec.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-008",
      "severity": "P2",
      "type": "divergent",
      "summary": "Manual push route is /api/invoice-adapters not /api/invoices/:id/push",
      "spec_ref": "API Endpoints",
      "code_ref": "apps/zync-api/src/routes/invoice-adapters/router.ts:216",
      "evidence": "Spec POST /api/invoices/:id/push; implementation POST /api/invoice-adapters/:provider/push/:invoiceId requiring provider param.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-009",
      "severity": "P2",
      "type": "divergent",
      "summary": "integration_sync_logs schema diverges from spec columns",
      "spec_ref": "Sync Logs",
      "code_ref": "packages/db/src/schema/invoice-adapters.ts:57",
      "evidence": "Table uses provider not adapter_id, status failure not error, lacks request_payload/response_payload/error_message; entity_type omits credit_note/payment.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-010",
      "severity": "P2",
      "type": "divergent",
      "summary": "Morning adapter uses api.morning.co.il/v2 not Green Invoice API",
      "spec_ref": "Supported Adapters — Morning",
      "code_ref": "apps/zync-api/src/integrations/invoice-adapters/index.ts:126",
      "evidence": "BASE_URL https://api.morning.co.il/v2 POST /doc; spec https://api.greeninvoice.co.il/api/v1 POST /documents type 320/305.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-011",
      "severity": "P2",
      "type": "divergent",
      "summary": "Adapter config permissions use owner/admin not settings:read/write",
      "spec_ref": "Permissions",
      "code_ref": "apps/zync-api/src/routes/invoice-adapters/router.ts:73",
      "evidence": "Routes check session.role owner/admin; spec maps configure adapter to settings:write and sync logs to settings:read.",
      "repro": ""
    },
    {
      "id": "invoices-adapters-012",
      "severity": "P3",
      "type": "divergent",
      "summary": "Cron route named invoice-adapter-reconcile not invoice-reconcile",
      "spec_ref": "Reconciliation Cron",
      "code_ref": "apps/zync-api/src/routes/index.ts:328",
      "evidence": "Mounted at /api/cron/invoice-adapter-reconcile; spec path /api/cron/invoice-reconcile.",
      "repro": ""
    }
  ],
  "summary": { "P0": 0, "P1": 7, "P2": 4, "P3": 1, "total": 12 }
}
